[cfe-dev] Incongruency in __builtin_constant_p with pointer argument

Eli Friedman eli.friedman at gmail.com
Tue May 3 09:04:39 PDT 2011


On Tue, May 3, 2011 at 12:17 AM, Abramo Bagnara
<abramo.bagnara at gmail.com> wrote:
> Il 03/05/2011 08:44, Eli Friedman ha scritto:
>> On Mon, May 2, 2011 at 11:13 PM, Abramo Bagnara
>> <abramo.bagnara at gmail.com> wrote:
>>> Il 27/04/2011 23:30, Abramo Bagnara ha scritto:
>>>>
>>>> $ cat t.c
>>>> typedef const int * ptr;
>>>>
>>>> const int i = 0;
>>>> const ptr p = &i;
>>>>
>>>> int a[__builtin_constant_p(i) ? 1 : -1];
>>>> int b[__builtin_constant_p(p) ? 1 : -1];
>>>>
>>>> $ clang -S t.c
>>>> t.c:7:7: error: 'b' declared as an array with a negative size
>>>> int b[__builtin_constant_p(p) ? 1 : -1];
>>>>       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> 1 error generated.
>>>> $ gcc -S t.c
>>>> t.c:6: error: size of array ‘a’ is negative
>>>> t.c:7: error: size of array ‘b’ is negative
>>>>
>>>> I'm perfectly fine with the fact that clang treats const typed variable
>>>> as evaluatable constant (although gcc don't), but this should be the
>>>> same for both cases.
>>>>
>>>> The fix is trivial and I'll commit it myself, but before I'd like to
>>>> know if it is preferred that __builtin_constant_p returns true for both
>>>> or false for both.
>>>
>>> Ping.
>>>
>>> We have also other fixes for clang constant expr evaluator, but we need
>>> to know the wanted policy. Currently it is not clear what is wishable
>>> and implementation is often incongruent.
>>>
>>> Also it need to be decided if __builtin_constant_p is tied to constant
>>> expr evaluator or not, i.e. if the value returned by this builtin should
>>> be the same of constant expr evaluator once taken in account the side
>>> effects.
>>
>> Have you read http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins
>> ?
>
> Yes, of course.
>
>  You're trying to impose semantics on __builtin_constant_p that
>> aren't part of its definition.  Currently, the results just sort of
>> fall out of whatever the AST-level constant folder happens to know how
>> to fold.  That isn't a guarantee, though; see also
>> http://llvm.org/bugs/show_bug.cgi?id=4898.
>
> Note that I'm not currently trying to impose any semantics, just to make
> implementation congruent with wished policy.
> To do this I need to know it, whatever it is ;-)
>
> Take this example:
>
> $ cat t.c
>
> const int a = 0;
> const char * const b = "p";
>
> char w[__builtin_constant_p(a) ? 1 : -1];
> char x[__builtin_constant_p(b) ? 1 : -1];
> char y[__builtin_constant_p("p") ? 1 : -1];
> char z[__builtin_constant_p(&a) ? 1 : -1];
> abramo at igor:~$ clang -S t.c
> t.c:6:8: error: 'x' declared as an array with a negative size
> char x[__builtin_constant_p(b) ? 1 : -1];
>       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> t.c:7:8: error: 'y' declared as an array with a negative size
> char y[__builtin_constant_p("p") ? 1 : -1];
>       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 2 errors generated.
>
> The 'w' line show that a constant variabile is treated as a foldable
> constant, but the 'x' line contraddicts that.
>
> One may think that pointer values are never treated as foldable
> constants, but then 'z' line is not explainable.
>
> Once decided which is the policy, to fix all that is easy, but now
> things are somewhat confused.

For stuff inside static intializers in particular, we should probably
try to be consistent with gcc, I guess.  Granted, there isn't much
code that does things like that...

-Eli




More information about the cfe-dev mailing list