re PR rtl-optimization/13400 (Compiled code crashes storing to read-only location)

PR middle-end/13400
	* ifcvt.c (noce_process_if_block): Disable unconditional write
	optimizations if we could introduce a store to trapping memory
	that wasn't present previously.

	* gcc.c-torture/execute/20031215-1.c: New test case.

From-SVN: r74663
This commit is contained in:
Roger Sayle 2003-12-16 02:22:59 +00:00 committed by Roger Sayle
parent 3fc63c15b4
commit 040fc92803
4 changed files with 69 additions and 0 deletions

View File

@ -1,3 +1,10 @@
2003-12-15 Roger Sayle <roger@eyesopen.com>
PR middle-end/13400
* ifcvt.c (noce_process_if_block): Disable unconditional write
optimizations if we could introduce a store to trapping memory
that wasn't present previously.
2003-12-15 Kazu Hirata <kazu@cs.umass.edu>
* system.h (DEFAULT_CALLER_SAVES): Poison.

View File

@ -1965,6 +1965,25 @@ noce_process_if_block (struct ce_if_block * ce_info)
goto success;
}
/* Disallow the "if (...) x = a;" form (with an implicit "else x = x;")
for most optimizations if writing to x may trap, i.e. its a memory
other than a static var or a stack slot. */
if (! set_b
&& GET_CODE (orig_x) == MEM
&& ! MEM_NOTRAP_P (orig_x)
&& rtx_addr_can_trap_p (XEXP (orig_x, 0)))
{
if (HAVE_conditional_move)
{
if (noce_try_cmove (&if_info))
goto success;
if (! HAVE_conditional_execution
&& noce_try_cmove_arith (&if_info))
goto success;
}
return FALSE;
}
if (noce_try_move (&if_info))
goto success;
if (noce_try_store_flag (&if_info))

View File

@ -1,3 +1,8 @@
2003-12-15 Roger Sayle <roger@eyesopen.com>
PR middle-end/13400
* gcc.c-torture/execute/20031215-1.c: New test case.
2003-12-15 Mark Mitchell <mark@codesourcery.com>
PR c++/13269

View File

@ -0,0 +1,38 @@
/* PR middle-end/13400 */
/* The following test used to fail at run-time with a write to read-only
memory, caused by if-conversion converting a conditional write into an
unconditional write. */
typedef struct {int c, l; char ch[3];} pstr;
const pstr ao = {2, 2, "OK"};
const pstr * const a = &ao;
void test1(void)
{
if (a->ch[a->l]) {
((char *)a->ch)[a->l] = 0;
}
}
void test2(void)
{
if (a->ch[a->l]) {
((char *)a->ch)[a->l] = -1;
}
}
void test3(void)
{
if (a->ch[a->l]) {
((char *)a->ch)[a->l] = 1;
}
}
int main(void)
{
test1();
test2();
test3();
return 0;
}