https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97323
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |ice-checking
Assignee|rth at gcc dot gnu.org |rguenth at gcc dot
gnu.org
--- Comment #18 from Richard Biener <rguenth at gcc dot gnu.org> ---
The odd thing is we have
<array_type 0x7ffff6665888
type <integer_type 0x7ffff66655e8 a SI
size <integer_cst 0x7ffff68120a8 constant 32>
unit-size <integer_cst 0x7ffff68120c0 constant 4>
user align:16 warn_if_not_align:0 symtab:-161040432 alias-set -1
canonical-type 0x7ffff68165e8 precision:32 min <integer_cst 0x7ffff68122e8
-2147483648> max <integer_cst 0x7ffff6812300 2147483647>>
no-force-blk BLK size <integer_cst 0x7ffff68120a8 32> unit-size
<integer_cst 0x7ffff68120c0 4>
user align:16 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ffff6665930
domain <integer_type 0x7ffff66657e0
so the array type has alignment 2 and BLKmode but the component type has
SImode and alignment 2. This is done by
SET_TYPE_MODE (type, mode_for_array (TREE_TYPE (type),
TYPE_SIZE (type))); <- sets SImode
if (TYPE_MODE (type) != BLKmode
&& STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
&& TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
{
TYPE_NO_FORCE_BLK (type) = 1;
SET_TYPE_MODE (type, BLKmode);
now, you could argue having both types have the same TYPE_CANONICAL isn't
needed. You don't need it for alias compatibility since that's keyed off the
element type of arrays only. Likewise for value assignments between
array types.
That said, a possibility would be to simply declare having this type
combination with a mode mismatch OK, at least for aggregate types
where modes historically behave a bit "odd".
So something like the following (we now exempt record-or-union types for
mode processing already)
diff --git a/gcc/tree.cc b/gcc/tree.cc
index eab40008e8b..d30ccf7cb7f 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -13924,6 +13924,7 @@ gimple_canonical_types_compatible_p (const_tree t1,
const_tree t2,
flexible array members, we allow mismatching modes for structures or
unions. */
if (!RECORD_OR_UNION_TYPE_P (t1)
+ && TREE_CODE (t1) != ARRAY_TYPE
&& TYPE_MODE (t1) != TYPE_MODE (t2))
return false;
@@ -14255,6 +14256,7 @@ verify_type (const_tree t)
flexible array members. */
&& !RECORD_OR_UNION_TYPE_P (t)
&& !RECORD_OR_UNION_TYPE_P (TYPE_CANONICAL (t))
+ && TREE_CODE (t) != ARRAY_TYPE
&& TYPE_MODE (t) != TYPE_MODE (TYPE_CANONICAL (t)))
{
error ("%<TYPE_MODE%> of %<TYPE_CANONICAL%> is not compatible");