Jump to page: 1 2
Thread overview
[Issue 22680] @safe hole with destructors
Jan 17, 2022
RazvanN
Jan 17, 2022
ag0aep6g
Jan 17, 2022
RazvanN
Jan 17, 2022
Stanislav Blinov
Mar 29, 2022
Dennis
Mar 29, 2022
Stanislav Blinov
Mar 29, 2022
Dennis
Mar 29, 2022
Dennis
Mar 29, 2022
Stanislav Blinov
Aug 31, 2022
Walter Bright
Aug 31, 2022
Walter Bright
Aug 31, 2022
Dlang Bot
Sep 05, 2022
Dlang Bot
January 17, 2022
https://issues.dlang.org/show_bug.cgi?id=22680

RazvanN <razvan.nitu1305@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |bootcamp
                 CC|                            |razvan.nitu1305@gmail.com
           Severity|minor                       |enhancement

--- Comment #1 from RazvanN <razvan.nitu1305@gmail.com> ---
There is nothing unsafe in assigning a class reference to another. I agree that

--
January 17, 2022
https://issues.dlang.org/show_bug.cgi?id=22680

ag0aep6g <ag0aep6g@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |safe
                 CC|                            |ag0aep6g@gmail.com
           Severity|enhancement                 |minor

--- Comment #2 from ag0aep6g <ag0aep6g@gmail.com> ---
(In reply to RazvanN from comment #1)
> There is nothing unsafe in assigning a class reference to another.

Unless you're assigning garbage, which is happening here. A more elaborate demonstration of the unsafety:

----
import std.stdio: writeln;
import core.memory: GC;
C c;
class C
{
    immutable int* ip;
    this(int x) @safe { this.ip = new int(x); }
    ~this() @safe { c = this; }
}
void main() @safe
{
    () { new C(42); } ();
    () { ubyte[1000] clear_stack; } ();
    () @trusted { GC.collect(); } ();
    immutable int* ip = c.ip;
    writeln(*ip); /* Prints "42". */
    new int(13);
    int should_still_be_42 = *ip;
    writeln(should_still_be_42); /* Prints "13" - immutable data has changed.
*/
}
----

--
January 17, 2022
https://issues.dlang.org/show_bug.cgi?id=22680

--- Comment #3 from RazvanN <razvan.nitu1305@gmail.com> ---
(In reply to ag0aep6g from comment #2)
> (In reply to RazvanN from comment #1)
> > There is nothing unsafe in assigning a class reference to another.
> 
> Unless you're assigning garbage, which is happening here. A more elaborate demonstration of the unsafety:
> 
> ----
> import std.stdio: writeln;
> import core.memory: GC;
> C c;
> class C
> {
>     immutable int* ip;
>     this(int x) @safe { this.ip = new int(x); }
>     ~this() @safe { c = this; }
> }
> void main() @safe
> {
>     () { new C(42); } ();
>     () { ubyte[1000] clear_stack; } ();
>     () @trusted { GC.collect(); } ();
>     immutable int* ip = c.ip;
>     writeln(*ip); /* Prints "42". */
>     new int(13);
>     int should_still_be_42 = *ip;
>     writeln(should_still_be_42); /* Prints "13" - immutable data has
> changed. */
> }
> ----

My comment was unfinished. What I wanted to propose is to mark destructors that are @safe with scope. I don't think there would be any un-wanted side effects.

I added some labels and I pushed "Save Changes", but I forgot that I had a comment started.

--
January 17, 2022
https://issues.dlang.org/show_bug.cgi?id=22680

Stanislav Blinov <stanislav.blinov@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |stanislav.blinov@gmail.com

--- Comment #4 from Stanislav Blinov <stanislav.blinov@gmail.com> ---
(In reply to RazvanN from comment #3)

> My comment was unfinished. What I wanted to propose is to mark destructors that are @safe with scope. I don't think there would be any un-wanted side effects.
> 

There would be unwanted side effects. On a struct, for example, marking a destructor scope would prevent you from returning instances of such struct.

I think that a more prudent measure is to mark escaping destructors @system (i.e. making original code a compile-time error).

--
March 29, 2022
https://issues.dlang.org/show_bug.cgi?id=22680

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dkorpel@live.nl

--- Comment #5 from Dennis <dkorpel@live.nl> ---
(In reply to Stanislav Blinov from comment #4)
> There would be unwanted side effects. On a struct, for example, marking a destructor scope would prevent you from returning instances of such struct.

No, it only adds restrictions to the destructor's function body, not the destructor's caller.

--
March 29, 2022
https://issues.dlang.org/show_bug.cgi?id=22680

--- Comment #6 from Stanislav Blinov <stanislav.blinov@gmail.com> ---
(In reply to Dennis from comment #5)
> (In reply to Stanislav Blinov from comment #4)
> > There would be unwanted side effects. On a struct, for example, marking a destructor scope would prevent you from returning instances of such struct.
> 
> No, it only adds restrictions to the destructor's function body, not the destructor's caller.

Compile this with -dip1000:

@safe:

struct S
{
    ~this() scope {}
    void* p;
}

S test()
{
    S s;
    return s; // Error: scope variable `s` may not be returned
}

void main()
{
}

--
March 29, 2022
https://issues.dlang.org/show_bug.cgi?id=22680

--- Comment #7 from Dennis <dkorpel@live.nl> ---
(In reply to Stanislav Blinov from comment #6)
> Compile this with -dip1000:

That looks like a bug / remnant from the old dip1000 design.

--
March 29, 2022
https://issues.dlang.org/show_bug.cgi?id=22680

--- Comment #8 from Dennis <dkorpel@live.nl> ---
(In reply to Dennis from comment #7)
> That looks like a bug / remnant from the old dip1000 design.

Introduced by https://github.com/dlang/dmd/pull/7284

--
March 29, 2022
https://issues.dlang.org/show_bug.cgi?id=22680

--- Comment #9 from Stanislav Blinov <stanislav.blinov@gmail.com> ---
(In reply to Dennis from comment #7)
> (In reply to Stanislav Blinov from comment #6)
> > Compile this with -dip1000:
> 
> That looks like a bug / remnant from the old dip1000 design.

Oh, OK, that's good to know, thanks!

--
August 31, 2022
https://issues.dlang.org/show_bug.cgi?id=22680

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #10 from Walter Bright <bugzilla@digitalmars.com> ---
(In reply to Stanislav Blinov from comment #6)
> S test()
> {
>     S s;
>     return s; // Error: scope variable `s` may not be returned
> }

This has been fixed.

--
« First   ‹ Prev
1 2