[net.bugs] C compiler trivium

jas@rtech.UUCP (05/23/86)

Those with pcc-based C compilers may be surprised by the output
of the following program:

int x;

main()

{
    int *ip = &x;

    switch( (int) ip )
    {
      case &x:
	printf( "x\n" );
	break;
    
      default:
	printf( "other\n" );
	break;
    }
    exit( 0 );
}

This compiles without a complaint on a 3B5 running System V, a Microvax II
running Ultrix, and a CCI Power 6 running CCI's 4.2 port.  The output
is "other".  For a clue to what's going on, add a second global int 'y',
and insert its address as another case in the switch.

Jim Shankland

..!ucbvax!mtxinu!\
                  rtech!jas
 ..!ihnp4!cpsc6a!/

greg@utcsri.UUCP (Gregory Smith) (05/26/86)

In article <271@rtech.UUCP> jas@rtech.UUCP writes:
>Those with pcc-based C compilers may be surprised by the output
>of the following program:
>int x;
>main()
>{    int *ip = &x;
>    switch( (int) ip )
>    {
>      case &x:	printf( "x\n" );	break;
>      default: printf( "other\n" );	break;
>    }
>    exit( 0 );
>}
>This compiles without a complaint on a 3B5 running System V, a Microvax II
>running Ultrix, and a CCI Power 6 running CCI's 4.2 port.  The output
>is "other".  For a clue to what's going on, add a second global int 'y',
>and insert its address as another case in the switch.
>
>Jim Shankland

An ICON node in the compiler ( meaning a node containing a constant )
can contain a static address as well - it contains an integer constant, and
another integer which is used to specify a symbol table entry (or internal
label # ). Thus '&x' reduces to a node containing '0' and a reference to x.
'&y+3' will create a node containing '12' and a reference to y (assuming
sizeof(y)==4 ). The 'add-a-case' subroutine forgets to check that no
variable name is involved in the ICON, so 'case &x:' is the same as 'case 0:'
( or indeed, 'case &y:' ):
-------------------------------
addcase(p) NODE *p; { /* add case to switch */

	p = optim( p );  /* change enum to ints */
	if( p->in.op != ICON ){
		uerror( "non-constant case expression");
		return;
		}
-------------------------------
The condition for the 'if' clause should be

	if( p->in.op != ICON || p->tn.rval != NONAME ){

This is about line 850 in cgram.y - actual linage may vary.
I haven't tested this fix, but it *looks* simple ... :-)
Also, it seems to me there should be a 'tfree(p);' before the 'return;'
above - and in the following if-then-error which checks that the case
is in a switch. Messy, messy.
K & R does prohibit `case &x:', BTW.

( Gee, I sure hope I haven't published proprietary bugs... )

-- 
"We demand rigidly defined areas of doubt and uncertainty!" - Vroomfondel
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg