+2017-04-12 Richard Biener <rguenther@suse.de>
+ Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR middle-end/79671
+ * alias.c (component_uses_parent_alias_set_from): Handle
+ TYPE_TYPELESS_STORAGE.
+ (get_alias_set): Likewise.
+ * tree-core.h (tree_type_common): Add typeless_storage flag.
+ * tree.h (TYPE_TYPELESS_STORAGE): New macro.
+ * stor-layout.c (place_union_field): Set TYPE_TYPELESS_STORAGE
+ for types containing members with TYPE_TYPELESS_STORAGE.
+ (place_field): Likewise.
+ (layout_type): Likewise for ARRAY_TYPE.
+ * lto-streamer-out.c (hash_tree): Hash TYPE_TYPELESS_STORAGE.
+ * tree-streamer-in.c (unpack_ts_type_common_value_fields): Stream
+ TYPE_TYPELESS_STORAGE.
+ * tree-streamer-out.c (pack_ts_type_common_value_fields): Likewise.
+
2017-04-12 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/80349
{
const_tree found = NULL_TREE;
+ if (AGGREGATE_TYPE_P (TREE_TYPE (t))
+ && TYPE_TYPELESS_STORAGE (TREE_TYPE (t)))
+ return const_cast <tree> (t);
+
while (handled_component_p (t))
{
switch (TREE_CODE (t))
variant. */
t = TYPE_MAIN_VARIANT (t);
+ if (AGGREGATE_TYPE_P (t)
+ && TYPE_TYPELESS_STORAGE (t))
+ return 0;
+
/* Always use the canonical type as well. If this is a type that
requires structural comparisons to identify compatible types
use alias set zero. */
+2017-04-12 Richard Biener <rguenther@suse.de>
+ Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR middle-end/79671
+ * tree.c (build_cplus_array_type): Set TYPE_TYPELESS_STORAGE
+ for arrays of character or std::byte type.
+
2017-04-11 Jason Merrill <jason@redhat.com>
PR c++/80294 - ICE with constexpr and inheritance.
else
{
t = build_array_type (elt_type, index_type);
+ if (elt_type == unsigned_char_type_node
+ || elt_type == signed_char_type_node
+ || elt_type == char_type_node
+ || (TREE_CODE (elt_type) == ENUMERAL_TYPE
+ && TYPE_CONTEXT (elt_type) == std_node
+ && !strcmp ("byte", TYPE_NAME_STRING (elt_type))))
+ TYPE_TYPELESS_STORAGE (t) = 1;
}
/* Now check whether we already have this array variant. */
as it will overwrite alignment etc. of all variants. */
TYPE_SIZE (t) = TYPE_SIZE (m);
TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (m);
+ TYPE_TYPELESS_STORAGE (t) = TYPE_TYPELESS_STORAGE (m);
}
TYPE_MAIN_VARIANT (t) = m;
}
else if (code == ARRAY_TYPE)
hstate.add_flag (TYPE_NONALIASED_COMPONENT (t));
+ if (AGGREGATE_TYPE_P (t))
+ hstate.add_flag (TYPE_TYPELESS_STORAGE (t));
hstate.commit_flag ();
hstate.add_int (TYPE_PRECISION (t));
hstate.add_int (TYPE_ALIGN (t));
+2017-04-12 Richard Biener <rguenther@suse.de>
+ Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR middle-end/79671
+ * lto.c (compare_tree_sccs_1): Compare TYPE_TYPELESS_STORAGE.
+
2017-02-14 Martin Liska <mliska@suse.cz>
* lto.c (do_stream_out): Free LTO file filename string.
}
else if (code == ARRAY_TYPE)
compare_values (TYPE_NONALIASED_COMPONENT);
+ if (AGGREGATE_TYPE_P (t1))
+ compare_values (TYPE_TYPELESS_STORAGE);
compare_values (TYPE_PACKED);
compare_values (TYPE_RESTRICT);
compare_values (TYPE_USER_ALIGN);
if (TREE_CODE (TREE_TYPE (field)) == ERROR_MARK)
return;
+ if (AGGREGATE_TYPE_P (TREE_TYPE (field))
+ && TYPE_TYPELESS_STORAGE (TREE_TYPE (field)))
+ TYPE_TYPELESS_STORAGE (rli->t) = 1;
+
/* We assume the union's size will be a multiple of a byte so we don't
bother with BITPOS. */
if (TREE_CODE (rli->t) == UNION_TYPE)
return;
}
+ if (AGGREGATE_TYPE_P (type)
+ && TYPE_TYPELESS_STORAGE (type))
+ TYPE_TYPELESS_STORAGE (rli->t) = 1;
+
/* Work out the known alignment so far. Note that A & (-A) is the
value of the least-significant bit in A that is one. */
if (! integer_zerop (rli->bitpos))
SET_TYPE_MODE (type, BLKmode);
}
}
+ if (AGGREGATE_TYPE_P (element))
+ TYPE_TYPELESS_STORAGE (type) = TYPE_TYPELESS_STORAGE (element);
/* When the element size is constant, check that it is at least as
large as the element alignment. */
if (TYPE_SIZE_UNIT (element)
+2017-04-12 Richard Biener <rguenther@suse.de>
+ Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR middle-end/79671
+ * g++.dg/torture/pr79671.C: New testcase.
+ * g++.dg/lto/pr79671_0.C: Likewise.
+ * g++.dg/lto/pr79671_1.c: Likewise.
+
2017-04-12 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/80349
--- /dev/null
+// { dg-lto-do run }
+
+void *operator new(__SIZE_TYPE__, void *p2) { return p2; }
+struct B { B(int i_) : i(i_) {} int i; };
+struct X
+{
+ unsigned char buf[sizeof (B)];
+};
+
+int __attribute__((noinline)) foo()
+{
+ X x alignas (B), y alignas (B);
+ new (&x) B (0);
+ y = x;
+ B *q = reinterpret_cast <B *>(&y);
+ asm volatile ("" : "=r" (q) : "r" (q));
+ return q->i;
+}
+extern "C" void bar ();
+int main()
+{
+ if (foo() != 0)
+ __builtin_abort ();
+ bar ();
+ return 0;
+}
--- /dev/null
+struct X
+{
+ unsigned char buf[sizeof (int)];
+};
+void bar () { struct X x; *(volatile char *)x.buf = 1; }
--- /dev/null
+// { dg-do run }
+
+void *operator new(__SIZE_TYPE__, void *p2) { return p2; }
+struct B { B(int i_) : i(i_) {} int i; };
+struct X
+{
+ unsigned char buf[sizeof (B)];
+};
+
+int __attribute__((noinline)) foo()
+{
+ X x alignas(B), y alignas(B);
+ new (&x) B (0);
+ y = x;
+ B *q = reinterpret_cast <B *>(&y);
+ asm volatile ("" : "=r" (q) : "r" (q));
+ return q->i;
+}
+
+int main()
+{
+ if (foo() != 0)
+ __builtin_abort ();
+ return 0;
+}
so we need to store the value 32 (not 31, as we need the zero
as well), hence six bits. */
unsigned align : 6;
- unsigned spare : 25;
+ unsigned typeless_storage : 1;
+ unsigned spare : 24;
+
alias_set_type alias_set;
tree pointer_to;
tree reference_to;
}
else if (TREE_CODE (expr) == ARRAY_TYPE)
TYPE_NONALIASED_COMPONENT (expr) = (unsigned) bp_unpack_value (bp, 1);
+ if (AGGREGATE_TYPE_P (expr))
+ TYPE_TYPELESS_STORAGE (expr) = (unsigned) bp_unpack_value (bp, 1);
TYPE_PRECISION (expr) = bp_unpack_var_len_unsigned (bp);
SET_TYPE_ALIGN (expr, bp_unpack_var_len_unsigned (bp));
#ifdef ACCEL_COMPILER
}
else if (TREE_CODE (expr) == ARRAY_TYPE)
bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
+ if (AGGREGATE_TYPE_P (expr))
+ bp_pack_value (bp, TYPE_TYPELESS_STORAGE (expr), 1);
bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr));
bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
}
#define TYPE_NONALIASED_COMPONENT(NODE) \
(ARRAY_TYPE_CHECK (NODE)->type_common.transparent_aggr_flag)
+/* For an ARRAY_TYPE, a RECORD_TYPE, a UNION_TYPE or a QUAL_UNION_TYPE
+ whether the array is typeless storage or the type contains a member
+ with this flag set. Such types are excempt from type-based alias
+ analysis. */
+#define TYPE_TYPELESS_STORAGE(NODE) \
+ (TREE_CHECK4 (NODE, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE, ARRAY_TYPE)->type_common.typeless_storage)
+
/* Indicated that objects of this type should be laid out in as
compact a way as possible. */
#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->base.u.bits.packed_flag)