[C++] PR 84792 ("[6/7/8 Regression] ICE with broken typedef of a struct")

Message ID 535f57c0-d193-adfc-a3b9-6a0407e0d731@oracle.com
State New
Headers show
Series
  • [C++] PR 84792 ("[6/7/8 Regression] ICE with broken typedef of a struct")
Related show

Commit Message

Paolo Carlini April 5, 2018, 12:48 a.m.
Hi,

I'm really happy to report that these 5 ugly lines are causing an actual 
bug. Seriously, not considering the formatting, the problem is that we 
really want to keep 'type' in sync, because we are using it below before 
returning. Note that we don't regress location-wise because either 
explicitly or implicitly we pass input_location anyway. Finishing 
testing on x86_64-linux.

Thanks, Paolo.

////////////////////
/cp
2018-04-04  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/84792
	* decl.c (grokdeclarator): Fix diagnostic about typedef name used
	as nested-name-specifier, keep type and TREE_TYPE (decl) in sync.

/testsuite
2018-04-04  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/84792
	* g++.dg/other/pr84792-1.C: New.
	* g++.dg/other/pr84792-2.C: Likewise.

Comments

Jason Merrill April 5, 2018, 1:42 p.m. | #1
On Wed, Apr 4, 2018 at 8:48 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> I'm really happy to report that these 5 ugly lines are causing an actual

> bug. Seriously, not considering the formatting, the problem is that we

> really want to keep 'type' in sync, because we are using it below before

> returning. Note that we don't regress location-wise because either

> explicitly or implicitly we pass input_location anyway. Finishing testing on

> x86_64-linux.


Hmm, I wonder why we need to make the type error_mark_node at all,
given that the problem is with the declarator.

But this patch is OK.

Jason

Patch

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 259104)
+++ cp/decl.c	(working copy)
@@ -11746,15 +11746,16 @@  grokdeclarator (const cp_declarator *declarator,
       if (reqs)
 	error_at (location_of (reqs), "requires-clause on typedef");
 
+      if (id_declarator && declarator->u.id.qualifying_scope)
+	{
+	  error ("typedef name may not be a nested-name-specifier");
+	  type = error_mark_node;
+	}
+
       if (decl_context == FIELD)
 	decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
       else
 	decl = build_decl (input_location, TYPE_DECL, unqualified_id, type);
-      if (id_declarator && declarator->u.id.qualifying_scope) {
-	error_at (DECL_SOURCE_LOCATION (decl), 
-		  "typedef name may not be a nested-name-specifier");
-	TREE_TYPE (decl) = error_mark_node;
-      }
 
       if (decl_context != FIELD)
 	{
Index: testsuite/g++.dg/other/pr84792-1.C
===================================================================
--- testsuite/g++.dg/other/pr84792-1.C	(nonexistent)
+++ testsuite/g++.dg/other/pr84792-1.C	(working copy)
@@ -0,0 +1,6 @@ 
+struct A {};
+
+typedef struct
+{
+  virtual void foo() {}
+} A::B;  // { dg-error "typedef" }
Index: testsuite/g++.dg/other/pr84792-2.C
===================================================================
--- testsuite/g++.dg/other/pr84792-2.C	(nonexistent)
+++ testsuite/g++.dg/other/pr84792-2.C	(working copy)
@@ -0,0 +1,6 @@ 
+struct A {};
+
+typedef struct
+{
+  void foo() {}
+} A::B;  // { dg-error "typedef" }