diff options
author | Mark Mitchell <mark@codesourcery.com> | 2005-06-03 16:16:46 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-06-03 16:16:46 +0000 |
commit | 7e45bd18daca810d7ecbd83ffcd9e97d31de0f12 (patch) | |
tree | 70ac825253c7f826918234c12f73d0876c812aa0 /gcc/cp/decl.c | |
parent | 83cd747fd944f49180cc60ddb1c3a9f889fb6b63 (diff) | |
download | gcc-7e45bd18daca810d7ecbd83ffcd9e97d31de0f12.zip gcc-7e45bd18daca810d7ecbd83ffcd9e97d31de0f12.tar.gz gcc-7e45bd18daca810d7ecbd83ffcd9e97d31de0f12.tar.bz2 |
re PR c++/21336 (Internal compiler error when using custom new operators)
PR c++/21336
* cp-tree.h (grok_op_properties): Remove friendp parameter.
* decl.c (grokfndecl): Adjust call.
(grok_op_properties): Determine the class of which the function is
a member by looking at its DECL_CONTEXT, not current_class_type.
* pt.c (tsubst_decl): Adjust call to grok_op_properties.
PR c++/21336
* g++.dg/template/new2.C: New test.
From-SVN: r100541
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 86 |
1 files changed, 46 insertions, 40 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6f1394b..6b278ae 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5610,7 +5610,7 @@ grokfndecl (tree ctype, } if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))) - grok_op_properties (decl, friendp, /*complain=*/true); + grok_op_properties (decl, /*complain=*/true); if (ctype && decl_function_context (decl)) DECL_NO_STATIC_CHAIN (decl) = 1; @@ -8608,7 +8608,7 @@ unary_op_p (enum tree_code code) errors are issued for invalid declarations. */ void -grok_op_properties (tree decl, int friendp, bool complain) +grok_op_properties (tree decl, bool complain) { tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); tree argtype; @@ -8616,6 +8616,7 @@ grok_op_properties (tree decl, int friendp, bool complain) tree name = DECL_NAME (decl); enum tree_code operator_code; int arity; + tree class_type; /* Count the number of arguments. */ for (argtype = argtypes, arity = 0; @@ -8623,8 +8624,9 @@ grok_op_properties (tree decl, int friendp, bool complain) argtype = TREE_CHAIN (argtype)) ++arity; - if (current_class_type == NULL_TREE) - friendp = 1; + class_type = DECL_CONTEXT (decl); + if (class_type && !CLASS_TYPE_P (class_type)) + class_type = NULL_TREE; if (DECL_CONV_FN_P (decl)) operator_code = TYPE_EXPR; @@ -8653,30 +8655,28 @@ grok_op_properties (tree decl, int friendp, bool complain) gcc_assert (operator_code != LAST_CPLUS_TREE_CODE); SET_OVERLOADED_OPERATOR_CODE (decl, operator_code); - if (! friendp) - { - switch (operator_code) - { - case NEW_EXPR: - TYPE_HAS_NEW_OPERATOR (current_class_type) = 1; - break; + if (class_type) + switch (operator_code) + { + case NEW_EXPR: + TYPE_HAS_NEW_OPERATOR (class_type) = 1; + break; - case DELETE_EXPR: - TYPE_GETS_DELETE (current_class_type) |= 1; - break; + case DELETE_EXPR: + TYPE_GETS_DELETE (class_type) |= 1; + break; - case VEC_NEW_EXPR: - TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1; - break; + case VEC_NEW_EXPR: + TYPE_HAS_ARRAY_NEW_OPERATOR (class_type) = 1; + break; - case VEC_DELETE_EXPR: - TYPE_GETS_DELETE (current_class_type) |= 2; - break; + case VEC_DELETE_EXPR: + TYPE_GETS_DELETE (class_type) |= 2; + break; - default: - break; - } - } + default: + break; + } /* [basic.std.dynamic.allocation]/1: @@ -8755,32 +8755,38 @@ grok_op_properties (tree decl, int friendp, bool complain) if (operator_code == CALL_EXPR) return; - if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl)) + /* Warn about conversion operators that will never be used. */ + if (IDENTIFIER_TYPENAME_P (name) + && ! DECL_TEMPLATE_INFO (decl) + && warn_conversion + /* Warn only declaring the function; there is no need to + warn again about out-of-class definitions. */ + && class_type == current_class_type) { tree t = TREE_TYPE (name); - if (! friendp) - { - int ref = (TREE_CODE (t) == REFERENCE_TYPE); - const char *what = 0; + int ref = (TREE_CODE (t) == REFERENCE_TYPE); + const char *what = 0; - if (ref) - t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); + if (ref) + t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); - if (TREE_CODE (t) == VOID_TYPE) - what = "void"; - else if (t == current_class_type) + if (TREE_CODE (t) == VOID_TYPE) + what = "void"; + else if (class_type) + { + if (t == class_type) what = "the same type"; /* Don't force t to be complete here. */ else if (IS_AGGR_TYPE (t) && COMPLETE_TYPE_P (t) - && DERIVED_FROM_P (t, current_class_type)) + && DERIVED_FROM_P (t, class_type)) what = "a base class"; - - if (what && warn_conversion) - warning (0, "conversion to %s%s will never use a type " - "conversion operator", - ref ? "a reference to " : "", what); } + + if (what) + warning (0, "conversion to %s%s will never use a type " + "conversion operator", + ref ? "a reference to " : "", what); } if (operator_code == COND_EXPR) { |