Commit 1dbdb756 by Patrick Palka Committed by Paolo Carlini

re PR c++/60765 (Function attributes ignored for pointer-to-member-function parameters)

2014-04-16  Patrick Palka  <patrick@parcs.ath.cx>

	PR c++/60765
	* decl2.c (cplus_decl_attributes): Handle
	pointer-to-member-function declarations.

2014-04-16  Patrick Palka  <patrick@parcs.ath.cx>

	PR c++/60764
	* call.c (build_user_type_coversion): Use build_dummy_object
	to create the placeholder object for a constructor method call.
	(build_special_member_call): Likewise.
	(build_over_call): Check for the placeholder object with
	is_dummy_object.
	(build_new_method_call_1): Likewise.  Don't attempt to resolve
	a dummy object for a constructor method call.

From-SVN: r209447
parent 10353a79
2014-04-16 Patrick Palka <patrick@parcs.ath.cx>
PR c++/60765
* decl2.c (cplus_decl_attributes): Handle
pointer-to-member-function declarations.
2014-04-16 Patrick Palka <patrick@parcs.ath.cx>
PR c++/60764
* call.c (build_user_type_coversion): Use build_dummy_object
to create the placeholder object for a constructor method call.
(build_special_member_call): Likewise.
(build_over_call): Check for the placeholder object with
is_dummy_object.
(build_new_method_call_1): Likewise. Don't attempt to resolve
a dummy object for a constructor method call.
2014-04-16 Paul Pluzhnikov <ppluzhnikov@google.com> 2014-04-16 Paul Pluzhnikov <ppluzhnikov@google.com>
PR c++/59295 PR c++/59295
......
...@@ -3524,8 +3524,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags, ...@@ -3524,8 +3524,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
{ {
int ctorflags = flags; int ctorflags = flags;
first_arg = build_int_cst (build_pointer_type (totype), 0); first_arg = build_dummy_object (totype);
first_arg = build_fold_indirect_ref (first_arg);
/* We should never try to call the abstract or base constructor /* We should never try to call the abstract or base constructor
from here. */ from here. */
...@@ -7101,7 +7100,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ...@@ -7101,7 +7100,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
temp or an INIT_EXPR otherwise. */ temp or an INIT_EXPR otherwise. */
fa = argarray[0]; fa = argarray[0];
if (integer_zerop (fa)) if (is_dummy_object (fa))
{ {
if (TREE_CODE (arg) == TARGET_EXPR) if (TREE_CODE (arg) == TARGET_EXPR)
return arg; return arg;
...@@ -7443,10 +7442,7 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args, ...@@ -7443,10 +7442,7 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
/* Handle the special case where INSTANCE is NULL_TREE. */ /* Handle the special case where INSTANCE is NULL_TREE. */
if (name == complete_ctor_identifier && !instance) if (name == complete_ctor_identifier && !instance)
{ instance = build_dummy_object (class_type);
instance = build_int_cst (build_pointer_type (class_type), 0);
instance = build1 (INDIRECT_REF, class_type, instance);
}
else else
{ {
if (name == complete_dtor_identifier if (name == complete_dtor_identifier
...@@ -7756,8 +7752,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args, ...@@ -7756,8 +7752,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
if (init) if (init)
{ {
if (INDIRECT_REF_P (instance) if (is_dummy_object (instance))
&& integer_zerop (TREE_OPERAND (instance, 0)))
return get_target_expr_sfinae (init, complain); return get_target_expr_sfinae (init, complain);
init = build2 (INIT_EXPR, TREE_TYPE (instance), instance, init); init = build2 (INIT_EXPR, TREE_TYPE (instance), instance, init);
TREE_SIDE_EFFECTS (init) = true; TREE_SIDE_EFFECTS (init) = true;
...@@ -7856,6 +7851,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args, ...@@ -7856,6 +7851,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
} }
if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
&& !DECL_CONSTRUCTOR_P (fn)
&& is_dummy_object (instance)) && is_dummy_object (instance))
{ {
instance = maybe_resolve_dummy (instance); instance = maybe_resolve_dummy (instance);
......
...@@ -1427,7 +1427,15 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags) ...@@ -1427,7 +1427,15 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
if (TREE_CODE (*decl) == TEMPLATE_DECL) if (TREE_CODE (*decl) == TEMPLATE_DECL)
decl = &DECL_TEMPLATE_RESULT (*decl); decl = &DECL_TEMPLATE_RESULT (*decl);
decl_attributes (decl, attributes, flags); if (TREE_TYPE (*decl) && TYPE_PTRMEMFUNC_P (TREE_TYPE (*decl)))
{
attributes
= decl_attributes (decl, attributes, flags | ATTR_FLAG_FUNCTION_NEXT);
decl_attributes (&TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (*decl)),
attributes, flags);
}
else
decl_attributes (decl, attributes, flags);
if (TREE_CODE (*decl) == TYPE_DECL) if (TREE_CODE (*decl) == TYPE_DECL)
SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl)); SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
......
...@@ -6,6 +6,6 @@ typedef int (*F [[gnu::warn_unused_result]]) (int); ...@@ -6,6 +6,6 @@ typedef int (*F [[gnu::warn_unused_result]]) (int);
typedef int (*F2 [[gnu::warn_unused_result]]) (int); typedef int (*F2 [[gnu::warn_unused_result]]) (int);
typedef int (S::*F3 [[gnu::warn_unused_result]]) (int); // { dg-warning "only applies to function types" } typedef int (S::*F3 [[gnu::warn_unused_result]]) (int);
typedef int [[gnu::warn_unused_result]] (*F5) (int); // { dg-warning "ignored" } typedef int [[gnu::warn_unused_result]] (*F5) (int); // { dg-warning "ignored" }
// PR c++/60765
// { dg-options "-Wall -Wunused-parameter" }
struct foo
{
} x;
void (foo::*g) (int *) __attribute__ ((nonnull (2)));
void
fun1 (void (foo::*f) (int *) __attribute__ ((nonnull (2))))
{
(x.*f) ((int *) 0); // { dg-warning "null argument" }
}
void
fun2 (void (foo::*f) () __attribute__ ((nonnull, unused))) // { dg-bogus "unused" }
{
(x.*g) ((int *) 0); // { dg-warning "null argument" }
}
// PR c++/60764
// { dg-options "-Wall" }
struct foo
{
foo () __attribute__ ((nonnull (1)));
};
const foo &x = foo (); // { dg-bogus "null argument" }
foo y = foo (); // { dg-bogus "null argument" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment