d: Fix ICE in gimplify_expr, at gimplify.c (PR98277)
The DMD front-end shouldn't, but can sometimes leak manifest constants in the AST passed to the code generator. To prevent this being an issue, the setting of DECL_INITIAL has been moved to the point where the CONST_DECL is used, rather than in the declaration handler. gcc/d/ChangeLog: PR d/98277 * decl.cc (DeclVisitor::visit (VarDeclaration *)): Move setting of DECL_INITIAL for manifest constants to ... (get_symbol_decl): ... here. gcc/testsuite/ChangeLog: PR d/98277 * gdc.dg/pr98277.d: New test.
This commit is contained in:
parent
34c7d3d3b2
commit
36c9a3fe3f
2 changed files with 35 additions and 21 deletions
|
@ -653,31 +653,13 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
/* Do not store variables we cannot take the address of,
|
||||
but keep the values for purposes of debugging. */
|
||||
if (!d->canTakeAddressOf ())
|
||||
{
|
||||
/* Don't know if there is a good way to handle instantiations. */
|
||||
if (d->isInstantiated ())
|
||||
return;
|
||||
|
||||
/* Cannot make an expression out of a void initializer. */
|
||||
if (!d->_init || d->_init->isVoidInitializer ())
|
||||
return;
|
||||
|
||||
tree decl = get_symbol_decl (d);
|
||||
Expression *ie = initializerToExpression (d->_init);
|
||||
|
||||
/* 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. */
|
||||
/* Do not store variables we cannot take the address of,
|
||||
but keep the values for purposes of debugging. */
|
||||
if (!d->type->isscalar ())
|
||||
DECL_INITIAL (decl) = build_expr (ie, false);
|
||||
else
|
||||
{
|
||||
DECL_INITIAL (decl) = build_expr (ie, true);
|
||||
tree decl = get_symbol_decl (d);
|
||||
d_pushdecl (decl);
|
||||
rest_of_decl_compilation (decl, 1, 0);
|
||||
}
|
||||
|
@ -1106,6 +1088,25 @@ 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)
|
||||
{
|
||||
/* Cannot make an expression out of a void initializer. */
|
||||
if (vd->_init && !vd->_init->isVoidInitializer ())
|
||||
{
|
||||
Expression *ie = initializerToExpression (vd->_init);
|
||||
|
||||
if (!vd->type->isscalar ())
|
||||
DECL_INITIAL (decl->csym) = build_expr (ie, false);
|
||||
else
|
||||
DECL_INITIAL (decl->csym) = build_expr (ie, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the declaration mangled identifier if static. */
|
||||
|
|
13
gcc/testsuite/gdc.dg/pr98277.d
Normal file
13
gcc/testsuite/gdc.dg/pr98277.d
Normal file
|
@ -0,0 +1,13 @@
|
|||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98277
|
||||
// { dg-do compile }
|
||||
|
||||
enum Side
|
||||
{
|
||||
left,
|
||||
right
|
||||
}
|
||||
|
||||
ref int getSide(Side side, ref int left, ref int right)
|
||||
{
|
||||
return side == Side.left ? left : right;
|
||||
}
|
Loading…
Add table
Reference in a new issue