D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 1605 - break in switch with goto breaks in ctfe
Summary: break in switch with goto breaks in ctfe
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: x86 Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
 
Reported: 2007-10-21 10:34 UTC by Lutger
Modified: 2014-02-24 15:30 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Lutger 2007-10-21 10:34:12 UTC
I stumbled upon a case where a break statement in a switch causes the outer while loop to exit. This happens only when the function is evaluated at compile time and a goto statement is involved. Forgive me the bad example: 

int Break()
{
    int i = 0;
    while (true)
    {
        switch(i)
        {
            case 0:
            goto LABEL; // comment out this line and all is fine
             LABEL:
                // at compile time, this breaks out of the while loop:
                break;
            default:
                return i;
        }
        i = 1;
    }
    return 0; // unreachable
}

void main()
{
    assert (Break() == 1); // ok
    static assert(Break() == 1); // not ok
}
Comment 1 Don 2009-08-24 04:21:21 UTC
Actually this has nothing to do with switch or break. It only requires 'goto' inside a while loop.
Reduced test case:

int Break()
{
    int i = 0;
    while (true) {   
        goto LABEL;
        LABEL:
        if (i!=0) return i;
        i = 27;
    }
    assert(i==27); // this passes, it did actually execute the loop.
    return 88; // unreachable
}

static assert(Break() == 27);
-----------
It's failing because the test for continuing to execute is wrong.
----
PATCH: interpret.c, Expression *WhileStatement::interpret(InterState *istate)

	if (e == EXP_BREAK_INTERPRET)
	    return NULL;
-	if (e != EXP_CONTINUE_INTERPRET)
+	if (e && e != EXP_CONTINUE_INTERPRET)
	    return e;
    }

    while (1)
    {
	e = condition->interpret(istate);
Comment 2 Walter Bright 2009-09-03 13:22:55 UTC
Fixed dmd 1.047 and 2.032