Skip to content

Commit 416fe77

Browse files
committed
d: Fix ICE in must_pass_in_stack_var_size_or_pad with D enums [PR123411]
An `enum : enum A` type caused the already computed underlying type size of `enum A` to be overwritten with NULL_TREE. To fix, don't finish the enum with layout_type unless we're handling the main variant type. PR d/123411 gcc/d/ChangeLog: * types.cc (TypeVisitor::visit (TypeEnum *)): Only call layout_type on the TYPE_MAIN_VARIANT of the enum. gcc/testsuite/ChangeLog: * gdc.dg/pr123411.d: New test.
1 parent 8e6b7c9 commit 416fe77

2 files changed

Lines changed: 40 additions & 23 deletions

File tree

gcc/d/types.cc

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,33 +1181,35 @@ class TypeVisitor : public Visitor
11811181
/* Finish the enumeration type. */
11821182
if (TREE_CODE (t->ctype) == ENUMERAL_TYPE)
11831183
{
1184-
TYPE_MIN_VALUE (t->ctype) = TYPE_MIN_VALUE (basetype);
1185-
TYPE_MAX_VALUE (t->ctype) = TYPE_MAX_VALUE (basetype);
1186-
TYPE_UNSIGNED (t->ctype) = TYPE_UNSIGNED (basetype);
1187-
SET_TYPE_ALIGN (t->ctype, TYPE_ALIGN (basetype));
1188-
TYPE_SIZE (t->ctype) = NULL_TREE;
1189-
TYPE_PRECISION (t->ctype) = dmd::size (t, t->sym->loc) * 8;
1184+
tree type = TYPE_MAIN_VARIANT (t->ctype);
11901185

1191-
layout_type (t->ctype);
1186+
if (type == t->ctype)
1187+
{
1188+
TYPE_MIN_VALUE (type) = TYPE_MIN_VALUE (basetype);
1189+
TYPE_MAX_VALUE (type) = TYPE_MAX_VALUE (basetype);
1190+
TYPE_UNSIGNED (type) = TYPE_UNSIGNED (basetype);
1191+
SET_TYPE_ALIGN (type, TYPE_ALIGN (basetype));
1192+
TYPE_SIZE (type) = NULL_TREE;
1193+
TYPE_PRECISION (type) = dmd::size (t, t->sym->loc) * 8;
1194+
1195+
layout_type (type);
1196+
}
11921197

11931198
/* Fix up all forward-referenced variants of this enum type. */
1194-
for (tree v = TYPE_MAIN_VARIANT (t->ctype); v;
1195-
v = TYPE_NEXT_VARIANT (v))
1199+
for (tree variant = TYPE_NEXT_VARIANT (type); variant;
1200+
variant = TYPE_NEXT_VARIANT (variant))
11961201
{
1197-
if (v == t->ctype)
1198-
continue;
1199-
1200-
TYPE_VALUES (v) = TYPE_VALUES (t->ctype);
1201-
TYPE_LANG_SPECIFIC (v) = TYPE_LANG_SPECIFIC (t->ctype);
1202-
TYPE_MIN_VALUE (v) = TYPE_MIN_VALUE (t->ctype);
1203-
TYPE_MAX_VALUE (v) = TYPE_MAX_VALUE (t->ctype);
1204-
TYPE_UNSIGNED (v) = TYPE_UNSIGNED (t->ctype);
1205-
TYPE_SIZE (v) = TYPE_SIZE (t->ctype);
1206-
TYPE_SIZE_UNIT (v) = TYPE_SIZE_UNIT (t->ctype);
1207-
SET_TYPE_MODE (v, TYPE_MODE (t->ctype));
1208-
TYPE_PRECISION (v) = TYPE_PRECISION (t->ctype);
1209-
SET_TYPE_ALIGN (v, TYPE_ALIGN (t->ctype));
1210-
TYPE_USER_ALIGN (v) = TYPE_USER_ALIGN (t->ctype);
1202+
TYPE_VALUES (variant) = TYPE_VALUES (type);
1203+
TYPE_LANG_SPECIFIC (variant) = TYPE_LANG_SPECIFIC (type);
1204+
TYPE_MIN_VALUE (variant) = TYPE_MIN_VALUE (type);
1205+
TYPE_MAX_VALUE (variant) = TYPE_MAX_VALUE (type);
1206+
TYPE_UNSIGNED (variant) = TYPE_UNSIGNED (type);
1207+
TYPE_SIZE (variant) = TYPE_SIZE (type);
1208+
TYPE_SIZE_UNIT (variant) = TYPE_SIZE_UNIT (type);
1209+
SET_TYPE_MODE (variant, TYPE_MODE (type));
1210+
TYPE_PRECISION (variant) = TYPE_PRECISION (type);
1211+
SET_TYPE_ALIGN (variant, TYPE_ALIGN (type));
1212+
TYPE_USER_ALIGN (variant) = TYPE_USER_ALIGN (type);
12111213
}
12121214

12131215
/* Complete forward-referenced fields of this enum type. */

gcc/testsuite/gdc.dg/pr123411.d

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// { dg-do compile }
2+
module object;
3+
enum E
4+
{
5+
unknown
6+
}
7+
enum : E
8+
{
9+
E_UNKNOWN
10+
}
11+
12+
E test()
13+
{
14+
return E.unknown;
15+
}

0 commit comments

Comments
 (0)