www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3569] New: DMD Stack Overflow with a struct member function inside a C-style struct initializer

reply d-bugmail puremagic.com writes:
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



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: -------
Dec 03 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3569




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: -------
Dec 03 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
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



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: -------
Dec 29 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3569




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: -------
Jan 22 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
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



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: -------
Jan 31 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
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



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: -------
Jun 07 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3569


Don <clugdbug yahoo.com.au> changed:

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



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: -------
Jun 07 2010
prev sibling parent d-bugmail puremagic.com writes:
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



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: -------
Jun 27 2010