This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Question regarding C code generation for a compound condition
- From: Andrew Haley <aph at redhat dot com>
- To: gcc-help at gcc dot gnu dot org
- Date: Tue, 07 Jun 2011 15:00:59 +0100
- Subject: Re: Question regarding C code generation for a compound condition
- References: <BANLkTikAv5qznKey=OwVs5hNBKqiaOPGrA@mail.gmail.com>
On 06/07/2011 02:38 PM, Albert ARIBAUD wrote:
> First of all, apologies if this is not the right list, or the correct
> way, to ask -- just point me in the right direction.
>
> We have encountered a weird case of gcc C code generation when
> compiling an if statement with a compound condition under -Os -O2; we
> suspect that the generated code is wrong, and we would like to make
> sure before we report a compiler bug...
>
> The code is as follows:
>
> -------------------------------------------
> #include <stdio.h>
>
> struct fields {
> char a;
> char b;
> };
>
>
> struct fields *g;
>
> void test_function(void)
> {
>
> if ( (g->a==0) || (g==NULL) )
> {
> g->b = 0;
> return;
> }
>
> g->b = 10;
>
> return;
>
> }
> -------------------------------------------
>
> Granted, the way the condition is written is not valid, as the
> evaluation will be done left to right, causing a dereference of g
> before testing it against NULL -- the right order should be "(g==NULL)
> || (g->a==0)", with short-circuit ensuring g->a is only evaluated if g
> != NULL.
>
> However, even with this admittedly bad order, we would expect both
> sides of the '||' expression to be generated; however, only the left
> side is, both with an ARM or and x86 backend as an objdump extract
> shows:
That's correct. The dereference of g in (g->a==0) with g == NULL
invokes undefined behaviour. In the case of undefined behaviour, the
compiler is entitled to do anything, which, obviously, includes not
testing g==NULL.
Andrew.