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).