D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5769 - struct elaborate constructor should make rvalue
Summary: struct elaborate constructor should make rvalue
Status: RESOLVED DUPLICATE of issue 5889
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-03-23 05:34 UTC by Kenji Hara
Modified: 2012-04-23 11:18 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Kenji Hara 2011-03-23 05:34:02 UTC
Struct literal/constructor call should make rvalue.
Related issue is issue5178.

Test code:
----
struct S    // has default parameterized constructor
{
    int n;
}
struct T    // has normal constructor
{
    this(int n){}
//  ref T __ctor(int n){ return this; }  // dmd generates internally like this
}
struct T2
{
    template __ctor()   // workaround
    {
        T2 __ctor(int n){ return this; } // return copied rvalue
    }
}

// lvalue checker
bool checker(T...)(auto ref T t){ return __traits(isRef, t[0]); }

import std.stdio;
void main()
{
    int n =    20;
    S   s =  S(20);
    T   t =  T(20);
    T2 t2 = T2(20);

    writefln("%s / %s", checker(   10) , checker( n));  // false/true, ok
    writefln("%s / %s", checker( S(10)), checker( s));  // true /true, NG   (Fixed by issue5178 patch)
    writefln("%s / %s", checker( T(10)), checker( t));  // true /true, NG!!!
    writefln("%s / %s", checker(T2(10)), checker(t2));  // false/true, ok
}
----
Comment 1 Kenji Hara 2011-03-23 05:47:01 UTC
Fixing thi bug is difficult for me.

DMD internally behavior is...
1.Elaborate constructor returns this reference internally.
  -> see CtorDeclaration::semantic()
2.Elaborate constructor call T(args) is translated like (T __ctmp, __ctmp.__ctor(args)) and __ctmp.__ctor returns ref T.
  -> see CallExp::semantic

Trivial fix patch is follwing, but this causes copying value.
----
 src/func.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/func.c b/src/func.c
index c3fd455..ea48670 100644
--- a/src/func.c
+++ b/src/func.c
@@ -2953,7 +2953,7 @@ void CtorDeclaration::semantic(Scope *sc)
 
 #if STRUCTTHISREF
     if (ad && ad->isStructDeclaration())
-    {   ((TypeFunction *)type)->isref = 1;
+    {   //((TypeFunction *)type)->isref = 1;
         if (!originalType)
             // Leave off the "ref"
             originalType = new TypeFunction(arguments, tret, varargs, LINKd, storage_class | sc->stc);
----
Comment 2 SomeDude 2012-04-23 02:10:48 UTC
On 2.059, 

PS E:\DigitalMars\dmd2\samples> rdmd bug.d
false / true
false / true
false / true
false / true
Comment 3 Kenji Hara 2012-04-23 11:18:45 UTC

*** This issue has been marked as a duplicate of issue 5889 ***