Courtesy of bearophile. void main() { return "a"; }
This is actually a regression. Did not ICE in 0.175, 1.006. Began to ICE at 1.017 or earlier. ICE in 2.000->2.022. Was fixed in 2.023. However, although it didn't ICE on those versions, it's an accepts-invalid. Seems to be adding an implicitly cast to void. (BTW, the accepts-invalid applies to all functions, not just main).
ROOT CAUSE: The logic for inserting a "return 0" at the end of a void main, and the logic for evaluating the return expression in a void function, interact incorrectly. The case where BOTH these things need to happen was missing. BTW, this is probably wrong in D2 as well. PATCH: statement.c, last lines of ReturnStatement::semantic (around line 2891): - if (exp && tbret->ty == Tvoid && !fd->isMain()) + if (exp && tbret->ty == Tvoid && !implicit0) { /* Replace: * return exp; * with: * exp; return; */ Statement *s = new ExpStatement(loc, exp); loc = 0; + if (fd->isMain()) exp = new IntegerExp(0); + else exp = NULL; return new CompoundStatement(loc, s, this); } return this; }
In D2, rather than an ICE, it generates wrong code. Can't really claim ICE<->wrong-code is a regression. Technically, this is valid, but I'm actually not sure if this type of code should be allowed. Should it check for side-effects? IE, void main() { return 2; } --> should this generate a "expression (2) has no effect" error? Seems like a newbie trap. Here's a more formal patch against DMD2.032: Index: statement.c =================================================================== --- statement.c (revision 54) +++ statement.c (revision 55) @@ -3454,7 +3454,7 @@ return gs; } - if (exp && tbret->ty == Tvoid && !fd->isMain()) + if (exp && tbret->ty == Tvoid && !implicit0) { /* Replace: * return exp; @@ -3463,7 +3463,10 @@ */ Statement *s = new ExpStatement(loc, exp); loc = 0; - exp = NULL; + if (fd->isMain()) + exp = new IntegerExp(0); + else + exp = NULL; return new CompoundStatement(loc, s, this); }
The patch for the related bug 3344 adds a check for side-effects.
Fixed dmd 1.048 and 2.033