OSDN Git Service

PR c++/17524
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 9 Oct 2004 17:33:02 +0000 (17:33 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 9 Oct 2004 17:33:02 +0000 (17:33 +0000)
* cp-tree.h (check_var_type): New function.
* decl.c (check_var_type): New function, split out from ...
(grokdeclarator): ... here.
* pt.c (tsubst_decl): Use check_var_type.

PR c++/17685
* decl.c (grokdeclarator): Disallow declarations of operators as

PR c++/17524
* g++.dg/template/static9.C: New test.

PR c++/17685
* g++.dg/parse/operator5.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88820 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/parse/operator5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/static9.C [new file with mode: 0644]

index ca408ec..5c4c7c8 100644 (file)
@@ -1,3 +1,15 @@
+2004-10-09  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/17524
+       * cp-tree.h (check_var_type): New function.
+       * decl.c (check_var_type): New function, split out from ...
+       (grokdeclarator): ... here.
+       * pt.c (tsubst_decl): Use check_var_type.
+
+       PR c++/17685
+       * decl.c (grokdeclarator): Disallow declarations of operators as
+       non-functions.
+       
 2004-10-08  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        PR c++/17868
index 826bd51..ca0722a 100644 (file)
@@ -3759,6 +3759,7 @@ extern void warn_extern_redeclared_static (tree, tree);
 extern const char *cxx_comdat_group             (tree);
 extern bool cp_missing_noreturn_ok_p           (tree);
 extern void initialize_artificial_var            (tree, tree);
+extern tree check_var_type (tree, tree);
 
 extern bool have_extern_spec;
 
index 919b619..fa50faa 100644 (file)
@@ -6395,6 +6395,31 @@ check_special_function_return_type (special_function_kind sfk,
   return type;
 }
 
+/* A variable or data member (whose unqualified name is IDENTIFIER)
+   has been declared with the indicated TYPE.  If the TYPE is not
+   acceptable, issue an error message and return a type to use for
+   error-recovery purposes. */
+
+tree
+check_var_type (tree identifier, tree type)
+{
+  if (VOID_TYPE_P (type))
+    {
+      if (!identifier)
+       error ("unnamed variable or field declared void");
+      else if (TREE_CODE (identifier) == IDENTIFIER_NODE)
+       {
+         gcc_assert (!IDENTIFIER_OPNAME_P (identifier));
+         error ("variable or field %qE declared void", identifier);
+       }
+      else
+       error ("variable or field declared void");
+      type = integer_type_node;
+    }
+  
+  return type;
+}
+
 /* Given declspecs and a declarator (abstract or otherwise), determine
    the name and type of the object declared and construct a DECL node
    for it.
@@ -7743,25 +7768,21 @@ grokdeclarator (const cp_declarator *declarator,
       unqualified_id = make_anon_name ();
     }
 
-  /* `void' at top level (not within pointer)
-     is allowed only in typedefs or type names.
-     We don't complain about parms either, but that is because
-     a better error message can be made later.  */
-
-  if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM)
+  /* Only functions may be declared using an operator-function-id.  */
+  if (unqualified_id
+      && IDENTIFIER_OPNAME_P (unqualified_id)
+      && TREE_CODE (type) != FUNCTION_TYPE
+      && TREE_CODE (type) != METHOD_TYPE)
     {
-      if (! unqualified_id)
-       error ("unnamed variable or field declared void");
-      else if (TREE_CODE (unqualified_id) == IDENTIFIER_NODE)
-       {
-         gcc_assert (!IDENTIFIER_OPNAME_P (unqualified_id));
-         error ("variable or field %qs declared void", name);
-       }
-      else
-       error ("variable or field declared void");
-      type = integer_type_node;
+      error ("declaration of %qD as non-function", unqualified_id);
+      return error_mark_node;
     }
 
+  /* We don't check parameter types here because we can emit a better
+     error message later.  */
+  if (decl_context != PARM)
+    type = check_var_type (unqualified_id, type);
+
   /* Now create the decl, which may be a VAR_DECL, a PARM_DECL
      or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE.  */
 
index 9a869ea..c794e35 100644 (file)
@@ -6508,6 +6508,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
            type = complete_type (type);
            DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
              = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
+           type = check_var_type (DECL_NAME (r), type);
          }
        else if (DECL_SELF_REFERENCE_P (t))
          SET_DECL_SELF_REFERENCE_P (r);
@@ -6548,9 +6549,6 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
          register_local_specialization (r, t);
 
        TREE_CHAIN (r) = NULL_TREE;
-       if (TREE_CODE (r) == VAR_DECL && VOID_TYPE_P (type))
-         cp_error_at ("instantiation of %qD as type %qT", r, type);
-       /* Compute the size, alignment, etc. of R.  */
        layout_decl (r, 0);
       }
       break;
index 28d0a11..b91dec5 100644 (file)
@@ -1,3 +1,11 @@
+2004-10-09  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/17524
+       * g++.dg/template/static9.C: New test.
+
+       PR c++/17685
+       * g++.dg/parse/operator5.C: New test.
+
 2004-10-09  Roger Sayle  <roger@eyesopen.com>
 
        PR middle-end/17894
diff --git a/gcc/testsuite/g++.dg/parse/operator5.C b/gcc/testsuite/g++.dg/parse/operator5.C
new file mode 100644 (file)
index 0000000..3e453bd
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/17685
+
+struct S {
+  operator int; // { dg-error "" }
+  operator void; // { dg-error "" }
+};
+
diff --git a/gcc/testsuite/g++.dg/template/static9.C b/gcc/testsuite/g++.dg/template/static9.C
new file mode 100644 (file)
index 0000000..4575708
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/17524
+
+template<typename T> struct A
+{
+  static const T i = 0; // { dg-error "" }
+};
+
+A<void> a; // { dg-error "" }