diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 3f980851259a5399004e1eec1070796578fc4a3d..0375ede082bb0b1ea70a64b0929e1697c8c2cc45 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 2efef4ed54f437163f673412ddfc55fb13c3b4d2..3172b799cb04b6938f5c54cf9eb7656b1ef86f30 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 0000000000000000000000000000000000000000..5aae9e5000daf39a76ec1286aa3e324341f2210c --- /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 0dff142a6ef41abdfe760c0c7a8d51a8808109ce..c88c735dec891fc7860984c12a7e741cc0e0b26d 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; +}