From 6da7682f86de3d64d68f5956afcf1f120586dd4a Mon Sep 17 00:00:00 2001 From: paolo Date: Wed, 16 Apr 2014 20:17:46 +0000 Subject: [PATCH] 2014-04-16 Patrick Palka PR c++/60765 * decl2.c (cplus_decl_attributes): Handle pointer-to-member-function declarations. 2014-04-16 Patrick Palka 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@209447 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 17 +++++++++++++++++ gcc/cp/call.c | 14 +++++--------- gcc/cp/decl2.c | 10 +++++++++- gcc/testsuite/g++.dg/cpp0x/gen-attrs-36-1.C | 2 +- gcc/testsuite/g++.dg/ext/attrib49.C | 20 ++++++++++++++++++++ gcc/testsuite/g++.dg/warn/nonnull2.C | 10 ++++++++++ 6 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/attrib49.C create mode 100644 gcc/testsuite/g++.dg/warn/nonnull2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f9206e86f33..28c6d969767 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +2014-04-16 Patrick Palka + + PR c++/60765 + * decl2.c (cplus_decl_attributes): Handle + pointer-to-member-function declarations. + +2014-04-16 Patrick Palka + + 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 PR c++/59295 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 7c0dcc2d57a..7dbe9359b44 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3524,8 +3524,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags, { int ctorflags = flags; - first_arg = build_int_cst (build_pointer_type (totype), 0); - first_arg = build_fold_indirect_ref (first_arg); + first_arg = build_dummy_object (totype); /* We should never try to call the abstract or base constructor from here. */ @@ -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 temp or an INIT_EXPR otherwise. */ fa = argarray[0]; - if (integer_zerop (fa)) + if (is_dummy_object (fa)) { if (TREE_CODE (arg) == TARGET_EXPR) return arg; @@ -7443,10 +7442,7 @@ build_special_member_call (tree instance, tree name, vec **args, /* Handle the special case where INSTANCE is NULL_TREE. */ if (name == complete_ctor_identifier && !instance) - { - instance = build_int_cst (build_pointer_type (class_type), 0); - instance = build1 (INDIRECT_REF, class_type, instance); - } + instance = build_dummy_object (class_type); else { if (name == complete_dtor_identifier @@ -7756,8 +7752,7 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, if (init) { - if (INDIRECT_REF_P (instance) - && integer_zerop (TREE_OPERAND (instance, 0))) + if (is_dummy_object (instance)) return get_target_expr_sfinae (init, complain); init = build2 (INIT_EXPR, TREE_TYPE (instance), instance, init); TREE_SIDE_EFFECTS (init) = true; @@ -7856,6 +7851,7 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, } if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE + && !DECL_CONSTRUCTOR_P (fn) && is_dummy_object (instance)) { instance = maybe_resolve_dummy (instance); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 6c52e53bca0..8a7a8369f19 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1427,7 +1427,15 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags) if (TREE_CODE (*decl) == TEMPLATE_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) SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl)); diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36-1.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36-1.C index 2aae9cae00b..131af368a21 100644 --- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36-1.C +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36-1.C @@ -6,6 +6,6 @@ typedef int (*F [[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" } diff --git a/gcc/testsuite/g++.dg/ext/attrib49.C b/gcc/testsuite/g++.dg/ext/attrib49.C new file mode 100644 index 00000000000..99c6154f1a5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib49.C @@ -0,0 +1,20 @@ +// 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" } +} diff --git a/gcc/testsuite/g++.dg/warn/nonnull2.C b/gcc/testsuite/g++.dg/warn/nonnull2.C new file mode 100644 index 00000000000..10515a47405 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/nonnull2.C @@ -0,0 +1,10 @@ +// 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" } -- 2.11.4.GIT