www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 2569] New: static arrays in CTFE functions don't compile

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569

           Summary: static arrays in CTFE functions don't compile
           Product: D
           Version: 1.039
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: clugdbug yahoo.com.au


int foo()
{
   int [3] a;
   return 0;
}

static x = foo();

---
bug.d(7): Error: cannot evaluate foo() at compile time

Interestingly, in D2.023, the error message is displayed twice.


-- 
Jan 08 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569






This isn't complicated. The only reason it doesn't work is that
BinExp::interpretAssignCommon in interpret.c doesn't deal with array assignment
AT ALL.

Adding a trivial hack like:
   if (e1->op == TOKslice) {
     return e2;
   }
is enough to make most cases work. I'm working on a proper patch which will
deal with array literals, etc.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 21 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch





Turned out to be slightly more involved than I thought, there are a few special
cases. I think I've captured them all.

Extended test case:
-------------------
struct Foo {
    int m;
}

int foo()
{
   short [4] a  = [2, 3, 4, 6];
   double [27] b = 2.0;
   cfloat[2] c;   
   auto d = [2, 3, 4, 5];
   Foo[2] e = [Foo(3), Foo(2)];
//   ushort [3] f  = [1, 2];  // Uncomment to generate a compile-time error.
   d[2..6] = 4;
   a[1] = 7;
   return a[0]-3;
}
static assert(foo()==-1);

PATCH: interpret.c, line 1464 in BinExp::interpretAssignCommon(),
before checking for the other cases.
------------
    // Assignment/initialization of static arrays
    if (e1->op == TOKslice && ((SliceExp *)e1)->e1->op==TOKvar) {
        SliceExp * sexp = (SliceExp *)e1;
        VarExp *ve = (VarExp *)(sexp->e1);
        VarDeclaration *v = ve->var->isVarDeclaration();
        Type *t = v->type->toBasetype();
        if (t->ty == Tsarray){             
            size_t dim = ((TypeSArray *)t)->dim->toInteger();
        if (e2->op == TOKarrayliteral) {
                // Static array assignment from literal
                ArrayLiteralExp *ae = (ArrayLiteralExp *)e2;
                // Ensure length is the same
                if (ae->elements->dim != dim) {
                 error("Array length mismatch");
                return e;
                }
                        v->value = ae;
                return ae;
            }
            if (t->nextOf()->ty == e2->type->ty) {
                 // Static array block assignment
                Expressions *elements = new Expressions();
                elements->setDim(dim);
                for (size_t i = 0; i < dim; i++)
                    elements->data[i] = e2;               
                ArrayLiteralExp *ae = new ArrayLiteralExp(0, elements);
                ae->type = v->type;
                v->value = ae;
                return e2;
            }
        }
    }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 22 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|patch                       |





The patch I posted was incomplete, so I'm withdrawing it. Done properly, it
should support slicing assignment, and arrays initialized to void.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 23 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569


Dimitar Kolev <DimitarRosenovKolev hotmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |DimitarRosenovKolev hotmail
                   |                            |.com





07:41:12 PDT ---

 The patch I posted was incomplete, so I'm withdrawing it. Done properly, it
 should support slicing assignment, and arrays initialized to void.
This is a nasty little bugger. Any idea when the pAtch will be ready? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 23 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569








 The patch I posted was incomplete, so I'm withdrawing it. Done properly, it
 should support slicing assignment, and arrays initialized to void.
This is a nasty little bugger. Any idea when the patch will be ready?
assignment in CTFE. There are an unbelievable number of special cases. The only thing that's missing is that it doesn't deal with assignment from string literals. Which means that: char [5] s = "abc"; // fails char [6] t = ['a', 'b', 'c']; // ok Here's my test case. All the tests below are working on my patched DMD: struct S { int x; char y; } // Functions which should fail CTFE int badfoo(){ S[2] c; c[4].x=6; // array bounds error return 7; } int badglobal = 1; int badfoo2(){ S[] c; c[7].x=6; // uninitialized error return 7; } int badfoo3(){ S[2] c; c[badglobal].x=6; // global index error return 7; } int badfoo4(){ static S[2] c; c[0].x=6; // Cannot access static return 7; } int badfoo5(){ S[] c = void; c[0].x=6; // c is uninitialized, and not a static array. return 1; } int badfoo6() { S[] b = [S(7), S(15), S(56), S(12)]; b[-2..4] = S(17); // exceeding (negative) array bounds return 1; } int badfoo7() { S[] b = [S(7), S(15), S(56), S(12), S(67)]; b[1..4] = [S(17), S(4)]; // slice mismatch in dynamic array return 1; } int badfoo8() { S[] b; b[1..3] = [S(17), S(4)]; // slice assign to uninitialized dynamic array return 1; } template Compileable(int z) { bool OK;} static assert(!is(typeof(Compileable!(badfoo()).OK))); static assert(!is(typeof(Compileable!(badfoo2()).OK))); static assert(!is(typeof(Compileable!(badfoo3()).OK))); static assert(!is(typeof(Compileable!(badfoo4()).OK))); static assert(!is(typeof(Compileable!(badfoo5()).OK))); static assert(!is(typeof(Compileable!(badfoo6()).OK))); static assert(!is(typeof(Compileable!(badfoo7()).OK))); static assert(!is(typeof(Compileable!(badfoo8()).OK))); // Functions which should pass CTFE int goodfoo1() { int[8] w; // use static array in CTFE w[]=7; // full slice assign w[$-1]=538; // use of $ in index assignment assert(w[6]==7); return w[7]; } static assert(goodfoo1()==538); int goodfoo2() { S[4] w = S(101); // Block-initialize array of structs w[$-2].x = 917; // use $ in index member assignment w[$-2].y = 58; // this must not clobber the prev assignment return w[2].x; // check we got the correct one } static assert(goodfoo2()==917); int goodfoo3() { S[4] w = void; // uninitialized array of structs w[$-2].x = 217; // initialize one member return w[2].x; } static assert(goodfoo3()==217); int goodfoo4() { S[4] b = [S(7), S(15), S(56), S(12)]; // assign from array literal assert(b[3]==S(12)); return b[2].x-55; } static assert(goodfoo4()==1); int goodfoo5() { S[4] b = [S(7), S(15), S(56), S(12)]; b[0..2] = [S(2),S(6)]; // slice assignment from array literal assert(b[3]==S(12)); assert(b[1]==S(6)); return b[0].x; } static assert(goodfoo5()==2); static assert(goodfoo5()==2); // check for memory corruption int goodfoo6() { S[6] b = void; b[2..5] = [S(2),S(6), S(17)]; // slice assign to uninitialized var assert(b[4]==S(17)); return b[3].x; } static assert(goodfoo6()==6); int goodfoo7() { S[8] b = void; b[2..5] = S(217); // slice assign to uninitialized var assert(b[4]==S(217)); return b[3].x; } static assert(goodfoo7()==217); int goodfoo8() { S[] b = [S(7), S(15), S(56), S(12), S(67)]; b[2..4] = S(17); // dynamic array block slice assign assert(b[3]==S(17)); assert(b[4]==S(67)); return b[0].x; } static assert(goodfoo8()==7); -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 24 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569






01:50:38 PDT ---
Thanks great work. You got a beer from me.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 24 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569






Created an attachment (id=434)
 --> (http://d.puremagic.com/issues/attachment.cgi?id=434)
Patch against DMD1.046. Works for DMD2.031 as well.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 24 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch





Here's the patch. Cheers!

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 24 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569


Max Samukha <samukha voliacable.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |samukha voliacable.com





PDT ---
Thanks a lot!

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 24 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569









compiler in multiple places, which is difficult).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 24 2009
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2569


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla digitalmars.com
         Resolution|                            |FIXED





13:24:02 PDT ---
Fixed dmd 1.047 and 2.032

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