OSDN Git Service

PR c++/10428
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Apr 2003 21:05:58 +0000 (21:05 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Apr 2003 21:05:58 +0000 (21:05 +0000)
* g++.dg/parse/elab1.C: New test.

PR c++/10428
* decl.c (check_elaborated_type_specifier): New function, split
out from ...
(xref_tag): ... here.  Use the new function in more places.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@65956 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/elab1.C [new file with mode: 0644]

index e5940ff..ec4684d 100644 (file)
@@ -1,5 +1,10 @@
 2003-04-22  Mark Mitchell  <mark@codesourcery.com>
 
 2003-04-22  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/10428
+       * decl.c (check_elaborated_type_specifier): New function, split
+       out from ...
+       (xref_tag): ... here.  Use the new function in more places.
+
        * rtti.c (throw_bad_typeid): Use build_cxx_call.
 
 2003-04-21  Mark Mitchell  <mark@codesourcery.com>
        * rtti.c (throw_bad_typeid): Use build_cxx_call.
 
 2003-04-21  Mark Mitchell  <mark@codesourcery.com>
index a14389f..84e267e 100644 (file)
@@ -12525,6 +12525,38 @@ tag_name (enum tag_types code)
     }
 }
 
     }
 }
 
+/* Name lookup in an elaborated-type-specifier (after the keyword
+   indicated by TAG_CODE) has found TYPE.  If the
+   elaborated-type-specifier is invalid, issue a diagnostic and return
+   error_mark_node; otherwise, return TYPE itself.  */
+
+static tree
+check_elaborated_type_specifier (enum tag_types tag_code,
+                                tree type)
+{
+  tree t;
+
+  t = follow_tag_typedef (type);
+
+  /* [dcl.type.elab] If the identifier resolves to a typedef-name or a
+     template type-parameter, the elaborated-type-specifier is
+     ill-formed.  */
+  if (!t)
+    {
+      error ("using typedef-name `%D' after `%s'",
+            TYPE_NAME (type), tag_name (tag_code));
+      t = error_mark_node;
+    }
+  else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+    {
+      error ("using template type parameter `%T' after `%s'",
+            type, tag_name (tag_code));
+      t = error_mark_node;
+    }
+
+  return t;
+}
+
 /* Get the struct, enum or union (CODE says which) with tag NAME.
    Define the tag as a forward-reference if it is not defined.
 
 /* Get the struct, enum or union (CODE says which) with tag NAME.
    Define the tag as a forward-reference if it is not defined.
 
@@ -12611,20 +12643,9 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
     {
       if (t)
        {
     {
       if (t)
        {
-         ref = follow_tag_typedef (t);
-
-         /* [dcl.type.elab] If the identifier resolves to a
-            typedef-name or a template type-parameter, the
-            elaborated-type-specifier is ill-formed.  */
-         if (!ref)
-           {
-             pedwarn ("using typedef-name `%D' after `%s'",
-                      TYPE_NAME (t), tag_name (tag_code));
-             ref = t;
-           }
-         else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
-           error ("using template type parameter `%T' after `%s'",
-                  t, tag_name (tag_code));
+         ref = check_elaborated_type_specifier (tag_code, t);
+         if (ref == error_mark_node)
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
        }
       else
        ref = lookup_tag (code, name, b, 0);
        }
       else
        ref = lookup_tag (code, name, b, 0);
@@ -12643,9 +12664,15 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
               template, so we want this type.  */
            ref = DECL_TEMPLATE_RESULT (ref);
 
               template, so we want this type.  */
            ref = DECL_TEMPLATE_RESULT (ref);
 
-         if (ref && TREE_CODE (ref) == TYPE_DECL
-             && TREE_CODE (TREE_TYPE (ref)) == code)
-           ref = TREE_TYPE (ref);
+         if (ref && TREE_CODE (ref) == TYPE_DECL)
+           {
+             ref = check_elaborated_type_specifier (tag_code, 
+                                                    TREE_TYPE (ref));
+             if (ref == error_mark_node)
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+             if (ref && TREE_CODE (ref) != code)
+               ref = NULL_TREE;
+           }
          else
            ref = NULL_TREE;
        }
          else
            ref = NULL_TREE;
        }
index 3face0f..35bbeb9 100644 (file)
@@ -1,3 +1,7 @@
+2003-04-22  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/10428
+       * g++.dg/parse/elab1.C: New test.
 
 2003-04-22  Devang Patel  <dpatel@apple.com>
 
 
 2003-04-22  Devang Patel  <dpatel@apple.com>
 
diff --git a/gcc/testsuite/g++.dg/parse/elab1.C b/gcc/testsuite/g++.dg/parse/elab1.C
new file mode 100644 (file)
index 0000000..2997eef
--- /dev/null
@@ -0,0 +1,9 @@
+namespace Name {
+
+    typedef void *(*Function)( void *, int );
+
+    struct Foo {
+      struct Function xyz[5]; // { dg-error "" }
+    };
+
+}