Re: Counter intuitively, asserts hurt gcc static dataflow analysis.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 09/05/18 12:31, Jonathan Wakely wrote:
> On 9 May 2018 at 11:13, David Brown wrote:
>> On 09/05/18 10:35, Jonathan Wakely wrote:
>>> On 4 May 2018 at 14:34, Segher Boessenkool wrote:
>>>> On Fri, May 04, 2018 at 03:16:14PM +0200, Mason wrote:
>>>>> On 04/05/2018 01:03, John Carter wrote:
>>>>>
>>>>>> But compile with ...
>>>>>> gcc  -O3 -W -Wall -Wextra -o a a.c
>>>>>> ...now results in NO warnings!
>>>>>>
>>>>>> ie. Although gcc _knows_ the assert  _will_ trigger at run time... it can't
>>>>>> tell me at compile time anymore.
>>>>>>
>>>>>> ie. Counter intuitively, adding asserts and error checks to my code has
>>>>>> made me less safe.
>>>>>
>>>>> In the first version, gcc inlines the function call, which enables
>>>>> further analysis. In the second version, the assert() call makes
>>>>> gcc decide not to inline the function call, thus later analysis passes
>>>>> are no longer able to spot the out-of-bounds access.
>>>>
>>>> No, that's not it.  In the second version there *is* no out of bounds
>>>> access!
>>>
>>> Right, the assert means that if the access would have been out of
>>> bounds the program terminates. So (when NDEBUG is not defined) it's
>>> impossible to reach the array access with an index >= 4.
>>>
>>> It doesn't hurt GCC's analysis, it just changes the program, and the
>>> analysis works on the new program.
>>>
>>
>>
>> What you might want here is a smarter assert:
>>
>> extern void __attribute__((error("Smart assert always failed")))
>>     __smartAssertAlwaysFail(void);
>>
>> #define smart_assert(x) do { \
>>     if (__builtin_constant_p(x)) { \
>>         if (!(x)) __smartAssertAlwaysFail(); \
>>     } else { \
>>         assert(x); \
>>     }
>>
>>
>> I use something similar for assertions in some of my embedded code (I
>> don't use normal asserts, because there is no output or way to exit the
>> program).
>>
>> I am sure something related could be put in the normal assert macro -
>> perhaps with a warning rather than an error.
> 
> IIUC __attribute__((warning("..."))) requires linking to an extern
> function, which might not be desirable in the general case for assert.
> 

Can you not use this?

static void __attribute__((warning("Smart assert always failed")))
     __smartAssertAlwaysFail(void) {}


(In the case of the error, I see it as an advantage that the error
function is not defined and will also give a linker error if I somehow
manage to compile code with the call left in.)




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux