aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2014-08-26 18:06:31 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2014-08-26 18:06:31 +0100
commitc218f6e89d7bee930ad705642cf069262432990a (patch)
tree2f34eb8a53683a3f2846042c1e5dfe9d0d5c16ed /gcc
parent43f4a446c24f8a950442c0d432788704a0531bf3 (diff)
downloadgcc-c218f6e89d7bee930ad705642cf069262432990a.zip
gcc-c218f6e89d7bee930ad705642cf069262432990a.tar.gz
gcc-c218f6e89d7bee930ad705642cf069262432990a.tar.bz2
Fix ARM ICE for register var asm ("pc") (PR target/60606).
PR target/60606 PR target/61330 * varasm.c (make_decl_rtl): Clear DECL_ASSEMBLER_NAME and DECL_HARD_REGISTER and return for invalid register specifications. * cfgexpand.c (expand_one_var): If expand_one_hard_reg_var clears DECL_HARD_REGISTER, call expand_one_error_var. * config/arm/arm.c (arm_hard_regno_mode_ok): Do not allow CC_REGNUM with non-MODE_CC modes. (arm_regno_class): Return NO_REGS for PC_REGNUM. testsuite: * gcc.dg/torture/pr60606-1.c, gcc.target/arm/pr60606-2.c, gcc.target/arm/pr60606-3.c, gcc.target/arm/pr60606-4.c: New tests. From-SVN: r214526
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/cfgexpand.c7
-rw-r--r--gcc/config/arm/arm.c6
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr60606-1.c9
-rw-r--r--gcc/testsuite/gcc.target/arm/pr60606-2.c10
-rw-r--r--gcc/testsuite/gcc.target/arm/pr60606-3.c9
-rw-r--r--gcc/testsuite/gcc.target/arm/pr60606-4.c9
-rw-r--r--gcc/varasm.c5
9 files changed, 73 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6b9bc1c..93d29a2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2014-08-26 Joseph Myers <joseph@codesourcery.com>
+
+ PR target/60606
+ PR target/61330
+ * varasm.c (make_decl_rtl): Clear DECL_ASSEMBLER_NAME and
+ DECL_HARD_REGISTER and return for invalid register specifications.
+ * cfgexpand.c (expand_one_var): If expand_one_hard_reg_var clears
+ DECL_HARD_REGISTER, call expand_one_error_var.
+ * config/arm/arm.c (arm_hard_regno_mode_ok): Do not allow
+ CC_REGNUM with non-MODE_CC modes.
+ (arm_regno_class): Return NO_REGS for PC_REGNUM.
+
2014-08-26 Marek Polacek <polacek@redhat.com>
PR c/61271
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 6c2b693..34e57b9 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1307,7 +1307,12 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
{
if (really_expand)
- expand_one_hard_reg_var (var);
+ {
+ expand_one_hard_reg_var (var);
+ if (!DECL_HARD_REGISTER (var))
+ /* Invalid register specification. */
+ expand_one_error_var (var);
+ }
}
else if (use_register_for_decl (var))
{
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index d9f38f4..11e0655 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -22970,6 +22970,9 @@ arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
|| (TARGET_HARD_FLOAT && TARGET_VFP
&& regno == VFPCC_REGNUM));
+ if (regno == CC_REGNUM && GET_MODE_CLASS (mode) != MODE_CC)
+ return false;
+
if (TARGET_THUMB1)
/* For the Thumb we only allow values bigger than SImode in
registers 0 - 6, so that there is always a second low
@@ -23066,6 +23069,9 @@ arm_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
enum reg_class
arm_regno_class (int regno)
{
+ if (regno == PC_REGNUM)
+ return NO_REGS;
+
if (TARGET_THUMB1)
{
if (regno == STACK_POINTER_REGNUM)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bdbb212..3290e7d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2014-08-26 Joseph Myers <joseph@codesourcery.com>
+
+ PR target/60606
+ PR target/61330
+ * gcc.dg/torture/pr60606-1.c, gcc.target/arm/pr60606-2.c,
+ gcc.target/arm/pr60606-3.c, gcc.target/arm/pr60606-4.c: New tests.
+
2014-08-26 Dominik Vogt <vogt@linux.vnet.ibm.com>
* gfortran.dg/bessel_7.f90: Bump allowed precision to avoid
diff --git a/gcc/testsuite/gcc.dg/torture/pr60606-1.c b/gcc/testsuite/gcc.dg/torture/pr60606-1.c
new file mode 100644
index 0000000..c4afae7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr60606-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-ffat-lto-objects" } */
+
+int
+f (void)
+{
+ register unsigned int r asm ("no-such-register"); /* { dg-error "invalid register name" } */
+ return r;
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr60606-2.c b/gcc/testsuite/gcc.target/arm/pr60606-2.c
new file mode 100644
index 0000000..7baf881
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr60606-2.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int
+f (void)
+{
+ register unsigned pc asm ("pc"); /* { dg-error "not general enough" } */
+
+ return pc > 0x12345678;
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr60606-3.c b/gcc/testsuite/gcc.target/arm/pr60606-3.c
new file mode 100644
index 0000000..60ae27d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr60606-3.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int
+f (void)
+{
+ register unsigned int r asm ("cc"); /* { dg-error "not general enough|suitable for data type" } */
+ return r;
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr60606-4.c b/gcc/testsuite/gcc.target/arm/pr60606-4.c
new file mode 100644
index 0000000..5288777
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr60606-4.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int
+f (void)
+{
+ register unsigned int r[50] asm ("r1"); /* { dg-error "suitable for a register" } */
+ return r[1];
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 80a3285..ce99a13 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -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;
}
/* Now handle ordinary static variables and functions (in memory).
Also handle vars declared register invalidly. */