Miscompilation with "-fpeel-loops" and -O{2,3,s}

Marcin Mirosław marcin at mejor.pl
Tue Oct 22 18:17:42 MSK 2013


W dniu 22.10.2013 16:08, Michael Tokarev pisze:
> 22.10.2013 17:44, Michael Tokarev wrote:
>> 22.10.2013 14:11, Marcin Mirosław wrote:
>>> Hi!
>>> I'm not sure if it's problem inside udns or inside gcc. I'm starting to
>>> ask here about it, if it's not problem in udns I'll look for help on gcc
>>> mailing list.
>>> I've noticed that compiling udns-0.2 using "-fpeel-loops" optimalization
>>> (togoether with -O2, -O3 or -Os) build executable which doesn't works
>>> correctly.
>>> Without -fpeel-loops:
>>> $ ./rblcheck -s rbl.mejor.pl 88.198.102.195 ; echo  $?
>>> 88.198.102.195 is listed by rbl.mejor.pl: 127.0.1.1
>>> 100
>>>
>>> with -fpeel-loops:
>>> $ ./rblcheck -s rbl.mejor.pl 88.198.102.195 ; echo $?
>>> 0
>>
>> Wow.
>>
>> I tried to reproduce, but my gcc (debian 4.7.2) produces a working
>> binary when compiled with -fpeel-loops -O2.
> 
> I reproduced it on debian with gcc-4.7.2 on second attempt.
> 
> It miscompiles dns_timeouts() function, choking on qlist_first(), probably
> the same way as clang produces a warning about use-after-free in another
> function which uses qlist_first() in a similar manner.
> 
> Here's the simplified code:
> 
>   q = qlist_first(&ctx->dnsc_qactive);
>   do {
>     if (q->dnsq_deadline > now) /* first non-expired query */
>       break;
>     else
>       /* process expired deadline */
>       dns_send(ctx, q, now);
>   } while((q = qlist_first(&ctx->dnsc_qactive)) != NULL);
> 
> qlist_first() is an inline function which, obviously, picks a first entry
> from the given list.  dns_send() will move the given entry to the end of
> this list, and this function is not inline.  It looks like the compiler
> does not see this and "thinks" that this list can't be modified outside
> of this function (in particular, within dns_send()), so in our use case
> it "thinks" that second qlist_first() can be optimized out, so the loop
> body is executed only once, but it should be done 2 times.
> 
> I wonder if it is possible to tell the compiler that dns_send() will modify
> the list in question...
I have no idea... It's beyond of my knowledge. Maybe it can be bring on
gcc mailinglist?

Marcin


More information about the udns mailing list