From: Richard Biener Date: Mon, 21 Aug 2017 07:37:59 +0000 (+0000) Subject: re PR tree-optimization/81884 (Invalid code generation with zero size arrays or flexi... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8322b607d60d721542792af78b84e9069ea1a662;p=gcc.git re PR tree-optimization/81884 (Invalid code generation with zero size arrays or flexible array members) 2017-08-21 Richard Biener PR middle-end/81884 * tree-ssa-alias.c (stmt_kills_ref_p): Handle array accesses at struct end conservatively when comparing common bases. * g++.dg/torture/pr81884.C: New testcase. From-SVN: r251217 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f4f12e072c8..213b5c803ab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-08-21 Richard Biener + + PR middle-end/81884 + * tree-ssa-alias.c (stmt_kills_ref_p): Handle array accesses + at struct end conservatively when comparing common bases. + 2017-08-21 Richard Biener * tree-ssa-loop-im.c (struct lim_aux_data): Add ref index member. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 749847f1914..35d0be15c0e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-08-21 Richard Biener + + PR middle-end/81884 + * g++.dg/torture/pr81884.C: New testcase. + 2017-08-20 John David Anglin PR ipa/77732 diff --git a/gcc/testsuite/g++.dg/torture/pr81884.C b/gcc/testsuite/g++.dg/torture/pr81884.C new file mode 100644 index 00000000000..f545355ce35 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr81884.C @@ -0,0 +1,39 @@ +/* { dg-do run } */ + +typedef unsigned long uint64_t; + +struct value_t { + uint64_t _count; + value_t(uint64_t c) : _count(c) {} +}; + +struct X { + value_t eventTime; + uint64_t arr[0]; +}; + +X* x; + +__attribute__((noclone, noinline)) +void initialize() +{ + x->arr[0] = 11; + x->arr[1] = 12; + x->eventTime = value_t(10); + x->arr[2] = 13; + x->arr[3] = 14; +} + +int main() +{ + char buffer[sizeof(X) + sizeof(uint64_t)*4]; + x = (X*)buffer; + x->eventTime = value_t(999); + x->arr[0] = 1; + x->arr[1] = 2; + x->arr[2] = 3; + x->arr[3] = 4; + initialize(); + if (x->arr[0] != 11 || x->arr[1] != 12 || x->arr[2] != 13 || x->arr[3] != 14) + __builtin_abort (); +} diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 5794d227fe5..9bbc163b1c3 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -2416,6 +2416,7 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) if (ref->ref) { tree base = ref->ref; + tree innermost_dropped_array_ref = NULL_TREE; if (handled_component_p (base)) { tree saved_lhs0 = NULL_TREE; @@ -2435,6 +2436,11 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) TREE_OPERAND (base, 0) = saved_base0; if (res) break; + /* Remember if we drop an array-ref that we need to + double-check not being at struct end. */ + if (TREE_CODE (base) == ARRAY_REF + || TREE_CODE (base) == ARRAY_RANGE_REF) + innermost_dropped_array_ref = base; /* Otherwise drop handled components of the access. */ base = saved_base0; } @@ -2443,15 +2449,22 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) TREE_OPERAND (lhs, 0) = saved_lhs0; } /* Finally check if the lhs has the same address and size as the - base candidate of the access. */ - if (lhs == base - || (((TYPE_SIZE (TREE_TYPE (lhs)) - == TYPE_SIZE (TREE_TYPE (base))) - || (TYPE_SIZE (TREE_TYPE (lhs)) - && TYPE_SIZE (TREE_TYPE (base)) - && operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)), - TYPE_SIZE (TREE_TYPE (base)), 0))) - && operand_equal_p (lhs, base, OEP_ADDRESS_OF))) + base candidate of the access. Watch out if we have dropped + an array-ref that was at struct end, this means ref->ref may + be outside of the TYPE_SIZE of its base. */ + if ((! innermost_dropped_array_ref + || ! array_at_struct_end_p (innermost_dropped_array_ref)) + && (lhs == base + || (((TYPE_SIZE (TREE_TYPE (lhs)) + == TYPE_SIZE (TREE_TYPE (base))) + || (TYPE_SIZE (TREE_TYPE (lhs)) + && TYPE_SIZE (TREE_TYPE (base)) + && operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)), + TYPE_SIZE (TREE_TYPE (base)), + 0))) + && operand_equal_p (lhs, base, + OEP_ADDRESS_OF + | OEP_MATCH_SIDE_EFFECTS)))) return true; }