Bug 17174 – can take address of member of struct parameter in @safe code

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-02-10T17:48:09Z
Last change time
2018-03-04T04:14:31Z
Keywords
accepts-invalid, safe
Assigned to
No Owner
Creator
Alex

Comments

Comment #0 by sascha.orlov — 2017-02-10T17:48:09Z
As discussed here: https://forum.dlang.org/post/[email protected] tested with 2.073.0 on a mac. // Code starts here void main() { initStruct iSb; iSb.var = 3; A b = A(iSb); assert(*b.myVar == 3); // this works iSb.var = 4; assert(*b.myVar == 4); // as expected b = A(initStruct(5)); // how does assert(*b.myVar == 5); // this work? } struct A { @disable this(); size_t* myVar; this()(auto ref initStruct iS) @nogc { import core.stdc.stdio; __traits(isRef, iS) ? printf("ref case\n") : printf("value case"); myVar = &iS.var; /* // This treatment is not needed? if(__traits(isRef, iS)) { myVar = &iS.var; } else { myVar = new size_t(iS.var); } */ } } struct initStruct { size_t var; } // Code ends here In case of initializing an A-instance with an rvalue, it should be a compile-time error to get a pointer to the parameter.
Comment #1 by ag0aep6g — 2017-02-10T19:46:55Z
Taking the address of a value parameter is allowed in @system code. Your constructor is not marked as @safe, so it's @system and you're allowed to do that. However, if you add @safe, the code still compiles. That's a bug. It doesn't seem to be related to `auto ref`, though. Rather, the compiler gets confused by the struct. I'm changing the summary of this issue to be about this. ---- /* Shouldn't compile: */ void f(initStruct iS) @safe { auto p = &iS.var; /* Should trigger the same error as below. */ } struct initStruct { size_t var; } /* Doesn't compile, as it should be: */ void g(size_t var) @safe { auto p = &var; /* "Error: cannot take address of parameter" */ } ----
Comment #2 by sascha.orlov — 2017-02-11T00:39:28Z
@ag0aep6g Ok... my complaint was about your first two lines. Didn't take this into account. But even then, it seems strange to me to be able to take a pointer to a value parameter, in any case... With other words: The treatment I was wondering about (allocating memory) is needed, and I should have known this, because the constructor is not marked as @safe.
Comment #3 by bugzilla — 2018-03-04T04:14:31Z
With -dip1000, both functions pass, because taking the address is allowed, you just cannot escape the address.