diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-02-10 13:51:23 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-02-10 13:51:23 +0000 |
commit | cdf2f9e49ad7cf81ce186b005f5c40b4254f232b (patch) | |
tree | ef09c2d939f1341f5a928daca4ec870b32320b8f /gcc/tree-eh.c | |
parent | 96c7d4b1727c5f9ddcbb02fb69f727a0f2f3572e (diff) | |
download | gcc-cdf2f9e49ad7cf81ce186b005f5c40b4254f232b.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207656 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-eh.c')
-rw-r--r-- | gcc/tree-eh.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 857ee4581bc..06941cd1745 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); |