--- /dev/null
+/* { 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 ();
+}
if (ref->ref)
{
tree base = ref->ref;
+ tree innermost_dropped_array_ref = NULL_TREE;
if (handled_component_p (base))
{
tree saved_lhs0 = NULL_TREE;
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;
}
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;
}