summaryrefslogtreecommitdiff
path: root/gcc/reload1.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2005-04-20 12:02:40 -0600
committerJeff Law <law@gcc.gnu.org>2005-04-20 12:02:40 -0600
commitad1032fd92e96960ecf2efd0ca26f7c1899a2bd9 (patch)
treec23d3cf2e1d3a9964cbe98f26ed40c908b4fafc9 /gcc/reload1.c
parent187230a795716fc0d98cb066402fe9d71639996c (diff)
downloadgcc-ad1032fd92e96960ecf2efd0ca26f7c1899a2bd9.tar.gz
reload1.c (reload): Ignore equivalences between pseudos and read only memory.
* reload1.c (reload): Ignore equivalences between pseudos and read only memory. From-SVN: r98466
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r--gcc/reload1.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 5e1ab1a27cc..b2200a8d3b3 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -740,8 +740,20 @@ reload (rtx first, int global)
that is not a legitimate memory operand. As later
stages of reload assume that all addresses found
in the reg_equiv_* arrays were originally legitimate,
- we ignore such REG_EQUIV notes. */
- if (memory_operand (x, VOIDmode))
+
+ It can also happen that a REG_EQUIV note contains a
+ readonly memory location. If the destination pseudo
+ is set from some other value (typically a different
+ pseudo), and the destination pseudo does not get a
+ hard reg, then reload will replace the destination
+ pseudo with its equivalent memory location. This
+ is horribly bad as it creates a store to a readonly
+ memory location and a runtime segfault. To avoid
+ this problem we reject readonly memory locations
+ for equivalences. This is overly conservative as
+ we could find all sets of the destination pseudo
+ and remove them as they should be redundant. */
+ if (memory_operand (x, VOIDmode) && ! MEM_READONLY_P (x))
{
/* Always unshare the equivalence, so we can
substitute into this insn without touching the