C: Incorrect Code Generated by switch() Statement

ID Number: Q43965

5.10 | 5.10

MS-DOS | OS/2

buglist5.10

Summary:

Under C Version 5.10, the following code sample causes incorrect code

generation as seen when compiled with the default optimization /Ot.

Compiling with /Od corrects the problem.

More information:

int dummy;

int *foo;

bug_demo()

{

if (foo)

switch(dummy)

{

case 'A' :

dummy=9;

break;

case 'B' :

if (*foo != 23)

bar (foo,*foo+1);

break;

case 'C' :

if (*foo != 79)

bar(foo,*foo);

break;

case 'D' : /* this case generates incorrect code */

if (*foo != 0) /* the compiler assumes foo to be in */

bar (foo,*foo-1); /* the same segment as the last */

break; /* data item accessed */

case 'H' :

dummy=3;

case 'I' :

dummy=4;

case 'J' :

break;

}

else

switch (dummy)

{

case '!' :

if (*foo != 0)

bar(foo,*foo-1);

break;

default :

break;

}

}

The following is part of the .COD listing created by the compiler when

you use the /Fc switch:

CONST SEGMENT

$T20001 DW SEG _foo

$T20002 DW SEG _dummy

;|*** case 'C' :

;|*** if (*foo != 79)

; Line 17

*** 00006e 8e 06 00 00 mov es,$T20001

*** 000072 26 c4 1e 00 00 les bx,DWORD PTR es:_foo

.

.

.

;|*** break;

;|*** case 'D' :

;|*** if (*foo != 0)

; Line 21

*** 00008c 26 c4 1e 00 00 les bx,DWORD PTR es:_foo

*** 000091 26 8b 37 mov si,WORD PTR es:[bx]

*** 000094 0b f6 or si,si

*** 000096 74 37 je $SD127

In case 'D', the segment address of _foo is not loaded into ES with a

mov instruction as in case 'C'. Thus _foo is incorrectly assumed to be

within the same data segment as "dummy", the previously operated upon

data item from the switch statement.