Bug 22522 – [dip1000] Creating interior pointers allowed in @safe

Status
REOPENED
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-11-18T12:34:20Z
Last change time
2024-12-13T19:19:20Z
Assigned to
No Owner
Creator
Dennis
Moved to GitHub: dmd#18066 →

Comments

Comment #0 by dkorpel — 2021-11-18T12:34:20Z
The garbage collection specification (https://dlang.org/spec/garbage.html) mentions it's undefined behavior to have interior pointers in a struct: > Do not have pointers in a struct instance that point back to the same instance. > The trouble with this is if the instance gets moved in memory, the pointer will > point back to where it came from, with likely disastrous results. Undefined behavior is not allowed in `@safe` code, but creating an interior pointer is, which can break dip1000: ``` // compile with -preview=dip1000 @safe: struct S { int storage; int* ptr; this(int dummy) { ptr = &storage; } int* get() return scope { return ptr; } } int* escape() { S s = S(0); return s.get; // escapes a pointer to stack variable `s` } ```
Comment #1 by fw — 2022-02-13T11:03:49Z
I get an error for this with dmd as of commit 05a27e287e546e8553741fffccea0059f0c11f63: t.d(8): Error: address of variable `this` assigned to `this` with longer lifetime
Comment #2 by dkorpel — 2022-02-13T11:22:19Z
(In reply to Florian Weimer from comment #1) > I get an error for this with dmd as of commit > 05a27e287e546e8553741fffccea0059f0c11f63: > > t.d(8): Error: address of variable `this` assigned to `this` with longer > lifetime I think this was fixed by https://github.com/dlang/dmd/pull/13577 then
Comment #3 by dkorpel — 2022-03-03T11:22:01Z
Re-opening, because: - the error message makes no sense - this is not yet tested for in the test suite - hence, the accidental 'fix' will quietly be reverted when issue 22801 gets fixed
Comment #4 by bugzilla — 2022-08-15T15:48:08Z
The error message isn't great, but it is correctly identifying the problem. ptr = &storage; *is* taking the address of `this`, and assigning it to `this`. As in`storage` is *(this+0), and `ptr` is *(this+8)
Comment #5 by dkorpel — 2022-08-15T17:18:51Z
(In reply to Walter Bright from comment #4) > The error message isn't great, but it is correctly identifying the problem. It's saying `this` has longer lifetime than `this`. Since when does `x > x` evaluate to true? It also still works when you add `return scope` to the constructor: ``` @safe: struct S { int storage; int* ptr; this(int dummy) return scope { ptr = &storage; } int* get() return scope { return ptr; } } int* escape() { S s = S(0); return s.get; // escapes a pointer to stack variable `s` } ```
Comment #6 by dkorpel — 2022-08-15T17:22:53Z
(In reply to Dennis from comment #5) > It's saying `this` has longer lifetime than `this`. Since when does `x > x` > evaluate to true? Nevermind, it says `this` has longer lifetime than "address of variable `this`", but, it should be in test suite and the modification with `return scope` needs to error.
Comment #7 by robert.schadek — 2024-12-13T19:19:20Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18066 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB