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
This commit is contained in:
Mark Mitchell 2005-06-03 16:16:46 +00:00 committed by Mark Mitchell
parent 83cd747fd9
commit 7e45bd18da
6 changed files with 77 additions and 44 deletions

View File

@ -1,3 +1,12 @@
2005-06-03 Mark Mitchell <mark@codesourcery.com>
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-06-02 Nathan Sidwell <nathan@codesourcery.com>
* method.c (synthesize_method): Add addtional arg to warning call.

View File

@ -3766,7 +3766,7 @@ extern int copy_fn_p (tree);
extern tree get_scope_of_declarator (const cp_declarator *);
extern void grok_special_member_properties (tree);
extern int grok_ctor_properties (tree, tree);
extern void grok_op_properties (tree, int, bool);
extern void grok_op_properties (tree, bool);
extern tree xref_tag (enum tag_types, tree, tag_scope, bool);
extern tree xref_tag_from_type (tree, tree, tag_scope);
extern void xref_basetypes (tree, tree);

View File

@ -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;
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 (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)
{

View File

@ -6494,8 +6494,7 @@ tsubst_decl (tree t, tree args, 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,

View File

@ -1,3 +1,8 @@
2005-06-03 Mark Mitchell <mark@codesourcery.com>
PR c++/21336
* g++.dg/template/new2.C: New test.
2005-06-03 Josh Conner <jconner@apple.com>
* gcc.dg/ppc-vector-memcpy.c (foo): Use non-zero values for

View File

@ -0,0 +1,14 @@
// PR c++/21336
typedef __SIZE_TYPE__ size_t;
template<class _T> void* operator new( size_t Size, _T&);
struct B {
int a;
int* m() {
return new(a) int;
}
};
B* n() {
return new B();
}