www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3809] New: Struct initializers apparently always CTFE'd, and incorrectly

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

           Summary: Struct initializers apparently always CTFE'd, and
                    incorrectly
           Product: D
           Version: 1.056
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: diagnostic, rejects-valid, wrong-code
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: matti.niemenmaa+dbugzilla iki.fi


--- Comment #0 from Matti Niemenmaa <matti.niemenmaa+dbugzilla iki.fi>
2010-02-16 14:25:34 PST ---
This worked at least as late as 1.051, but now fails in 1.056:

struct S { int xx; int x() { return xx; } }
void foo(S s) {
    S a = {100 / s.x()};
    S b = {100 / s.x()};
}

$ dmd arst.d
Error: divide by 0
arst.d(4): Error: cannot evaluate s.x() at compile time

It seems like it's CTFEing the s.x() calls, which would explain the (bonus:
location-lacking) division by zero error as well: xx is zero by default, after
all.

Confirmed by changing "int xx" to "int xx = 1" and returning b from foo: the
code compiles, and the disassembly shows that no divisions are being performed,
it was erroneously done at compile time. Similarly, changing the code to
perform e.g. a multiplication instead of a division makes it compile (as the
division by zero is the cause for the lack of compilation), but again the s.x()
has been improperly CTFE'd.

An additional point of interest: the "cannot evaluate" error is only reported
for the S's after the first: with only one, the code compiles (to wrong code,
again).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 16 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3809


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au


--- Comment #1 from Don <clugdbug yahoo.com.au> 2010-02-26 07:49:20 PST ---
I think this is the same as bug 3792.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 26 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3809



--- Comment #2 from Don <clugdbug yahoo.com.au> 2010-04-23 12:51:54 PDT ---
Starting with the simple thing: the missing line number in the division by 0
error message.
PATCH:  interpret.c, near the start of BinExp::interpretAssignCommon().

    else if (e1->op != TOKslice)
    {   /* Look for special case of struct being initialized with 0.
        */
        if (type->toBasetype()->ty == Tstruct && newval->op == TOKint64)
        {
-            newval = type->defaultInitLiteral();
+            newval = type->defaultInitLiteral(loc);
        }
        newval = Cast(type, type, newval);
        e = newval;
    }

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



--- Comment #3 from Don <clugdbug yahoo.com.au> 2010-04-23 12:58:21 PDT ---
(In reply to comment #2)
 Starting with the simple thing: the missing line number in the division by 0
 error message.
 PATCH:  interpret.c, near the start of BinExp::interpretAssignCommon().
[snip] Oops, that patch fixed a related test case: struct S { int xx; } int badline() { S s; return 100/s.xx; } static assert(badline()); To fix this one as well, the same patch needs to applied to interpret.c, getVarExp(), around line 1250. if (v->init) { if (v->init->isVoidInitializer()) { error(loc, "variable %s is used before initialization", v->toChars()); return EXP_CANT_INTERPRET; } e = v->init->toExpression(); e = e->interpret(istate); } else // This should never happen { - e = v->type->defaultInitLiteral(); + e = v->type->defaultInitLiteral(loc); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 23 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3809



--- Comment #4 from Don <clugdbug yahoo.com.au> 2010-05-31 11:46:37 PDT ---
This isn't really a regression. Struct static initializers
have always been CTFEd, for example the code below generates a compile-time
div-by-zero error even in DMD 1.023. The only reason this code ever worked
was that CTFE didn't work for member functions. Starting with svn 337 
(DMD1.056), member functions can be called at compile time.

However, the spec says:
"The static initializer syntax can also be used to initialize non-static
variables, provided that the member names are not given. 
The initializer need not be evaluatable at compile time."

The compiler has never complied with this part of the spec.

// Should compile, but fails
int bug3809() { asm { nop; } return 0; }
struct BUG3809 { int xx; }
void bug3809b() {
    BUG3809 b = { bug3809() };
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 31 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3809


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|wrong-code                  |
                 CC|                            |bugzilla digitalmars.com


--- Comment #5 from Walter Bright <bugzilla digitalmars.com> 2010-06-02
15:37:10 PDT ---
http://www.dsource.org/projects/dmd/changeset/517 turns it into rejects-valid

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 02 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3809


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|1.056                       |D1 & D2
            Summary|Struct initializers         |Struct initializers
                   |apparently always CTFE'd,   |apparently always CTFE'd
                   |and incorrectly             |
           Severity|regression                  |major


--- Comment #6 from Don <clugdbug yahoo.com.au> 2010-08-06 03:34:42 PDT ---
Although CTFE is still performed, it's no longer performed incorrectly.
Since CTFE has always been performed on struct initializers, I'm removing the
'regression' tag.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 06 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3809


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


--- Comment #7 from Walter Bright <bugzilla digitalmars.com> 2011-04-27
20:06:33 PDT ---
https://github.com/D-Programming-Language/dmd/commit/97c73b140f1cde5d0b713eb72fd1e82084a6ac11

https://github.com/D-Programming-Language/dmd/commit/13dcf90d934325b4f37c50679e07978a821c4249

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