Bug 5708 – [CTFE] Incorrect string constant folding with -inline
Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-03-05T17:00:00Z
Last change time
2015-06-09T05:15:21Z
Keywords
rejects-valid
Assigned to
nobody
Creator
issues.dlang
Comments
Comment #0 by issues.dlang — 2011-03-05T17:00:59Z
From Tom on D.Learn (and I've confirmed it on Linux with both -m32 and -m64):
Minimal test case:
import std.stdio;
import std.conv;
int main(string[] args) {
int[string] t;
writeln(text(t));
return 0;
}
Tried:
dmd -O -release -inline -noboundscheck -c -Isrc src\main.d -> ERROR
dmd -release -inline -noboundscheck -c -Isrc src\main.d -> ERROR
dmd -O -inline -noboundscheck -c -Isrc src\main.d -> OK
dmd -O -release -noboundscheck -c -Isrc src\main.d -> OK
dmd -O -release -inline -c -Isrc src\main.d -> OK
Where ERROR is:
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): expression
expected, not 'EOF'
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ']'
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ')' following template argument list
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ']'
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ')' following template argument list
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ']'
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ')' following template argument list
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ']'
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ')' following template argument list
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ']'
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ')' following template argument list
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ']'
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ')' following template argument list
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ']'
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ')' following template argument list
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ']'
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ')' following template argument list
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ']'
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ')' following template argument list
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ']'
E:\d\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(364): found 'EOF'
when expecting ')' following template argument list
Comment #1 by bearophile_hugs — 2011-03-05T17:19:25Z
Problem confirmed on Windows, DMD 2.052, compiled with:
-inline -release -noboundscheck
A bit reduced code:
import std.conv: to;
void main() {
int[string] aa;
to!string(aa);
}
Comment #2 by bearophile_hugs — 2011-03-05T17:39:42Z
Well, given the error, it involves creating a tuple, which none of the code here is doing directly, so in theory, it should be possible to reduce it to code which creates a tuple, but I don't know how you'd do that in this case. I assume that v in the foreach loop is a tuple of the key and value, and that's probably where the problem is, but I don't use associative arrays all that often, and when I do, I rarely iterate over them, so I'm not sure. Regardless, if you're really trying to reuduce it, in theory, you should be able to reduce it down to the creation of a tuple with a particular set of types.
Comment #4 by bearophile_hugs — 2011-03-05T18:41:43Z
(In reply to comment #3)
> I assume that v in the foreach loop is a tuple of the key and value,
It's just a value, so it's an int.
Comment #5 by kennytm — 2011-03-06T00:43:01Z
It has nothing to do with the AA. Also, -inline alone is actually enough to trigger this bug. This seems to be a problem in string pooling in compile time.
import std.conv;
import std.typecons;
void ik(T,U)(T t, U u) {
Tuple!(T,U) x;
}
pragma(msg, ik!(string,string));
void main() {
() { to!string("lit"); } ();
}
Comment #6 by kennytm — 2011-03-06T00:53:53Z
Further removing the Tuple:
import std.conv;
void ik(T)(T) {
enum a = to!string("foo") ~ to!string("bar");
static assert(a == "foobar");
}
alias ik!int ik2;
void main() {
cast(void) () { to!string("lit"); };
}
As of 2.052 it asserts:
~/Downloads:911$ dmd -inline y.d
y.d(5): Error: static assert ("foofoo" == "foobar") is false
y.d(7): instantiated from here: ik!(int)
Comment #7 by kennytm — 2011-03-06T01:02:07Z
Further removing all Phobos dependency:
string b(string s) { return s; }
string a(string s) { return b(s); }
void ik(T)(T) {
enum p = a("foo");
enum q = a("bar");
static assert(q == "bar");
}
alias ik!int ik2;
void main() {
cast(void) () { a("lit"); };
}
Currently asserts:
y.d(7): Error: static assert ("foo" == "bar") is false
y.d(9): instantiated from here: ik!(int)
Comment #8 by bus_dbugzilla — 2011-04-08T03:33:16Z
It doesn't seem like this is fixed in dmd 2.053, but it should be according to the changelog.
Comment #11 by clugdbug — 2011-05-29T21:19:24Z
(In reply to comment #10)
> It doesn't seem like this is fixed in dmd 2.053, but it should be according to
> the changelog.
Can you describe what's failing? The test in comment 7 works for me.
Comment #12 by jcao219 — 2011-05-29T21:31:41Z
The test in comment 7 asserts for me.
I'm using dmd 2.053 on Windows.
Comment #13 by jcao219 — 2011-05-29T22:32:24Z
It doesn't work on Fedora 15 either.
I'm using dmd 2.053 directly from the zip file on the digitalmars site (for both Fedora 15 and Windows).
Don, is your dmd built from source? Maybe there's a difference between mine and yours.
Comment #14 by clugdbug — 2011-05-30T07:54:25Z
I think there was something wrong with that test case, it wasn't instantiating the template. Here's a reduced test case:
string b(string s) { return s; }
string a(string s) { return b(s); }
void bug5708() {
void m() { a("lit"); }
static assert(a("foo") == "foo");
static assert(a("bar") == "bar");
}