Comment #0 by default_357-line — 2022-03-07T13:09:10Z
import std.uni;
void main()
{
static foreach (ch; unicode.Control.byCodepoint) { }
}
This segfaults on DMD 2.099-rc.1.
From looking at the longer DMD debug mode backtrace on master, there seems to be a stack variable destructor call that reads dead stack memory?
Comment #1 by dkorpel — 2022-03-07T15:20:25Z
digger bisect:
```
digger: 8be5c8b0111b68ca23e23c36a6fd1cc746a9c0cc is the first bad commit
commit 8be5c8b0111b68ca23e23c36a6fd1cc746a9c0cc
Author: Iain Buclaw <[email protected]>
Date: Wed Jun 9 12:34:57 2021 +0200
dmd: static foreach: Delay running ctfeInterpret until the lowering stage
```
Comment #2 by default_357-line — 2022-03-07T16:37:32Z
(In reply to FeepingCreature from comment #0)
> From looking at the longer DMD debug mode backtrace on master, there seems
> to be a stack variable destructor call that reads dead stack memory?
As far as I can tell, possibly an artificial/temporary variable that has not been declared properly.
Comment #4 by ibuclaw — 2022-12-20T17:20:46Z
Tweaking the code to use a regular foreach:
---
void main() {
foreach (ch; SomeContainer().range) { }
}
pragma(msg, main());
---
This is where the temporary gets *pushed* onto the CTFE stack.
---
// If the comma returns a temporary variable, it needs to be an lvalue
// (this is particularly important for struct constructors)
if (e.e1.op == EXP.declaration &&
e.e2.op == EXP.variable &&
e.e1.isDeclarationExp().declaration == e.e2.isVarExp().var &&
e.e2.isVarExp().var.storage_class & STC.ctfe)
{
VarExp ve = e.e2.isVarExp();
VarDeclaration v = ve.var.isVarDeclaration();
ctfeGlobals.stack.push(v); // <--- here
---
However for `static foreach`, this is never done because of the equality condition (declaration == var) is not true.
This despite both declarationexp and varexp having the same identifier name (__slSomeCo3).
Obviously, *something* has been copied that really shouldn't have been.