aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Reichelt <reichelt@igpm.rwth-aachen.de>2006-08-26 00:25:59 +0000
committerVolker Reichelt <reichelt@igpm.rwth-aachen.de>2006-08-26 00:25:59 +0000
commit6041360a711617268f4b14b70e136bc074d0a357 (patch)
tree74df540e6aa73f51e712e18ff456fede8456d1e6
parent1b0a5e356408986a70d9dde4e43dbaeb708b84a8 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@116463 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c64
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/other/operator1.C2
-rw-r--r--gcc/testsuite/g++.dg/other/operator2.C10
7 files changed, 68 insertions, 30 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 24fbf9aef27..c56f75675eb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 79018a40878..713d3711420 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2d69cdbae04..542fcbe40af 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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. */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5843a50e57b..749291c63e3 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f74ad90653a..8fa3f7f7893 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/other/operator1.C b/gcc/testsuite/g++.dg/other/operator1.C
index 1760a1c385c..86841c99956 100644
--- a/gcc/testsuite/g++.dg/other/operator1.C
+++ b/gcc/testsuite/g++.dg/other/operator1.C
@@ -5,5 +5,5 @@ int operator=(int); // { dg-error "member function" }
void foo()
{
- operator=(0);
+ operator=(0); // { dg-error "not defined" }
}
diff --git a/gcc/testsuite/g++.dg/other/operator2.C b/gcc/testsuite/g++.dg/other/operator2.C
new file mode 100644
index 00000000000..4b952bf11eb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/operator2.C
@@ -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" }