Jump to page: 1 2
Thread overview
[Issue 20809] return statement might access memory from destructed temporary
May 08, 2020
dlang@foerdi.net
May 09, 2020
Ketmar Dark
May 13, 2020
welkam
May 13, 2020
welkam
Jun 09, 2020
timon.gehr@gmx.ch
Nov 18, 2021
Dennis
Nov 18, 2021
foerdi
Nov 18, 2021
Dennis
Nov 26, 2021
RazvanN
Jan 17, 2022
vitamin
Aug 09, 2022
Walter Bright
Aug 09, 2022
Dlang Bot
Aug 15, 2022
Dlang Bot
May 08, 2020
https://issues.dlang.org/show_bug.cgi?id=20809

moonlightsentinel@disroot.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |moonlightsentinel@disroot.o
                   |                            |rg

--- Comment #1 from moonlightsentinel@disroot.org ---
Digger blames this PR: https://github.com/dlang/dmd/pull/10577

--
May 08, 2020
https://issues.dlang.org/show_bug.cgi?id=20809

hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hsteoh@quickfur.ath.cx

--- Comment #2 from hsteoh@quickfur.ath.cx ---
Please copy-n-paste the code in this bug, so that it won't get lost in the ether in the future.

--
May 08, 2020
https://issues.dlang.org/show_bug.cgi?id=20809

--- Comment #3 from hsteoh@quickfur.ath.cx ---
Here, let me do it for you:

------
import std.stdio;
@safe:
struct S
{
    @safe:
    int a;
    ~this()
    {
        a = 0;
    }

    ref val()
    {
        return a;
    }
}

S bar()
{
    return S(2);
}

int foo()
{
    return bar.val; // The return value of val is saved locally as ref int and
then the destructor of S is called (set the local cache to 0). Now the ref
value is dereferenced and returned
}

void main()
{
    assert(foo() == 2); // foo() is 0
}
------

Just please keep in mind next time to post the entire body of code in the bug so that it will never get lost in the future.

--
May 08, 2020
https://issues.dlang.org/show_bug.cgi?id=20809

--- Comment #4 from dlang@foerdi.net ---
(In reply to hsteoh from comment #3)

> Just please keep in mind next time to post the entire body of code in the bug so that it will never get lost in the future.

Thank you, I will keep this in my mind for the next time.

--
May 09, 2020
https://issues.dlang.org/show_bug.cgi?id=20809

Ketmar Dark <ketmar@ketmar.no-ip.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ketmar@ketmar.no-ip.org

--
May 13, 2020
https://issues.dlang.org/show_bug.cgi?id=20809

welkam <wwwelkam@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |wwwelkam@gmail.com

--- Comment #5 from welkam <wwwelkam@gmail.com> ---
Even more reduced test case
----------------------------
struct S
{
    int a;
    ~this()
    {
        a = 0;
    }
}

void main()
{
    assert(foo() == 2); // foo() is 0
}

int foo()
{
    //bug is here
    return S(2).a; // destructor of the struct is called in this scope and sets
a to 0
}

--
May 13, 2020
https://issues.dlang.org/show_bug.cgi?id=20809

--- Comment #6 from welkam <wwwelkam@gmail.com> ---
This function works as expected
int foo()
{
    S test = S(2);
    return test.a;
}

--
June 09, 2020
https://issues.dlang.org/show_bug.cgi?id=20809

timon.gehr@gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timon.gehr@gmx.ch

--- Comment #7 from timon.gehr@gmx.ch ---
While this is a regression, the underlying bug existed already in 2.089.1:

@safe:
struct S{
    @safe:
    int[8] a;
    ~this(){ a[] = 0; }
    ref val(){ return a; }
}
S bar(){ return S([2,2,2,2,2,2,2,2]); }
int[8] foo(){ return bar.val; }

void main(){ assert(foo() == [2,2,2,2,2,2,2,2]); } // error

I guess this is why review did not catch the problem (the pull request just generalized an already existing wrong transformation).

--
November 18, 2021
https://issues.dlang.org/show_bug.cgi?id=20809

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |safe
                 CC|                            |dkorpel@live.nl
           Hardware|x86_64                      |All
                 OS|Linux                       |All

--- Comment #8 from Dennis <dkorpel@live.nl> ---
This is important for making Phobos's tempCString @safe:

```
    // $(RED WARNING): $(RED Incorrect usage)
    auto pInvalid1 = str.tempCString().ptr;
    const char* pInvalid2 = str.tempCString();
    // Both pointers refer to invalid memory here as
    // returned values aren't assigned to a variable and
    // both primary expressions are ended.
```

--
November 18, 2021
https://issues.dlang.org/show_bug.cgi?id=20809

--- Comment #9 from foerdi <dlang@foerdi.net> ---
Recently I discovered an interesting fact: this error or regression has also affected the std RefCounter.

https://run.dlang.io/is/PMyy0W
```d
import std;

int foo()
{
    return refCounted(2); //(alias this) .refCountedPayload has ref return
}

void main()
{
    writeln(foo()); // foo() is corrupted
    assert(foo() == 2); // foo() is corrupted
}
```

I am surprised that this issue has not been more noticeable.

--
« First   ‹ Prev
1 2