[Issue 3901] New: PATCH: Nested struct assignment for CTFE

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon Mar 8 11:29:17 PST 2010


http://d.puremagic.com/issues/show_bug.cgi?id=3901

           Summary: PATCH: Nested struct assignment for CTFE
           Product: D
           Version: 1.055
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: patch, rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody at puremagic.com
        ReportedBy: clugdbug at yahoo.com.au


--- Comment #0 from Don <clugdbug at yahoo.com.au> 2010-03-08 11:29:16 PST ---
This is a MAJOR refactoring of assignment in CTFE. The assign function was a
big mess. A lot of work, and there's not really much to show for it from 
a user's perspective. But it's a solid platform to allow the final CTFE bugs to
be fixed.

To install this patch, you need to add a single function to mtype.c, and
completely replace interpret.c with the attachment.(There are so many changes,
that a patch doesn't make sense).
Fortunately the test suite file interpret.d is getting quite extensive.
And these new tests do some pretty evil things...

==

New features:
* Arbitrary nested struct assignment now works in CTFE.
  a.b.c.d = e;
  a[i].b.c.d = e;
* ref return values now work in CTFE (D2 only).

BUGS FIXED:
3842 ICE(expression.c) using pointer in CTFE
3899 CTFE: poor error message for use of uninitialized variable
3900 CTFE: Wrong return value for array.var assignment

========================================================
============  PATCH for mtype.c: =======================
========================================================

--- mtype.c    (revision 409)
+++ mtype.c    (working copy)
@@ -3451,6 +3451,21 @@
     return next->isZeroInit(loc);
 }

+Expression *TypeSArray::defaultInitLiteral(Loc loc)
+{
+#if LOGDEFAULTINIT
+    printf("TypeSArray::defaultInitLiteral() '%s'\n", toChars());
+#endif
+    size_t d = dim->toInteger();
+    Expression *elementinit = next->defaultInitLiteral(loc);
+    Expressions *elements = new Expressions();
+    elements->setDim(d);
+    for (size_t i = 0; i < d; i++)
+     elements->data[i] = elementinit;
+    ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements);
+    ae->type = this;
+    return ae;
+}

 Expression *TypeSArray::toExpression()
 {
Index: mtype.h
===================================================================
--- mtype.h    (revision 409)
+++ mtype.h    (working copy)
@@ -406,6 +406,7 @@
     MATCH constConv(Type *to);
     MATCH implicitConvTo(Type *to);
     Expression *defaultInit(Loc loc);
+    Expression *defaultInitLiteral(Loc loc);
     dt_t **toDt(dt_t **pdt);
     dt_t **toDtElem(dt_t **pdt, Expression *e);
     MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
Objects *dedtypes);


========================================================
========= Test cases for test suite. ===================
========================================================


struct ArrayRet{
   int x;
}

int arrayRetTest(int z)
{
  ArrayRet[6] w;
  int q = (w[3].x = z);
  return q;  
}

static assert(arrayRetTest(51)==51);

// Bugzilla 3842 -- must not segfault
int ice3842(int z)
{
   ArrayRet w;
   return arrayRetTest((*(&w)).x);   
}

static assert(true || is(typeof(compiles!(ice3842(51)))));


int arrayret2(){

  int [5] a;
  int [3] b;
  b[] = a[1..$-1] = 5;
  return b[1];
}
static assert(arrayret2()==5);

struct DotVarTest
{
   ArrayRet z;
}

struct DotVarTest2
{
   ArrayRet z;
   DotVarTest p;
}

int dotvar1()
{
    DotVarTest w;
    w.z.x = 3;
    return w.z.x; 
}

int dotvar2()
{
    DotVarTest2[4] m;
    m[2].z.x = 3;
    m[1].p.z.x = 5;
    return m[2].z.x + 7;
}

static assert(dotvar1()==3);
static assert(dotvar2()==10);


struct RetRefStruct{
   int x;
   char c;
}

// Return value reference tests, for D2 only.

ref RetRefStruct reffunc1(ref RetRefStruct a)
{
int y = a.x;
return a;
}


ref RetRefStruct reffunc2(ref RetRefStruct a)
{
   RetRefStruct z = a;
   return reffunc1(a);
}

ref int reffunc7(ref RetRefStruct aa)
{
   return reffunc1(aa).x;
}

ref int reffunc3(ref int a)
{
    return a;
}

struct RefTestStruct
{
  RetRefStruct r;

  ref RefTestStruct reffunc4(ref RetRefStruct[3] a)
  {
    return this;
  }

  ref int reffunc6()
  {
    return this.r.x;
  }
}

ref RetRefStruct reffunc5(ref RetRefStruct[3] a)
{
   int t = 1;
   for (int i=0; i<10; ++i)
   { if (i==7)  ++t;}
    return a[reffunc3(t)];
}

int retRefTest1()
{
    RetRefStruct b = RetRefStruct(0,'a');
    reffunc1(b).x =3;
    return b.x-1;
}

int retRefTest2()
{
    RetRefStruct b = RetRefStruct(0,'a');
    reffunc2(b).x =3;
    RetRefStruct[3] z;
    RefTestStruct w;
    w.reffunc4(z).reffunc4(z).r.x = 4;
    assert(w.r.x == 4);
    w.reffunc6() = 218;
    assert(w.r.x == 218);
    z[2].x = 3;
    int q=4;
    int u = reffunc5(z).x + reffunc3(q);
    assert(u==7);
    reffunc5(z).x += 7;
    assert(z[2].x == 10);
    RetRefStruct m = RetRefStruct(7, 'c');
    m.x = 6;
    reffunc7(m)+=3;
    assert(m.x==9);
    return b.x-1;
}

int retRefTest3()
{
    RetRefStruct b = RetRefStruct(0,'a');
    auto deleg = function (RetRefStruct a){ return a;};
    typeof(deleg)[3] z;
    z[] = deleg;    
    auto y = deleg(b).x + 27;
    b.x = 5;
    assert(y == 27);
    y = z[1](b).x + 22;
    return y - 1;
}

int retRefTest4()
{
    RetRefStruct b = RetRefStruct(0,'a');
    reffunc3(b.x) = 218;
    assert(b.x == 218);
    return b.x;
}


static assert(retRefTest1()==2);
static assert(retRefTest2()==2);
static assert(retRefTest3()==26);
static assert(retRefTest4()==218);

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list