In an earlier fix, the following change was made in varasm.c for invalid register variables:

--- trunk/gcc/varasm.c  2014/08/26 14:59:59     214525
+++ trunk/gcc/varasm.c  2014/08/26 17:06:31     214526
@@ -1371,6 +1371,11 @@ make_decl_rtl (tree decl)
          /* As a register variable, it has no section.  */
          return;
        }
+      /* Avoid internal errors from invalid register
+        specifications.  */
+      SET_DECL_ASSEMBLER_NAME (decl, NULL_TREE);
+      DECL_HARD_REGISTER (decl) = 0;
+      return;
     }

As seen in PR67639, this makes the IL inconsistent and triggers another internal error where we expect to see an SSA_NAME instead of a VAR_DECL.

The following patch extends the above slightly, by also setting DECL_EXTERNAL to pretend that the erroneous variable is actually a global.

Bootstrapped and tested on x86_64-linux, ok?


Bernd
	PR middle-end/67639
	* varasm.c (make_decl_rtl): Mark invalid register vars as
	DECL_EXTERNAL.

testsuite/
	PR middle-end/67639
	* c-c++-common/pr67639.c: New test.

Index: gcc/testsuite/c-c++-common/pr67639.c
===================================================================
--- gcc/testsuite/c-c++-common/pr67639.c	(revision 0)
+++ gcc/testsuite/c-c++-common/pr67639.c	(working copy)
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+void
+foo (int p)
+{
+  int t; 
+  register long x asm ("rhubarb") = p; /* { dg-error "register name" } */
+  __asm ("" : "=r" (t), "=r" (t), "=r" (t), "=r" (x) : "0" (x));
+}
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	(revision 231653)
+++ gcc/varasm.c	(working copy)
@@ -1420,6 +1420,9 @@ make_decl_rtl (tree decl)
 	 specifications.  */
       SET_DECL_ASSEMBLER_NAME (decl, NULL_TREE);
       DECL_HARD_REGISTER (decl) = 0;
+      /* Also avoid SSA inconsistencies by pretending this is an external
+	 decl now.  */
+      DECL_EXTERNAL (decl) = 1;
       return;
     }
   /* Now handle ordinary static variables and functions (in memory).

Reply via email to