Thread overview
[Issue 3569] New: DMD Stack Overflow with a struct member function inside a C-style struct initializer
Dec 03, 2009
Rob Jacques
Dec 03, 2009
Rob Jacques
Dec 29, 2009
Don
Jan 22, 2010
Don
Jan 31, 2010
Don
Jun 07, 2010
Don
Jun 07, 2010
Don
Jun 28, 2010
Walter Bright
December 03, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3569

           Summary: DMD Stack Overflow with a struct member function
                    inside a C-style struct initializer
           Product: D
           Version: 2.036
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: ice-on-valid-code
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: sandford@jhu.edu


--- Comment #0 from Rob Jacques <sandford@jhu.edu> 2009-12-03 13:45:02 PST ---
This is a regression between DMD 2.035 and DMD 2.036. Here is a simplified test case:

struct Foo {
    Foo bar() { return this; }
}

struct Bar {
    Foo foo;
    Bar opCom() {
        Bar r = { foo.bar() }; // Error caused by this line
        return r;
    }
}

The simple work around is to use D style constructors: Bar r = ( foo.bar() ); or to set the fields manually. However, tracking these down is very difficult because there is no line number nor easy find/replace.

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



--- Comment #1 from Rob Jacques <sandford@jhu.edu> 2009-12-03 13:54:14 PST ---
The cause of the stack overflow may be due to the C style initializers being incorrectly (correctly?) evaluated at compile time:

i.e.:
struct Foo {
    float opMul(float b) { return b; }
}

struct Bar {
    Foo foo;
    Bar opMul(float b) {
        Bar r = {foo*b};
        return r;
    }
}

generates the errors:
Error: variable b is used before initialization
Error: cannot evaluate this.foo.opMul(b) at compile time
Error: cannot implicitly convert expression (this.foo.opMul(b)) of type float
to Foo
Error: cannot evaluate this.foo.opMul(b) at compile time

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 29, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3569


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch
                 CC|                            |clugdbug@yahoo.com.au


--- Comment #2 from Don <clugdbug@yahoo.com.au> 2009-12-29 12:32:09 PST ---
This patch to AssertExp::interpret() prevents the stack overflow, turning it
into a simple error message. It doesn't patch the regression.
As Rob notes, the static struct initializers are evaluated at compile time, but
they shouldn't be. Nonetheless, this patch is still required to prevent
segfaults in the case where they are forcibly evaluated at compile time. Eg,
code like the following:

struct Foo {
    Foo bar() { return this; }
}

struct Bar {
    Foo foo;
    int fog() {
        enum Bar r = { foo.bar() };
        return 3;
    }
}

PATCH -----------------------

Index: interpret.c ===================================================================
--- interpret.c    (revision 318)
+++ interpret.c    (working copy)
@@ -2535,14 +2535,18 @@
     if( this->e1->op == TOKaddress)
     {   // Special case: deal with compiler-inserted assert(&this, "null
this")
     AddrExp *ade = (AddrExp *)this->e1;
-    if(ade->e1->op == TOKthis && istate->localThis)
-    return istate->localThis->interpret(istate);
+    if(ade->e1->op == TOKthis && istate->localThis)
+        if (istate->localThis->op==TOKdotvar
+          && ((DotVarExp *)(istate->localThis))->e1->op==TOKthis)
+        return getVarExp(loc, istate, ((DotVarExp
*)(istate->localThis))->var);
+        else
+            return istate->localThis->interpret(istate);
     }
-if (this->e1->op == TOKthis)
-{
+    if (this->e1->op == TOKthis)
+    {
     if(istate->localThis)
-    return istate->localThis->interpret(istate);
-}
+        return istate->localThis->interpret(istate);
+    }
     e1 = this->e1->interpret(istate);
     if (e1 == EXP_CANT_INTERPRET)
     goto Lcant;

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 22, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3569



--- Comment #3 from Don <clugdbug@yahoo.com.au> 2010-01-22 00:09:28 PST ---
Svn commit 337 gets rid of the stack overflow, and turns it into a rejects-valid bug.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 31, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3569


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|ice-on-valid-code, patch    |rejects-valid


--- Comment #4 from Don <clugdbug@yahoo.com.au> 2010-01-31 11:57:01 PST ---
This is downgraded from ice-on-valid-code to rejects-valid in DMD2.040.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 07, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3569


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|rejects-valid               |ice-on-valid-code


--- Comment #5 from Don <clugdbug@yahoo.com.au> 2010-06-07 06:59:26 PDT ---
This is causing a stack overflow again. I don't know why I thought it was fixed.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 07, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3569


Don <clugdbug@yahoo.com.au> changed:

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


--- Comment #6 from Don <clugdbug@yahoo.com.au> 2010-06-07 13:24:35 PDT ---
The fact that struct initializers are evaluated at compile time is bug 3809; only the stack overflow is unique to this bug.

Some tough cases for the test suite.
---
template Compileable(int z) { bool OK;}

struct Bug3569 {
    int bar() { return 7; }
}

struct Bug3569b {
    Bug3569 foo;
    void crash() {
        static assert(!is(typeof(Compileable!(foo.bar()))));
        static assert(!is(typeof(Compileable!((foo = Bug3569.init).bar()))));
    }
}

========
PATCH
Index: interpret.c
===================================================================
--- interpret.c    (revision 524)
+++ interpret.c    (working copy)
@@ -1110,8 +1110,9 @@

 Expression *ThisExp::interpret(InterState *istate)
 {
-    if (istate->localThis)
+    if (istate && istate->localThis)
         return istate->localThis->interpret(istate);
+    error("value of 'this' is not known at compile time");
     return EXP_CANT_INTERPRET;
 }

@@ -2105,6 +2106,11 @@
 #endif
     Expression *e = EXP_CANT_INTERPRET;
     Expression *e1 = this->e1;
+    if (!istate)
+    {
+        error("value of %s is not known at compile time", e1->toChars());
+        return e;
+    }

     if (fp)
     {

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 28, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3569


Walter Bright <bugzilla@digitalmars.com> changed:

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


--- Comment #7 from Walter Bright <bugzilla@digitalmars.com> 2010-06-27 20:50:24 PDT ---
http://www.dsource.org/projects/dmd/changeset/563

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