]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
sra: Bail out when encountering accesses with negative offsets (PR 96730)
authorMartin Jambor <mjambor@suse.cz>
Tue, 25 Aug 2020 14:11:56 +0000 (16:11 +0200)
committerMartin Jambor <mjambor@suse.cz>
Tue, 25 Aug 2020 14:11:56 +0000 (16:11 +0200)
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.

(cherry picked from commit 556600286dd312d3ddf3d673a8579576862663e3)

gcc/testsuite/gcc.dg/tree-ssa/pr96730.c [new file with mode: 0644]
gcc/tree-sra.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96730.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96730.c
new file mode 100644 (file)
index 0000000..39a0684
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+struct a {
+  int b;
+  int c;
+} d() {
+  struct a e[9];
+  int f = 3362953455;
+  e[f] = e[6];
+  e[6].c = 1;
+}
+int main() {}
index 227bde0625792e6cf6c5df924f1e09649ef2bacb..cd9bc6c9104cf72809f19c0843311253358cf4c7 100644 (file)
@@ -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)))
     {