[gnu.gcc.bug] gcc 1.32 has problems with conditional lvalues

schmidt%crimee.ics.uci.edu@PARIS.ICS.UCI.EDU ("Douglas C. Schmidt") (01/02/89)

Bug Report for GCC:
-------------------
Problem :  I believe the following code demonstrates a bug with gcc (
and g++ ) handling of lvalued conditional expressions, i.e.:

	 ( a ? b : c ) = d;

where b, c, and d are pointers.  The problem occurs with and without
-O, I've included some assembly code output ( derived from a -O
compilation ) which illustrates part of the problem.

If the a.out file is executed it either gets a bus error, or produces
incorrect output.  This occurs on either the Sun 3 or Sun 4, using
either gcc 1.32 or g++ 1.32.

Doug

1.) Version : gcc 1.32
-----------

2.) Input Program :
-----------------
struct Tree {
   int          Item;
   struct Tree *Left;
   struct Tree *Right;
};

struct Tree *New_Tree ( int i ) {
   struct Tree *Temp = ( struct Tree * ) malloc ( sizeof ( struct Tree ) );
   Temp->Item = i;
   Temp->Left = Temp->Right = 0;
   return ( Temp );
}

struct Tree *Insert ( struct Tree *T, int i ) {
   if ( ! T ) {
      T = New_Tree ( i );
   }
   else {
      struct Tree *Ptr = T;
      struct Tree *Temp;
      
      do {
         Temp = Ptr;
      } while ( Ptr = Ptr->Item < i ? Ptr->Right : Ptr->Left );

      Ptr = New_Tree ( i );

      /* gcc seems to generate faulty code here */

      ( Temp->Item < i ? Temp->Right : Temp->Left ) = Ptr;
   }
   return ( T );
}

void Print ( struct Tree *T ) {
   if ( T ) {
      Print ( T->Left );
      printf ( "%d\n", T->Item );
      Print ( T->Right );
   }
}

main ( int argc, char *argv [ ] ) {
   struct Tree *T = 0;
   int i;

   for ( i = atoi ( argv [ 1 ] ); --i >= 0; ) {
      T = Insert ( T, i );
   }

   Print ( T ); /* should print out ( i - 0 ) thru 0. */
}

3.) Command Used : gcc -O
----------------

4.) Files used :
--------------
		tm.h          -> tm-sparc.h
		md            -> sparc.md
      config.h      -> xm-sunos4.h
      aux-output.c  -> output-sparc.c
      
5.) Machine(s) used :
-------------------
   Sun 4 running Sun4.0

6.) Assembly output for Sun 3 :
------------------------

#NO_APP
.text
	.even
.globl _New_Tree
_New_Tree:
	link a6,#0
	pea 12:w
	jbsr _malloc
	movel d0,a0
	movel a6@(8),a0@
	clrl a0@(8)
	clrl a0@(4)
	unlk a6
	rts
	.even
.globl _Insert
_Insert:
	link a6,#0
	moveml #0x3820,sp@-
	movel a6@(8),d2
	movel a6@(12),d3
	tstl d2
	jne L3
	movel d3,sp@-
	jbsr _New_Tree
	movel d0,d2
	jra L4
L3:
	movel d2,a0
L5:
	movel a0,a2
	cmpl a2@,d3
	jle L8
	movel a0@(8),a0
	jra L9
L8:
	movel a0@(4),a0
L9:
	tstl a0
	jne L5
	movel d3,sp@-
	jbsr _New_Tree
	movel d0,a0
	cmpl a2@,d3
	jle L10
	movel a0,d4
	movel d4,a2@(8)
	jra L4
L10:
	movel d4,a2@(4) /* note that d4 is used, but not set on the jle L10 jump */
L4:
	movel d2,d0
	moveml a6@(-16),#0x41c
	unlk a6
	rts
LC0:
	.ascii "%d\12\0"
	.even
.globl _Print
_Print:
	link a6,#0
	moveml #0x30,sp@-
	movel a6@(8),a3
	tstl a3
	jeq L13
	movel a3@(4),sp@-
	lea _Print,a2
	jbsr a2@
	movel a3@,sp@-
	pea LC0
	jbsr _printf
	movel a3@(8),sp@-
	jbsr a2@
L13:
	moveml a6@(-8),#0xc00
	unlk a6
	rts
	.even
.globl _main
_main:
	link a6,#0
	moveml #0x3000,sp@-
	clrl d3
	movel a6@(12),a0
	movel a0@(4),sp@-
	jbsr _atoi
	movel d0,d2
	addqw #4,sp
	jra L15
L18:
	movel d2,sp@-
	movel d3,sp@-
	jbsr _Insert
	movel d0,d3
	addqw #8,sp
L15:
	subql #1,d2
	jpl L18
	movel d3,sp@-
	jbsr _Print
	moveml a6@(-8),#0xc
	unlk a6
	rts