This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[3.4 PATCH] PR 18493: Corner case for switch in C front-end.

The following patch resolves PR middle-end/18493 with is a problem
handling switch statements without any case labels in the C parser.
This is a regression from 3.x and results in references to
non-existant labels in assembly output.

The issue is closely related to PR c/9262.  The fix to that problem
was to thread statement lists to a switch's SWITCH_BODY as soon as
a case label or default: was encountered.  This provided for better
error recovery if a parse error was encountered in the switch body.
A side-effect of this is that 3.4 ended up completely ignoring switch
bodies that don't contain any case or default labels.  Normally, this
isn't an issue as the code is effectively unreachable, unless of course
it contains a user label that's the destination of a goto statement.
The code in the bugzilla PR, reproduced as switch-4.c below, is exactly
this rare corner case.

The fix is that in "c_finish_case", the SWITCH_BODY is still NULL, i.e.
we haven't encountered any labels whilst parsing the body (i.e. do_case
was never called), we need to thread any statements that we did see to
the SWITCH_BODY.  This shouldn't cause any performance overhead as the
RTL expansion code uses expand_unreachable_stmt on the SWITCH_BODY, so
if it didn't contain a user label, we'll not emit any code as before.

I've also double and triple checked that this change doesn't interfere
with the solution for PR c/9262 using variants of its test cases.  It
turns out that the failures in PR c/9262 were caused by the fact that
c_finish_case wasn't being called during error recovery.  Hence, this
change should have no affect for those cases, and indeed the tests in
the testsuite confirm this.

The following patch has been tested against the gcc-3_4-branch on
i686-pc-linux-gnu with a full "make bootstrap", all default languages,
and regression tested with a top-level "make -k check" with no new

Ok for the gcc-3_4-branch?  I'll also commit the new test to mainline,
but obviously this area of the compiler has been completely rewritten
for 4.0.

2004-11-26  Roger Sayle  <>

	PR middle-end/18493
	* c-typeck.c (c_finish_case): Rechain statements if we didn't
	encounter any case labels or a default.

	* gcc.dg/switch-4.c: New test case.

Index: c-typeck.c
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision
diff -c -3 -p -r1.272.2.10 c-typeck.c
*** c-typeck.c	23 Sep 2004 15:05:13 -0000
--- c-typeck.c	26 Nov 2004 02:48:45 -0000
*************** c_finish_case (void)
*** 6551,6556 ****
--- 6551,6564 ----
    struct c_switch *cs = switch_stack;

+   /* If we've not seen any case labels (or a default), we may still
+      need to chain any statements that were seen as the SWITCH_BODY.  */
+   if (SWITCH_BODY (cs->switch_stmt) == NULL)
+     {
+       SWITCH_BODY (cs->switch_stmt) = TREE_CHAIN (cs->switch_stmt);
+       TREE_CHAIN (cs->switch_stmt) = NULL_TREE;
+     }
    /* Rechain the next statements to the SWITCH_STMT.  */
    last_tree = cs->switch_stmt;

/* PR middle-end/18493 */
/* { dg-do link } */

int main() {
goto bug;
switch(0) {
bug: return 0;

Roger Sayle,                         E-mail:
OpenEye Scientific Software,         WWW:
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]