Jump to page: 1 2
Thread overview
[Issue 15869] RVO can overwrite argument
Apr 04, 2016
ag0aep6g@gmail.com
Apr 05, 2016
Yuxuan Shui
Apr 05, 2016
ag0aep6g@gmail.com
Apr 05, 2016
Yuxuan Shui
Apr 05, 2016
ag0aep6g@gmail.com
Mar 14, 2018
FeepingCreature
Mar 14, 2018
Yuxuan Shui
Mar 14, 2018
Ketmar Dark
Mar 14, 2018
FeepingCreature
Apr 22, 2018
Walter Bright
Apr 22, 2018
Walter Bright
Apr 22, 2018
Ketmar Dark
Apr 22, 2018
Walter Bright
April 04, 2016
https://issues.dlang.org/show_bug.cgi?id=15869

ag0aep6g@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
                 CC|                            |ag0aep6g@gmail.com
           Hardware|x86_64                      |All
                 OS|Linux                       |All
           Severity|enhancement                 |normal

--- Comment #1 from ag0aep6g@gmail.com ---
Slightly reduced:
----
struct Set {
    @disable this(this);
    int value = 0;
}
Set clobber(Set* a) {
    Set ret; // <- This overwrites *a, i.e. &ret is the same as a
    ret.value = a.value; // <- Now a.value is 0
    return ret;
}
struct XX {
    Set a = Set(1);
    this(int n) {
        a = clobber(&a);
    }
}
void main(){
    XX xx = XX(0);
    assert(xx.a.value == 1); /* fails */
}
----

--
April 05, 2016
https://issues.dlang.org/show_bug.cgi?id=15869

--- Comment #2 from Yuxuan Shui <yshuiv7@gmail.com> ---
I think the expected behavior here is a compile error.

--
April 05, 2016
https://issues.dlang.org/show_bug.cgi?id=15869

--- Comment #3 from ag0aep6g@gmail.com ---
(In reply to Yuxuan Shui from comment #2)
> I think the expected behavior here is a compile error.

I think it should compile and set xx.a.value to 1. The compiler manages to do that when `a = clobber(&a);` is done outside of the constructor, and I don't see a reason why it being in a constructor should make a difference.

--
April 05, 2016
https://issues.dlang.org/show_bug.cgi?id=15869

--- Comment #4 from Yuxuan Shui <yshuiv7@gmail.com> ---
Looks like if clobber is not called in constructor, the return value is stored into a temporary variable and then copied into xx using Set.opAssign.

I'm not sure if this is correct since Set has disabled this(this).

--
April 05, 2016
https://issues.dlang.org/show_bug.cgi?id=15869

--- Comment #5 from ag0aep6g@gmail.com ---
(In reply to Yuxuan Shui from comment #4)
> Looks like if clobber is not called in constructor, the return value is stored into a temporary variable and then copied into xx using Set.opAssign.
> 
> I'm not sure if this is correct since Set has disabled this(this).

`@disable this(this)` does not prevent moving the struct. A move is a bitwise copy that invalidates the source, i.e. there are no destructor or postblit calls.

--
March 14, 2018
https://issues.dlang.org/show_bug.cgi?id=15869

FeepingCreature <default_357-line@yahoo.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |default_357-line@yahoo.de

--- Comment #6 from FeepingCreature <default_357-line@yahoo.de> ---
I think what's happening here is that DMD thinks that because a is assigned in the  XX constructor, the member a is to be initialized by the constructor and not the default initializer. As a result, &a is technically use-before-initialization and invalid.

If true, then even though it's invalid code this still needs to be added to the docs, because it is somewhat unintuitive.

--
March 14, 2018
https://issues.dlang.org/show_bug.cgi?id=15869

--- Comment #7 from Yuxuan Shui <yshuiv7@gmail.com> ---
> As a result, &a is technically use-before-initialization and invalid.

If that's the case, this shouldn't compile:

struct Set {
    @disable this(this);
    int value = 0;
}
@safe Set clobber(Set* a) {}
struct XX {
    Set a = Set(1);
    @safe this(int n) {
        a = clobber(&a); // use-before-init
    }
}

But it does.

--
March 14, 2018
https://issues.dlang.org/show_bug.cgi?id=15869

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

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

--
March 14, 2018
https://issues.dlang.org/show_bug.cgi?id=15869

--- Comment #8 from FeepingCreature <default_357-line@yahoo.de> ---
Agreed.

--
April 22, 2018
https://issues.dlang.org/show_bug.cgi?id=15869

Walter Bright <bugzilla@digitalmars.com> changed:

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

--- Comment #9 from Walter Bright <bugzilla@digitalmars.com> ---
The most pragmatic solution is to not allow taking a reference to an unconstructed field.

--
« First   ‹ Prev
1 2