aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-eh.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2014-02-10 13:51:23 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2014-02-10 13:51:23 +0000
commit4e1f39e43a61a05299036307745d54fadbfa4971 (patch)
treeef09c2d939f1341f5a928daca4ec870b32320b8f /gcc/tree-eh.c
parente7af1c221d51f354ed7b6026a6629524fd2974d8 (diff)
downloadgcc-4e1f39e43a61a05299036307745d54fadbfa4971.zip
gcc-4e1f39e43a61a05299036307745d54fadbfa4971.tar.gz
gcc-4e1f39e43a61a05299036307745d54fadbfa4971.tar.bz2
re PR tree-optimization/60115 (wrong code at -O3 on x86_64-linux-gnu)
2014-02-10 Richard Biener <rguenther@suse.de> PR tree-optimization/60115 * tree-eh.c (tree_could_trap_p): Unify TARGET_MEM_REF and MEM_REF handling. Properly verify that the accesses are not out of the objects bound. * gcc.dg/torture/pr60115.c: New testcase. From-SVN: r207656
Diffstat (limited to 'gcc/tree-eh.c')
-rw-r--r--gcc/tree-eh.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 857ee45..06941cd 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2610,12 +2610,6 @@ tree_could_trap_p (tree expr)
restart:
switch (code)
{
- case TARGET_MEM_REF:
- if (TREE_CODE (TMR_BASE (expr)) == ADDR_EXPR
- && !TMR_INDEX (expr) && !TMR_INDEX2 (expr))
- return false;
- return !TREE_THIS_NOTRAP (expr);
-
case COMPONENT_REF:
case REALPART_EXPR:
case IMAGPART_EXPR:
@@ -2642,10 +2636,36 @@ tree_could_trap_p (tree expr)
return false;
return !in_array_bounds_p (expr);
+ case TARGET_MEM_REF:
case MEM_REF:
- if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
+ if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR
+ && tree_could_trap_p (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)))
+ return true;
+ if (TREE_THIS_NOTRAP (expr))
return false;
- /* Fallthru. */
+ /* We cannot prove that the access is in-bounds when we have
+ variable-index TARGET_MEM_REFs. */
+ if (code == TARGET_MEM_REF
+ && (TMR_INDEX (expr) || TMR_INDEX2 (expr)))
+ return true;
+ if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
+ {
+ tree base = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
+ double_int off = mem_ref_offset (expr);
+ if (off.is_negative ())
+ return true;
+ if (TREE_CODE (base) == STRING_CST)
+ return double_int::from_uhwi (TREE_STRING_LENGTH (base)).ule (off);
+ else if (DECL_SIZE_UNIT (base) == NULL_TREE
+ || TREE_CODE (DECL_SIZE_UNIT (base)) != INTEGER_CST
+ || tree_to_double_int (DECL_SIZE_UNIT (base)).ule (off))
+ return true;
+ /* Now we are sure the first byte of the access is inside
+ the object. */
+ return false;
+ }
+ return true;
+
case INDIRECT_REF:
return !TREE_THIS_NOTRAP (expr);