D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3160 - ICE(cgcod.c 1511-D1) or bad code-D2 returning string from void main
Summary: ICE(cgcod.c 1511-D1) or bad code-D2 returning string from void main
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: Other Windows
: P2 critical
Assignee: No Owner
URL:
Keywords: ice-on-valid-code, patch
Depends on:
Blocks:
 
Reported: 2009-07-10 00:45 UTC by Don
Modified: 2014-04-18 09:12 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Don 2009-07-10 00:45:32 UTC
Courtesy of bearophile.

void main() { return "a"; }
Comment 1 Don 2009-09-14 23:54:41 UTC
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).
Comment 2 Don 2009-09-15 08:44:16 UTC
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;
}
Comment 3 Don 2009-09-15 11:31:30 UTC
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);
     }
Comment 4 Don 2009-10-01 05:47:20 UTC
The patch for the related bug 3344 adds a check for side-effects.
Comment 5 Walter Bright 2009-10-06 02:17:15 UTC
Fixed dmd 1.048 and 2.033