From 04ec9f69bcc07132fc9261ec1079d58fd02e1cd6 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 3 Jun 2005 16:29:35 +0000 Subject: [PATCH] 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: r100545 --- gcc/cp/ChangeLog | 9 +++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/decl.c | 87 ++++++++++++++++++++++------------------- gcc/cp/pt.c | 3 +- gcc/testsuite/ChangeLog | 5 +++ 5 files changed, 62 insertions(+), 44 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 55f3c46f788e..74f3b1b80f43 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2005-06-03 Mark Mitchell + + 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. + 2005-05-26 Volker Reichelt PR c++/21768 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ed33f3271d79..cc1f937e19d1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3683,7 +3683,7 @@ extern int copy_fn_p (tree); extern tree get_scope_of_declarator (tree); extern void grok_special_member_properties (tree); extern int grok_ctor_properties (tree, tree); -extern bool grok_op_properties (tree, int, bool); +extern bool grok_op_properties (tree, bool); extern tree xref_tag (enum tag_types, tree, bool, bool); extern tree xref_tag_from_type (tree, tree, int); extern void xref_basetypes (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6c7cece8eee1..699fe0225b98 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5718,7 +5718,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; @@ -9004,7 +9004,7 @@ unary_op_p (enum tree_code code) errors are issued for invalid declarations. */ bool -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; @@ -9013,6 +9013,7 @@ grok_op_properties (tree decl, int friendp, bool complain) enum tree_code operator_code; int arity; bool ok; + tree class_type; /* Assume that the declaration is valid. */ ok = true; @@ -9023,9 +9024,10 @@ 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; else @@ -9053,30 +9055,28 @@ grok_op_properties (tree decl, int friendp, bool complain) my_friendly_assert (operator_code != LAST_CPLUS_TREE_CODE, 20000526); 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; + } if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR) TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl)); @@ -9130,31 +9130,36 @@ grok_op_properties (tree decl, int friendp, bool complain) if (operator_code == CALL_EXPR) return ok; - 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 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; + + if (ref) + t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); + + if (TREE_CODE (t) == VOID_TYPE) + what = "void"; + else if (class_type) { - int ref = (TREE_CODE (t) == REFERENCE_TYPE); - const char *what = 0; - - if (ref) - t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); - - if (TREE_CODE (t) == VOID_TYPE) - what = "void"; - else if (t == current_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 ("conversion to %s%s will never use a type conversion operator", - ref ? "a reference to " : "", what); } + + if (what) + warning ("conversion to %s%s will never use a type conversion operator", + ref ? "a reference to " : "", what); } if (operator_code == COND_EXPR) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d97b75072f65..d3cc61e9d277 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6291,8 +6291,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) clone_function_decl (r, /*update_method_vec_p=*/0); } else if (IDENTIFIER_OPNAME_P (DECL_NAME (r))) - grok_op_properties (r, DECL_FRIEND_P (r), - (complain & tf_error) != 0); + grok_op_properties (r, (complain & tf_error) != 0); if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t)) SET_DECL_FRIEND_CONTEXT (r, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 78eee781c6d4..3b74f891fe8d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-06-03 Mark Mitchell + + PR c++/21336 + * g++.dg/template/new2.C: New test. + 2005-05-29 Eric Botcazou * gcc.dg/c99-math.h: New -- 2.47.2