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