Bug 7965 – Invalid outer function scope pointer in some cases
Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-04-21T23:43:00Z
Last change time
2012-11-08T07:57:40Z
Keywords
pull, wrong-code
Assigned to
nobody
Creator
verylonglogin.reg
Comments
Comment #0 by verylonglogin.reg — 2012-04-21T23:43:01Z
---
import std.stdio;
void main() {
int i;
writeln("Real &i: ", &i); // Prints 12FE44
void nested() {
writeln("Fake &i: ", &i); // Prints FFFFFFF0
i = 0; // Access Violation
}
struct LocalS {
// `S s;` or `S s = void;` fields also causes this bug
// for `struct S { int unused = 0; }`
int unused = 0;
void f() { nested(); }
}
LocalS ls;
ls.f();
}
---
Because of this bug things like `map!nestedPred("a b".splitter(" "))` give us `Access Violation` so it's major.
Comment #1 by nilsbossung — 2012-06-17T16:50:24Z
Seems to me that the default initializer for nested structs misses the context pointer.
---
void main() {
int x;
struct S {
char y;
void boom() {x = 42;} // makes the struct nested
}
S s;
s.boom();
}
---
There's no crash with an int y, probably because then the struct is considered to be "all zeros", and is given special treatment. It crashes anyway when y is explicitly initialized to 0, because the "all zeros" recognizer isn't that smart <https://github.com/D-Programming-Language/dmd/blob/aa7939aefcf61d6a44f2d4df15157427f7725fc0/src/struct.c#L532>.
There's no crash if s is initialized to S() or {}.
S.init.boom() crashes, too, of course.
Comment #4 by verylonglogin.reg — 2012-07-02T01:15:37Z
I think this bug may be fixed when `std.algorithm` will work.
Example mentioned in this issue description (now fails):
---
import std.array;
import std.algorithm;
void main() {
string s = "x";
auto arr = map!(a => (s ~= "y", s ~ a ~ a))("a b".splitter(" ")).array();
assert(arr == ["xyaa", "xyybb"]);
}
---
A bit reduced case:
---
import std.algorithm;
void main() {
string s = "x";
auto f = map!(a => s)("a b".splitter(" ")).front;
}
---
Comment #5 by verylonglogin.reg — 2012-07-02T01:43:33Z
Reduced test-case:
---
struct S
{
string str;
uint unused1, unused2 = 0;
}
auto f(alias fun)()
{
struct Result
{
S s;
this(S _s) { s = _s; }
void g() { assert(fun(s.str) == "xa"); }
}
return Result(S("a"));
}
void main() {
string s = "x";
f!(a => s ~= a)().g();
assert(s == "xa");
}
---
Comment #6 by k.hara.pg — 2012-07-02T08:37:57Z
(In reply to comment #5)
> Reduced test-case:
> ---
> struct S
> {
> string str;
> uint unused1, unused2 = 0;
> }
>
> auto f(alias fun)()
> {
> struct Result
> {
> S s;
>
> this(S _s) { s = _s; }
>
> void g() { assert(fun(s.str) == "xa"); }
> }
>
> return Result(S("a"));
> }
>
> void main() {
> string s = "x";
> f!(a => s ~= a)().g();
> assert(s == "xa");
> }
> ---
Thanks for your work and good test case!
https://github.com/D-Programming-Language/dmd/pull/1034
Comment #7 by github-bugzilla — 2012-07-08T12:36:55Z