On 1/29/16 11:53 PM, Matt Elkins wrote:
Title says it; I get an access violation in code marked @safe. Here's a
minimal example:

[code]
@safe:

struct Foo(alias Callback)
{
     ~this() {Callback();}
}

unittest
{
     uint stackVar;
     alias FooType = Foo!((){++stackVar;});

     FooType[1] foos;
     foos[0] = FooType.init;
}
[/code]

This results in:
object.Error@(0): Access Violation
----------------
0x00405E2A in pure nothrow @nogc @safe void
test.__unittestL9_4().__lambda1() at <path>\test.d(12)
.... more stack ...

Line 12 is the alias FooType line, where the delegate is defined.

Where is this coming from? Intuition says it is something to do with
calling the delegate after the stack frame has popped and stackVar is
unreachable, but I'm not seeing it. Wouldn't foos be destructed before
the stack frame is gone?

I don't get the issue if I mark stackVar static, or if I don't perform
the assignment to foos[0].

This looks like a bug in the compiler. It appears that Foo.init as an rvalue destroying itself results in a call into an invalid stack.

It doesn't require a lambda, or a fixed-size array. And it doesn't require the stack frame holding stackVar to be invalid. This also shows the behavior:

unittest
{
uint stackVar;
void blah() { ++stackVar; }

{
   // introduce inner scope
   FooType foo = FooType.init;
}

}

https://issues.dlang.org/enter_bug.cgi

-Steve

Reply via email to