Thread overview | ||||||
---|---|---|---|---|---|---|
|
March 06, 2019 [Issue 19721] Cannot take address of scope local variable even with dip1000 if a member variable is a delegate | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19721 Atila Neves <atila.neves@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |rejects-valid, safe -- |
February 09, 2020 [Issue 19721] Cannot take address of scope local variable even with dip1000 if a member variable is a delegate | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19721 ag0aep6g <ag0aep6g@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ag0aep6g@gmail.com --- Comment #1 from ag0aep6g <ag0aep6g@gmail.com> --- As far as I understand, it's correct that the code is rejected. `scope` only provides one level of protection. That means, you can't return a `scope` pointer, but you can dereference it, make a copy of the pointee, and return that. In the example, `func` is allowed to return `*clientData`, regardless of what happens anywhere else in the code. And since `s` is `scope`, `s.dg` might rely on references to the stack. So to avoid a leak, you can't be allowed to call `func` on `s`. In code: ---- Struct g; void main() @safe { main2(); () { int[10] stompy = 13; } (); g.dg(0); /* Prints "13". We've got memory corruption. */ } void main2() @safe { int stack; scope s = Struct(); s.dg = (int x) @safe { import std.stdio; writeln(stack); }; () @trusted { func(&s); } (); /* Let's pretend this works in @safe. */ } private struct Struct { void delegate(int) @safe dg; } void func(scope Struct* clientData) @safe nothrow { g = *clientData; } ---- (In reply to Atila Neves from comment #0) > It compiles if the `dg` member variable is removed or replaced with, say, an int. An int doesn't have any indirections, unlike a delegate. -- |
March 04, 2020 [Issue 19721] Cannot take address of scope local variable even with dip1000 if a member variable is a delegate | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19721 Walter Bright <bugzilla@digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bugzilla@digitalmars.com --- Comment #2 from Walter Bright <bugzilla@digitalmars.com> --- It also fails to compile if dg is defined as `int* dg;`: --------------- void main() @safe { scope s = Struct(); func(&s); } private struct Struct { int* dg; } void func(scope Struct* clientData) @safe nothrow { } ----------------------- In fact, it has nothing to do with structs, as this fails to compile the same way: ----- void main() @safe { scope int* s = null; func(&s); } void func(scope int** clientData) @safe nothrow { } ------ -- |
March 04, 2020 [Issue 19721] Cannot take address of scope local variable even with dip1000 if a member variable is a delegate | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19721 Walter Bright <bugzilla@digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Hardware|x86_64 |All Resolution|--- |INVALID OS|Linux |All --- Comment #3 from Walter Bright <bugzilla@digitalmars.com> --- Here's what's happening. `scope int* s;` declares `s` as a pointer that must not be allowed to escape `main()`. The `func(&s);` passes the address of `s` to `func`. `func` declares its parameter as `scope int**`. This ensures that the address of `s` does not escape, but says nothing about `s`'s pointer value, which must not be allowed to escape. I.e. the value of `s` is not protected from escaping `func`, so the call causes a compile error. If `s` is simply declared as an `int`, the `scope` annotation for `s` is meaningless, as there is no pointer value to protect, and it compiles successfully. ---- Generally, rewriting perplexing examples as simple pointers tends to make what is happening much easier to determine. A delegate is regarded as a pointer. A struct that contains pointer values is itself regarded as a pointer. Hence the simplification of the example. -- |
Copyright © 1999-2021 by the D Language Foundation