Hi, On Mon, Jul 25, 2011 at 8:41 PM, Ian Lance Taylor <iant@xxxxxxxxxx> wrote: > Arnaud Lacombe <lacombar@xxxxxxxxx> writes: > >> gcc will only emits the warning at -Os. It seems to me that the >> resulting code clearly ends-up testing an uninitialized value, ie. >> assuming the following test-case: >> >> extern void *e(void); >> extern void *f(void); >> extern void g(void); >> >> void fn(void) >> { >> void *b, *a; >> >> a = e(); >> if (a != 0) >> b = f(); >> if (a != 0 && b != 0) >> g(); >> } >> >> ... >> >> It seems gcc transforms the conditional from: >> >> if (a != NULL && b != NULL) ... >> >> to >> >> if (b != NULL && a != NULL) ... >> >> In which case the warning is fully valid. I'm not sure what's the C >> standard guarantee in term of conditional test order. gcc 4.7.0 has >> the same behavior. > > Not quite. C guarantees that && is executed in order. In this case gcc > is generating > > a = e(); > if (a != NULL) > b = f(); > if (a != NULL & b != NULL) > g(); > > Note the change from && to & in the last conditional. I've got some trouble linking the final optimized tree with the code generated. That is, the final tree (generated by -fdump-tree-all) is: foo () { void * b; void * a; _Bool D.1993; _Bool D.1992; _Bool D.1991; <bb 2>: a_2 = e (); if (a_2 != 0B) goto <bb 3>; else goto <bb 4>; <bb 3>: b_4 = f (); <bb 4>: # b_1 = PHI <b_3(D)(2), b_4(3)> D.1991_5 = a_2 != 0B; D.1992_6 = b_1 != 0B; D.1993_7 = D.1992_6 & D.1991_5; if (D.1993_7 != 0) goto <bb 5>; else goto <bb 6>; <bb 5>: g (); [tail call] <bb 6>: return; } but the code generated seem to test %esi (`b', potentially uninitialized) before %ebx (`a'). Am I still missing something ? Thanks, - Arnaud