| |
|
Don 
| 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@puremagic.com
ReportedBy: clugdbug@yahoo.com.au
--- Comment #0 from Don <clugdbug@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: -------
|