aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-sra.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2020-08-25 13:33:44 +0200
committerMartin Jambor <mjambor@suse.cz>2020-08-25 13:33:44 +0200
commit556600286dd312d3ddf3d673a8579576862663e3 (patch)
tree0b1a8471ebf003437d8291a4266af96ad3f357b3 /gcc/tree-sra.c
parent26ea069ec02f15593ff35cf1d5b6056c1c17e4f4 (diff)
downloadgcc-556600286dd312d3ddf3d673a8579576862663e3.zip
gcc-556600286dd312d3ddf3d673a8579576862663e3.tar.gz
gcc-556600286dd312d3ddf3d673a8579576862663e3.tar.bz2
sra: Bail out when encountering accesses with negative offsets (PR 96730)
I must admit I was quite surprised to see that SRA does not disqualify an aggregate from any transformations when it encounters an offset for which get_ref_base_and_extent returns a negative offset. It may not matter too much because I sure hope such programs always have undefined behavior (SRA candidates are local variables on stack) but it is probably better not to perform weird transformations on them as build ref model with the new build_reconstructed_reference function currently happily do for negative offsets (they just copy the existing expression which is then used as the expression of a "propagated" access) and of course the compiler must not ICE (as it currently does because the SRA forest verifier does not like the expression). gcc/ChangeLog: 2020-08-24 Martin Jambor <mjambor@suse.cz> PR tree-optimization/96730 * tree-sra.c (create_access): Disqualify any aggregate with negative offset access. (build_ref_for_model): Add assert that offset is non-negative. gcc/testsuite/ChangeLog: 2020-08-24 Martin Jambor <mjambor@suse.cz> PR tree-optimization/96730 * gcc.dg/tree-ssa/pr96730.c: New test.
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r--gcc/tree-sra.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index fcba7fb..754f413 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -931,6 +931,11 @@ create_access (tree expr, gimple *stmt, bool write)
}
if (size == 0)
return NULL;
+ if (offset < 0)
+ {
+ disqualify_candidate (base, "Encountered a negative offset access.");
+ return NULL;
+ }
if (size < 0)
{
disqualify_candidate (base, "Encountered an unconstrained access.");
@@ -1667,6 +1672,7 @@ build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
struct access *model, gimple_stmt_iterator *gsi,
bool insert_after)
{
+ gcc_assert (offset >= 0);
if (TREE_CODE (model->expr) == COMPONENT_REF
&& DECL_BIT_FIELD (TREE_OPERAND (model->expr, 1)))
{