re PR c++/28852 (ICE on invalid conversion operator)

PR c++/28852
	* cp-tree.h (grok_op_properties): Return bool instead of void.
	* decl.c (grokfndecl): Discard invalid operator declarations.
	(copy_fn_p): Revert change for PR 27547.
	(grok_op_properties): Return error status (true on success).
	* pt.c (tsubst_decl): Discard invalid operator declarations.

	* g++.dg/other/operator1.C: Add error-marker.
	* g++.dg/other/operator2.C: New test.

From-SVN: r116463
This commit is contained in:
Volker Reichelt 2006-08-26 00:25:59 +00:00 committed by Volker Reichelt
parent b30409daca
commit 398cd19904
7 changed files with 68 additions and 30 deletions

View File

@ -1,3 +1,12 @@
2006-08-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/28852
* cp-tree.h (grok_op_properties): Return bool instead of void.
* decl.c (grokfndecl): Discard invalid operator declarations.
(copy_fn_p): Revert change for PR 27547.
(grok_op_properties): Return error status (true on success).
* pt.c (tsubst_decl): Discard invalid operator declarations.
2006-08-25 Mark Mitchell <mark@codesourcery.com>
PR c++/28056

View File

@ -3899,7 +3899,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, bool);
extern bool 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

@ -6117,8 +6117,9 @@ grokfndecl (tree ctype,
quals = TYPE_UNQUALIFIED;
}
if (IDENTIFIER_OPNAME_P (DECL_NAME (decl)))
grok_op_properties (decl, /*complain=*/true);
if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))
&& !grok_op_properties (decl, /*complain=*/true))
return NULL_TREE;
if (ctype && decl_function_context (decl))
DECL_NO_STATIC_CHAIN (decl) = 1;
@ -8900,9 +8901,7 @@ copy_fn_p (tree d)
tree arg_type;
int result = 1;
if (!DECL_FUNCTION_MEMBER_P (d))
/* Non-members are invalid. We complained, but kept the declaration. */
return 0;
gcc_assert (DECL_FUNCTION_MEMBER_P (d));
if (TREE_CODE (d) == TEMPLATE_DECL
|| (DECL_TEMPLATE_INFO (d)
@ -9055,7 +9054,7 @@ unary_op_p (enum tree_code code)
/* DECL is a declaration for an overloaded operator. If COMPLAIN is true,
errors are issued for invalid declarations. */
void
bool
grok_op_properties (tree decl, bool complain)
{
tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
@ -9141,9 +9140,15 @@ grok_op_properties (tree decl, bool complain)
if (DECL_NAMESPACE_SCOPE_P (decl))
{
if (CP_DECL_CONTEXT (decl) != global_namespace)
error ("%qD may not be declared within a namespace", decl);
{
error ("%qD may not be declared within a namespace", decl);
return false;
}
else if (!TREE_PUBLIC (decl))
error ("%qD may not be declared as static", decl);
{
error ("%qD may not be declared as static", decl);
return false;
}
}
}
@ -9165,7 +9170,7 @@ grok_op_properties (tree decl, bool complain)
|| operator_code == NOP_EXPR)
{
error ("%qD must be a nonstatic member function", decl);
return;
return false;
}
else
{
@ -9175,14 +9180,14 @@ grok_op_properties (tree decl, bool complain)
{
error ("%qD must be either a non-static member "
"function or a non-member function", decl);
return;
return false;
}
for (p = argtypes; p && p != void_list_node; p = TREE_CHAIN (p))
{
tree arg = non_reference (TREE_VALUE (p));
if (arg == error_mark_node)
return;
return false;
/* IS_AGGR_TYPE, rather than CLASS_TYPE_P, is used
because these checks are performed even on
@ -9193,12 +9198,10 @@ grok_op_properties (tree decl, bool complain)
if (!p || p == void_list_node)
{
if (!complain)
return;
error ("%qD must have an argument of class or "
"enumerated type",
decl);
if (complain)
error ("%qD must have an argument of class or "
"enumerated type", decl);
return false;
}
}
}
@ -9206,7 +9209,7 @@ grok_op_properties (tree decl, bool complain)
/* There are no restrictions on the arguments to an overloaded
"operator ()". */
if (operator_code == CALL_EXPR)
return;
return true;
/* Warn about conversion operators that will never be used. */
if (IDENTIFIER_TYPENAME_P (name)
@ -9246,9 +9249,13 @@ grok_op_properties (tree decl, bool complain)
{
/* 13.4.0.3 */
error ("ISO C++ prohibits overloading operator ?:");
return false;
}
else if (ellipsis_p)
error ("%qD must not have variable number of arguments", decl);
{
error ("%qD must not have variable number of arguments", decl);
return false;
}
else if (ambi_op_p (operator_code))
{
if (arity == 1)
@ -9298,11 +9305,11 @@ grok_op_properties (tree decl, bool complain)
{
if (methodp)
error ("postfix %qD must take %<int%> as its argument",
decl);
decl);
else
error
("postfix %qD must take %<int%> as its second argument",
decl);
error ("postfix %qD must take %<int%> as its second "
"argument", decl);
return false;
}
}
else
@ -9311,6 +9318,7 @@ grok_op_properties (tree decl, bool complain)
error ("%qD must take either zero or one argument", decl);
else
error ("%qD must take either one or two arguments", decl);
return false;
}
/* More Effective C++ rule 6. */
@ -9349,6 +9357,7 @@ grok_op_properties (tree decl, bool complain)
error ("%qD must take %<void%>", decl);
else
error ("%qD must take exactly one argument", decl);
return false;
}
}
else /* if (binary_op_p (operator_code)) */
@ -9359,6 +9368,7 @@ grok_op_properties (tree decl, bool complain)
error ("%qD must take exactly one argument", decl);
else
error ("%qD must take exactly two arguments", decl);
return false;
}
/* More Effective C++ rule 7. */
@ -9395,11 +9405,13 @@ grok_op_properties (tree decl, bool complain)
pedwarn ("%qD cannot have default arguments", decl);
}
else
error ("%qD cannot have default arguments", decl);
{
error ("%qD cannot have default arguments", decl);
return false;
}
}
}
return true;
}
/* Return a string giving the keyword associate with CODE. */

View File

@ -6668,8 +6668,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
if (PRIMARY_TEMPLATE_P (gen_tmpl))
clone_function_decl (r, /*update_method_vec_p=*/0);
}
else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
grok_op_properties (r, (complain & tf_error) != 0);
else if (IDENTIFIER_OPNAME_P (DECL_NAME (r))
&& !grok_op_properties (r, (complain & tf_error) != 0))
return error_mark_node;
if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t))
SET_DECL_FRIEND_CONTEXT (r,

View File

@ -1,3 +1,9 @@
2006-08-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/28852
* g++.dg/other/operator1.C: Add error-marker.
* g++.dg/other/operator2.C: New test.
2006-08-25 Joseph S. Myers <joseph@codesourcery.com>
PR c/27893

View File

@ -5,5 +5,5 @@ int operator=(int); // { dg-error "member function" }
void foo()
{
operator=(0);
operator=(0); // { dg-error "not defined" }
}

View File

@ -0,0 +1,10 @@
// PR c++/28852
// { do-do compile }
struct A
{
operator int&(int); // { dg-error "void" }
};
A a;
int& i = a; // { dg-error "initialization" }