OSDN Git Service

PR c++/28852
authorreichelt <reichelt@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 26 Aug 2006 00:25:59 +0000 (00:25 +0000)
committerreichelt <reichelt@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 26 Aug 2006 00:25:59 +0000 (00:25 +0000)
* 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: svn+ssh://gcc.gnu.org/svn/gcc/trunk@116463 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/operator1.C
gcc/testsuite/g++.dg/other/operator2.C [new file with mode: 0644]

index 24fbf9a..c56f756 100644 (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
index 79018a4..713d371 100644 (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);
index 2d69cdb..542fcbe 100644 (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;
 }
 \f
 /* Return a string giving the keyword associate with CODE.  */
index 5843a50..749291c 100644 (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,
index f74ad90..8fa3f7f 100644 (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
index 1760a1c..86841c9 100644 (file)
@@ -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 (file)
index 0000000..4b952bf
--- /dev/null
@@ -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" }