aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2023-07-07 21:06:07 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2023-07-07 21:19:14 +0200
commitf934c5753849f7c48c6a3abfcd73b8f6008e8371 (patch)
tree0eec803efd5cca9f8a8646c933468802f75aeed3
parentbb3b9c1c3ba8228387ea8a94f3638190d1696324 (diff)
downloadgcc-f934c5753849f7c48c6a3abfcd73b8f6008e8371.zip
gcc-f934c5753849f7c48c6a3abfcd73b8f6008e8371.tar.gz
gcc-f934c5753849f7c48c6a3abfcd73b8f6008e8371.tar.bz2
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.
-rw-r--r--gcc/d/decl.cc36
-rw-r--r--gcc/d/imports.cc9
-rw-r--r--gcc/testsuite/gdc.dg/pr108842.d4
-rw-r--r--gcc/testsuite/gdc.dg/pr98277.d11
4 files changed, 45 insertions, 15 deletions
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 3f98085..0375ede 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -782,7 +782,7 @@ public:
{
/* Do not store variables we cannot take the address of,
but keep the values for purposes of debugging. */
- if (!d->type->isscalar ())
+ if (d->type->isscalar () && !d->type->hasPointers ())
{
tree decl = get_symbol_decl (d);
d_pushdecl (decl);
@@ -1212,6 +1212,20 @@ get_symbol_decl (Declaration *decl)
return decl->csym;
}
+ if (VarDeclaration *vd = decl->isVarDeclaration ())
+ {
+ /* CONST_DECL was initially intended for enumerals and may be used for
+ scalars in general, but not for aggregates. Here a non-constant
+ value is generated anyway so as its value can be used. */
+ if (!vd->canTakeAddressOf () && !vd->type->isscalar ())
+ {
+ gcc_assert (vd->_init && !vd->_init->isVoidInitializer ());
+ Expression *ie = initializerToExpression (vd->_init);
+ decl->csym = build_expr (ie, false);
+ return decl->csym;
+ }
+ }
+
/* Build the tree for the symbol. */
FuncDeclaration *fd = decl->isFuncDeclaration ();
if (fd)
@@ -1259,23 +1273,15 @@ get_symbol_decl (Declaration *decl)
if (vd->storage_class & STCextern)
DECL_EXTERNAL (decl->csym) = 1;
- /* CONST_DECL was initially intended for enumerals and may be used for
- scalars in general, but not for aggregates. Here a non-constant
- value is generated anyway so as the CONST_DECL only serves as a
- placeholder for the value, however the DECL itself should never be
- referenced in any generated code, or passed to the back-end. */
- if (vd->storage_class & STCmanifest)
+ if (!vd->canTakeAddressOf ())
{
/* Cannot make an expression out of a void initializer. */
- if (vd->_init && !vd->_init->isVoidInitializer ())
- {
- Expression *ie = initializerToExpression (vd->_init);
+ gcc_assert (vd->_init && !vd->_init->isVoidInitializer ());
+ /* Non-scalar manifest constants have already been dealt with. */
+ gcc_assert (vd->type->isscalar ());
- if (!vd->type->isscalar ())
- DECL_INITIAL (decl->csym) = build_expr (ie, false);
- else
- DECL_INITIAL (decl->csym) = build_expr (ie, true);
- }
+ Expression *ie = initializerToExpression (vd->_init);
+ DECL_INITIAL (decl->csym) = build_expr (ie, true);
}
/* [type-qualifiers/const-and-immutable]
diff --git a/gcc/d/imports.cc b/gcc/d/imports.cc
index 2efef4e..3172b79 100644
--- a/gcc/d/imports.cc
+++ b/gcc/d/imports.cc
@@ -127,6 +127,15 @@ public:
this->result_ = this->make_import (TYPE_STUB_DECL (type));
}
+ void visit (VarDeclaration *d) final override
+ {
+ /* Not all kinds of manifest constants create a CONST_DECL. */
+ if (!d->canTakeAddressOf () && !d->type->isscalar ())
+ return;
+
+ visit ((Declaration *) d);
+ }
+
/* For now, ignore importing other kinds of dsymbols. */
void visit (ScopeDsymbol *) final override
{
diff --git a/gcc/testsuite/gdc.dg/pr108842.d b/gcc/testsuite/gdc.dg/pr108842.d
new file mode 100644
index 0000000..5aae9e5
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr108842.d
@@ -0,0 +1,4 @@
+// { dg-do compile }
+// { dg-options "-fno-rtti" }
+module object;
+enum int[] x = [0, 1, 2];
diff --git a/gcc/testsuite/gdc.dg/pr98277.d b/gcc/testsuite/gdc.dg/pr98277.d
index 0dff142..c88c735 100644
--- a/gcc/testsuite/gdc.dg/pr98277.d
+++ b/gcc/testsuite/gdc.dg/pr98277.d
@@ -11,3 +11,14 @@ ref int getSide(Side side, return ref int left, return ref int right)
{
return side == Side.left ? left : right;
}
+
+enum SideA : int[]
+{
+ left = [0],
+ right = [1],
+}
+
+int getSideA(SideA side, ref int left, ref int right)
+{
+ return side == SideA.left ? left : right;
+}