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]

[patch] Fix PR c++/27572: ICE on typedef in parameter declaration


The C++ frontend gets hiccups (a.k.a. ICEs) when a typedef appears in
a parameter declaration. This affects function parameters as well as
template parameters. Consider for example 

  void foo(typedef) {}

or

  template<typedef,int> struct A;

For more testcases see PR c++/27572 and the testcases below.

The problem is that grokdeclarator in decl.c complains about the invalid
typedef, but later returns a TYPE_DECL anyway. From there things go
downhill.

The patch below just resets the flag for a typedef if it is not allowed.
Due to the definition of declspecs as "const cp_decl_specifier_seq*"
we cannot modify "declspecs->specs[(int)ds_typedef]" directly. So we
have to track the status in a new local variable "typedefp".

The patch is mostly mechanical, as it replaces all uses of
"declspecs->specs[(int)ds_typedef]" by "typedefp". The only interesting
part is the third hunk where typedefp is reset for parameters.

Bootstrapped and regtested on x86_64-unknown-linux-gnu.
Ok for mainline, 4.1 branch, and 4.0 branch?

Btw, "typedefp" is now the sixth variable to track the status of
declspecs locally in grokdeclarator. Wouldn't it make more sense in
the long run to skip the "const" in "declspecs" and modify the
original specs direcly?

Regards,
Volker

:ADDPATCH C++:


2006-05-12  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/27572
	* decl.c (grokdeclarator): Track status of
	declspecs->specs[(int)ds_typedef] in new variable typedefp.
	Reset typedefp if a typedef decl is not	allowed.

===================================================================
--- gcc/gcc/cp/decl.c	(revision 113706)
+++ gcc/gcc/cp/decl.c	(working copy)
@@ -6794,7 +6794,7 @@ grokdeclarator (const cp_declarator *dec
 {
   tree type = NULL_TREE;
   int longlong = 0;
-  int virtualp, explicitp, friendp, inlinep, staticp;
+  int virtualp, explicitp, friendp, inlinep, staticp, typedefp;
   int explicit_int = 0;
   int explicit_char = 0;
   int defaulted_int = 0;
@@ -7269,6 +7269,7 @@ grokdeclarator (const cp_declarator *dec
   inlinep = !! declspecs->specs[(int)ds_inline];
   virtualp = !! declspecs->specs[(int)ds_virtual];
   explicitp = !! declspecs->specs[(int)ds_explicit];
+  typedefp = !! declspecs->specs[(int)ds_typedef];
 
   storage_class = declspecs->storage_class;
   if (storage_class == sc_static)
@@ -7291,8 +7292,11 @@ grokdeclarator (const cp_declarator *dec
   /* Issue errors about use of storage classes for parameters.  */
   if (decl_context == PARM)
     {
-      if (declspecs->specs[(int)ds_typedef])
-	error ("typedef declaration invalid in parameter declaration");
+      if (typedefp)
+	{
+	  error ("typedef declaration invalid in parameter declaration");
+	  typedefp = 0;
+	}
       else if (storage_class == sc_static
 	       || storage_class == sc_extern
 	       || thread_p)
@@ -7324,7 +7328,7 @@ grokdeclarator (const cp_declarator *dec
 	   && ((storage_class
 		&& storage_class != sc_extern
 		&& storage_class != sc_static)
-	       || declspecs->specs[(int)ds_typedef]))
+	       || typedefp))
     {
       error ("multiple storage classes in declaration of %qs", name);
       thread_p = false;
@@ -7338,7 +7342,7 @@ grokdeclarator (const cp_declarator *dec
 	  && (storage_class == sc_register
 	      || storage_class == sc_auto))
 	;
-      else if (declspecs->specs[(int)ds_typedef])
+      else if (typedefp)
 	;
       else if (decl_context == FIELD
 	       /* C++ allows static class elements.  */
@@ -7762,8 +7766,7 @@ grokdeclarator (const cp_declarator *dec
 	  else
 	    type = build_memfn_type (type, ctype, memfn_quals);
 	}
-      else if (declspecs->specs[(int)ds_typedef]
-	       && current_class_type)
+      else if (typedefp && current_class_type)
 	{
 	  error ("cannot declare member %<%T::%s%> within %qT",
 		 ctype, name, current_class_type);
@@ -7820,7 +7823,7 @@ grokdeclarator (const cp_declarator *dec
 	  error ("non-member %qs cannot be declared %<mutable%>", name);
 	  storage_class = sc_none;
 	}
-      else if (decl_context == TYPENAME || declspecs->specs[(int)ds_typedef])
+      else if (decl_context == TYPENAME || typedefp)
 	{
 	  error ("non-object member %qs cannot be declared %<mutable%>", name);
 	  storage_class = sc_none;
@@ -7844,7 +7847,7 @@ grokdeclarator (const cp_declarator *dec
     }
 
   /* If this is declaring a typedef name, return a TYPE_DECL.  */
-  if (declspecs->specs[(int)ds_typedef] && decl_context != TYPENAME)
+  if (typedefp && decl_context != TYPENAME)
     {
       tree decl;
 
===================================================================

2006-05-12  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/27572
	* g++.dg/other/typedef1.C: New test.
	* g++.dg/template/typedef4.C: New test.
	* g++.dg/template/typedef5.C: New test.

===================================================================
--- gcc/gcc/testsuite/g++.dg/other/typedef1.C	2005-08-29 00:25:44 +0200
+++ gcc/gcc/testsuite/g++.dg/other/typedef1.C	2006-05-12 10:17:42 +0200
@@ -0,0 +1,7 @@
+// PR c++/27572
+// { dg-do compile }
+
+void f1(typedef) {}        // { dg-error "no type|typedef declaration" }
+void f2(typedef x) {}      // { dg-error "no type|typedef declaration" }
+void f3(typedef x[]) {}    // { dg-error "no type|typedef declaration" }
+void f4(typedef int x) {}  // { dg-error "typedef declaration" }
===================================================================
--- gcc/gcc/testsuite/g++.dg/template/typedef4.C	2005-08-29 00:25:44 +0200
+++ gcc/gcc/testsuite/g++.dg/template/typedef4.C	2006-05-12 10:17:42 +0200
@@ -0,0 +1,9 @@
+// PR c++/27572
+// { dg-do compile }
+
+template<typedef> void foo();  // { dg-error "no type|typedef declaration" }
+
+void bar()
+{
+  foo<int>();                  // { dg-error "matching" }
+}
===================================================================
--- gcc/gcc/testsuite/g++.dg/template/typedef5.C	2005-08-29 00:25:44 +0200
+++ gcc/gcc/testsuite/g++.dg/template/typedef5.C	2006-05-12 10:17:42 +0200
@@ -0,0 +1,16 @@
+// PR c++/27572
+// { dg-do compile }
+
+template<typedef,int>        struct A1; // { dg-error "no type|typedef declaration" }
+template<typedef x,int>      struct A2; // { dg-error "no type|typedef declaration" }
+template<typedef x[],int>    struct A3; // { dg-error "no type|typedef declaration" }
+template<typedef int x, int> struct A4; // { dg-error "typedef declaration" }
+
+template<typedef> struct B // { dg-error "no type|typedef declaration" }
+{
+  void f1();
+  void f2();
+  friend void g();
+};
+
+B<int> b; // { dg-error "type/value mismatch|expected a constant|invalid type" }
===================================================================



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