This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Candidate fix for PR c/7353


On Fri, Nov 01, 2002 at 01:38:29PM -0500, Jason Merrill wrote:
> On Fri, 1 Nov 2002 09:45:18 -0800, Zack Weinberg <zack@codesourcery.com> wrote:
> 
> > On Fri, Nov 01, 2002 at 01:55:48AM -0500, Jason Merrill wrote:
> >> This patch causes us to no longer give an error for
> >> 
> >>   struct A {
> >>     typedef int B = 0;
> >>   };
> 
> > Huh?
> >
> > $ ./cc1plus -quiet test.c
> > test.c:2: error: ISO C++ forbids declaration of `B' with no type
> 
> I don't get this error.  It does say 'int', after all...

Oof, sorry, I skimmed right past the 'int' when I retyped the test
case.

In the C++ front end, field declarations don't go through start_decl
so they get missed.  This isn't a problem in C because you can't put
a typedef inside an aggregate at all, in that language.

I'm testing this patch for the bug.

zw

cp:
	PR c/7353 redux
	* decl2.c (grokfield): Reject TYPE_DECLs with initializers.

testsuite:
	* g++.dg/ext/typedef-init.C, gcc.dg/typedef-init.C:
	Add some more cases.

===================================================================
Index: cp/decl2.c
--- cp/decl2.c	31 Oct 2002 16:07:31 -0000	1.569
+++ cp/decl2.c	1 Nov 2002 19:46:35 -0000
@@ -915,7 +915,13 @@ grokfield (declarator, declspecs, init, 
     /* friend or constructor went bad.  */
     return value;
   if (TREE_TYPE (value) == error_mark_node)
-    return error_mark_node;  
+    return error_mark_node;
+
+  if (TREE_CODE (value) == TYPE_DECL && init)
+    {
+      error ("typedef `%D' is initialized (use __typeof__ instead)", value);
+      init = NULL_TREE;
+    }
 
   /* Pass friendly classes back.  */
   if (TREE_CODE (value) == VOID_TYPE)
===================================================================
Index: testsuite/g++.dg/ext/typedef-init.C
--- testsuite/g++.dg/ext/typedef-init.C	9 Oct 2002 21:27:38 -0000	1.1
+++ testsuite/g++.dg/ext/typedef-init.C	1 Nov 2002 19:46:36 -0000
@@ -5,10 +5,29 @@
    it's been broken since GCC 3.0 (caused ICE) and we have now removed
    the extension.  See PR c/7353.
 
-   C++ issues a warning in addition to the error, since this construct
-   appears to be a case of implicit int (forbidden in std. C++) until
-   we get to the equals sign.  */
-
-typedef A = 0;  /* { dg-error "initialized" "typedef A = B" } */
-                /* { dg-warning "no type" "also warns" { target *-*-* } 12 } */
-A a;            /* { dg-bogus "" "no error cascade" } */
+   For cases A and C, C++ issues a warning in addition to the error,
+   since this construct appears to be a case of implicit int
+   (forbidden in std. C++) until we get to the equals sign.  */
+
+/* Case A: just the bare name = initializer.  */
+
+typedef A = 0;  /* { dg-error "initialized" "A" } */
+                /* { dg-warning "no type" "A warns" { target *-*-* } 14 } */
+A a;            /* { dg-bogus "" "A error cascade" } */
+
+/* Case B: with a type also.  */
+
+typedef int B = 0;  /* { dg-error "initialized" "B" } */
+B b;		    /* { dg-bogus "" "B error cascade" } */
+
+/* C and D are the same as A and B, but wrapped in a structure;
+   field declarations go by a different code path in C++ (ick).  */
+
+struct S {
+  typedef C = 0; /* { dg-error "initialized" "C" } */
+                 /* { dg-warning "no type" "C warns" { target *-*-* } 27 } */
+  C c;		 /* { dg-bogus "" "C error cascade" } */
+
+  typedef int D = 0; /* { dg-error "initialized" "D" } */
+  D d;		     /* { dg-bogus "" "D error cascade" } */
+};
===================================================================
Index: testsuite/gcc.dg/typedef-init.c
--- testsuite/gcc.dg/typedef-init.c	9 Oct 2002 21:27:38 -0000	1.1
+++ testsuite/gcc.dg/typedef-init.c	1 Nov 2002 19:46:37 -0000
@@ -5,5 +5,12 @@
    it's been broken since GCC 3.0 (caused ICE) and we have now removed
    the extension.  See PR c/7353.  */
 
-typedef A = 0;  /* { dg-error "initialized" "typedef A = B" } */
-A a;            /* { dg-bogus "" "no error cascade" } */
+/* Case A: just the bare name = initializer.  */
+
+typedef A = 0;  /* { dg-error "initialized" "A" } */
+A a;            /* { dg-bogus "" "A error cascade" } */
+
+/* Case B: with a type also.  */
+
+typedef int B = 0;  /* { dg-error "initialized" "B" } */
+B b;		    /* { dg-bogus "" "B error cascade" } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]