Counter intuitively, asserts hurt gcc static dataflow analysis.

John Carter john.carter@taitradio.com
Thu May 10 23:27:00 GMT 2018


Sadly this variant is a C only variant... Anyone know how to do something
cunning in C++17?

On Fri, May 11, 2018 at 10:48 AM, John Carter <john.carter@taitradio.com>
wrote:

> Here's a variant that works even at  -O3, the trick seems to be to combine
> __builtin_choose_expr with __builtin_constant_p
>
> https://godbolt.org/g/pQeRvE
>
> #include <stdlib.h>
>
> void assertFailure( void) __attribute__((warning("Compile time assertion
> failure")));
>
> int z(void);
>
>
> int main()
> {
>    int j;
>
>    for(  j=0;j<4;j++) {
>       if( z()) break;
>    }
>
>    __builtin_choose_expr( __builtin_constant_p(!(j < 4)),
>                           ((!(j < 4)) ? assertFailure() : (void)0),
>                           ((!(j < 4)) ? abort() : (void)0));
>
>    return 0;
> }
>
>
> On Fri, May 11, 2018 at 10:37 AM, Marc Glisse <marc.glisse@inria.fr>
> wrote:
>
>> On Fri, 11 May 2018, John Carter wrote:
>>
>> Here is an example where gcc's optimizers go, ahhh, strange....
>>>
>>
>> There is nothing strange about it. You are trying to abuse
>> __builtin_constant_p for warnings when it is meant for optimization. Linux
>> kernel developers had the same issue.
>>
>> Try play with the optimizations settings on godbolt.
>>> https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(j:1,lang
>>> :___c,source:'%23include+%3Cstdlib.h%3E%0A%0Avoid+assertFail
>>> ure(+void)+__attribute__((warning(%22Compile+time+assertion+
>>> failure%22)))%3B%0A%0Aint+z(void)%3B%0A%0A%0Aint+main()%
>>> 0A%7B%0A+++int+j%3B%0A%0A+++for(++j%3D0%3Bj%3C4%3Bj%2B%2B)
>>> +%7B%0A++++++if(+z())+break%3B%0A+++%7D%0A+++%0A+++if(+__
>>> builtin_constant_p(!!(j+%3C+4)))%0A+++%7B%0A++++++if(!!(j+%
>>> 3C+4))%0A+++++++++assertFailure()%3B%0A+++%7D%0A+++else%0A++
>>> ++++if(+!!(j+%3C+4))%0A+++++++++abort()%3B%0A+++%0A+++
>>> return+0%3B%0A%7D%0A'),l:'5',n:'0',o:'C+source+%231',t:'0')
>>> ),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compi
>>> ler:cg81,filters:(b:'0',binary:'1',commentOnly:'0',demangle:
>>> '0',directives:'0',execute:'1',intel:'0',trim:'0'),lang:___
>>> c,libs:!(),options:'-Os+-Wall',source:1),l:'5',n:'0',o:'x86-
>>> 64+gcc+8.1+(Editor+%231,+Compiler+%231)+C',t:'0')),k:
>>> 50,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4
>>>
>>> On -Os it behaves sane, on -O2 or higher it calls assertFailure.
>>>
>>> #include <stdlib.h>
>>>
>>> void assertFailure( void) __attribute__((warning("Compile time assertion
>>> failure")));
>>>
>>> int z(void);
>>>
>>>
>>> int main()
>>> {
>>>   int j;
>>>
>>>   for(  j=0;j<4;j++) {
>>>      if( z()) break;
>>>   }
>>>
>>>   if( __builtin_constant_p(!(j < 4)))
>>>
>>
>> gcc duplicates this piece of code, one version if we came through "break"
>> and one version if the loop completed. For each version, the value of j<4
>> is known at compile-time and optimized as such. For optimization purposes,
>> this is perfect.
>>
>>
>>   {
>>>      if(!(j < 4))
>>>         assertFailure();
>>>   }
>>>   else
>>>      if( !(j < 4))
>>>         abort();
>>>
>>>   return 0;
>>> }
>>>
>>
>> --
>> Marc Glisse
>>
>
>
>
> --
> John Carter
> Phone : (64)(3) 358 6639
> Tait Electronics
> PO Box 1645 Christchurch
> New Zealand
>
>


-- 
John Carter
Phone : (64)(3) 358 6639
Tait Electronics
PO Box 1645 Christchurch
New Zealand

-- 
This Communication is Confidential. We only send and receive email on the

basis of the terms set out at www.taitradio.com/email_disclaimer 
<http://www.taitradio.com/email_disclaimer>



More information about the Gcc-help mailing list