Skip to content

Commit f934c57

Browse files
committed
d: Fix PR 108842: Cannot use enum array with -fno-druntime
Restrict the generating of CONST_DECLs for D manifest constants to just scalars without pointers. It shouldn't happen that a reference to a manifest constant has not been expanded within a function body during codegen, but it has been found to occur in older versions of the D front-end (PR98277), so if the decl of a non-scalar constant is requested, just return its initializer as an expression. PR d/108842 gcc/d/ChangeLog: * decl.cc (DeclVisitor::visit (VarDeclaration *)): Only emit scalar manifest constants. (get_symbol_decl): Don't generate CONST_DECL for non-scalar manifest constants. * imports.cc (ImportVisitor::visit (VarDeclaration *)): New method. gcc/testsuite/ChangeLog: * gdc.dg/pr98277.d: Add more tests. * gdc.dg/pr108842.d: New test.
1 parent bb3b9c1 commit f934c57

File tree

4 files changed

+45
-15
lines changed

4 files changed

+45
-15
lines changed

gcc/d/decl.cc

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ class DeclVisitor : public Visitor
782782
{
783783
/* Do not store variables we cannot take the address of,
784784
but keep the values for purposes of debugging. */
785-
if (!d->type->isscalar ())
785+
if (d->type->isscalar () && !d->type->hasPointers ())
786786
{
787787
tree decl = get_symbol_decl (d);
788788
d_pushdecl (decl);
@@ -1212,6 +1212,20 @@ get_symbol_decl (Declaration *decl)
12121212
return decl->csym;
12131213
}
12141214

1215+
if (VarDeclaration *vd = decl->isVarDeclaration ())
1216+
{
1217+
/* CONST_DECL was initially intended for enumerals and may be used for
1218+
scalars in general, but not for aggregates. Here a non-constant
1219+
value is generated anyway so as its value can be used. */
1220+
if (!vd->canTakeAddressOf () && !vd->type->isscalar ())
1221+
{
1222+
gcc_assert (vd->_init && !vd->_init->isVoidInitializer ());
1223+
Expression *ie = initializerToExpression (vd->_init);
1224+
decl->csym = build_expr (ie, false);
1225+
return decl->csym;
1226+
}
1227+
}
1228+
12151229
/* Build the tree for the symbol. */
12161230
FuncDeclaration *fd = decl->isFuncDeclaration ();
12171231
if (fd)
@@ -1259,23 +1273,15 @@ get_symbol_decl (Declaration *decl)
12591273
if (vd->storage_class & STCextern)
12601274
DECL_EXTERNAL (decl->csym) = 1;
12611275

1262-
/* CONST_DECL was initially intended for enumerals and may be used for
1263-
scalars in general, but not for aggregates. Here a non-constant
1264-
value is generated anyway so as the CONST_DECL only serves as a
1265-
placeholder for the value, however the DECL itself should never be
1266-
referenced in any generated code, or passed to the back-end. */
1267-
if (vd->storage_class & STCmanifest)
1276+
if (!vd->canTakeAddressOf ())
12681277
{
12691278
/* Cannot make an expression out of a void initializer. */
1270-
if (vd->_init && !vd->_init->isVoidInitializer ())
1271-
{
1272-
Expression *ie = initializerToExpression (vd->_init);
1279+
gcc_assert (vd->_init && !vd->_init->isVoidInitializer ());
1280+
/* Non-scalar manifest constants have already been dealt with. */
1281+
gcc_assert (vd->type->isscalar ());
12731282

1274-
if (!vd->type->isscalar ())
1275-
DECL_INITIAL (decl->csym) = build_expr (ie, false);
1276-
else
1277-
DECL_INITIAL (decl->csym) = build_expr (ie, true);
1278-
}
1283+
Expression *ie = initializerToExpression (vd->_init);
1284+
DECL_INITIAL (decl->csym) = build_expr (ie, true);
12791285
}
12801286

12811287
/* [type-qualifiers/const-and-immutable]

gcc/d/imports.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,15 @@ class ImportVisitor : public Visitor
127127
this->result_ = this->make_import (TYPE_STUB_DECL (type));
128128
}
129129

130+
void visit (VarDeclaration *d) final override
131+
{
132+
/* Not all kinds of manifest constants create a CONST_DECL. */
133+
if (!d->canTakeAddressOf () && !d->type->isscalar ())
134+
return;
135+
136+
visit ((Declaration *) d);
137+
}
138+
130139
/* For now, ignore importing other kinds of dsymbols. */
131140
void visit (ScopeDsymbol *) final override
132141
{

gcc/testsuite/gdc.dg/pr108842.d

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// { dg-do compile }
2+
// { dg-options "-fno-rtti" }
3+
module object;
4+
enum int[] x = [0, 1, 2];

gcc/testsuite/gdc.dg/pr98277.d

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,14 @@ ref int getSide(Side side, return ref int left, return ref int right)
1111
{
1212
return side == Side.left ? left : right;
1313
}
14+
15+
enum SideA : int[]
16+
{
17+
left = [0],
18+
right = [1],
19+
}
20+
21+
int getSideA(SideA side, ref int left, ref int right)
22+
{
23+
return side == SideA.left ? left : right;
24+
}

0 commit comments

Comments
 (0)