[cfe-users] __builtin_constant_p(), __builtin_expect() and __builtin_types_compatible_p() and __has_builtin()

2019-08-09 Thread Chris Hall via cfe-users


I find that __builtin_constant_p() works as expected, but 
__has_builtin(constant_p) denies it !


Similarly __builtin_expect() and __builtin_types_compatible_p() !

Can I just assume these are all supported by all version of clang ?

Chris
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] __builtin_constant_p(), __builtin_expect() and __builtin_types_compatible_p() and __has_builtin()

2019-08-09 Thread Matthew Fernandez via cfe-users

> On Aug 9, 2019, at 05:23, Chris Hall via cfe-users  
> wrote:
> 
> 
> I find that __builtin_constant_p() works as expected, but 
> __has_builtin(constant_p) denies it !

I believe you need __has_builtin(__builtin_constant_p).

> 
> Similarly __builtin_expect() and __builtin_types_compatible_p() !
> 
> Can I just assume these are all supported by all version of clang ?
> 
> Chris
> ___
> cfe-users mailing list
> cfe-users@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users

___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] __builtin_constant_p(), __builtin_expect() and __builtin_types_compatible_p() and __has_builtin()

2019-08-09 Thread Chris Hall via cfe-users

On 09/08/2019 15:00, Matthew Fernandez wrote:

On Aug 9, 2019, at 05:23, Chris Hall via cfe-users wrote:

I find that __builtin_constant_p() works as expected, but 
__has_builtin(constant_p) denies it !



I believe you need __has_builtin(__builtin_constant_p).


Ah :-(  So you do... sorry... I have no idea why I thought otherwise :-(


Similarly __builtin_expect() and __builtin_types_compatible_p() !


Except that __has_builtin(__builtin_types_compatible_p) also denies it.

   #include 

   int
   main(int argc, char* argv[])
   {
     printf("__has_builtin(__builtin_types_compatible_p)=%d\n"
  "__builtin_types_compatible_p(int, int)=%d\n"
  "__builtin_types_compatible_p(int, long)=%d\n",
     __has_builtin(__builtin_types_compatible_p),
   __builtin_types_compatible_p(int, int),
   __builtin_types_compatible_p(int, long)) ;
   }

outputs:

   __has_builtin(__builtin_types_compatible_p)=0
   __builtin_types_compatible_p(int, int)=1
   __builtin_types_compatible_p(int, long)=0

I hope I haven't missed something blindingly obvious this time.

Thanks,

Chris

___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] __builtin_constant_p(), __builtin_expect() and __builtin_types_compatible_p() and __has_builtin()

2019-08-09 Thread Richard Smith via cfe-users
On Fri, 9 Aug 2019 at 10:32, Chris Hall via cfe-users <
cfe-users@lists.llvm.org> wrote:

> On 09/08/2019 15:00, Matthew Fernandez wrote:
> >> On Aug 9, 2019, at 05:23, Chris Hall via cfe-users wrote:
> >>
> >> I find that __builtin_constant_p() works as expected, but
> >> __has_builtin(constant_p) denies it !
>
> > I believe you need __has_builtin(__builtin_constant_p).
>
> Ah :-(  So you do... sorry... I have no idea why I thought otherwise :-(
>
> >> Similarly __builtin_expect() and __builtin_types_compatible_p() !
>
> Except that __has_builtin(__builtin_types_compatible_p) also denies it.
>
> #include 
>
> int
> main(int argc, char* argv[])
> {
>   printf("__has_builtin(__builtin_types_compatible_p)=%d\n"
>"__builtin_types_compatible_p(int, int)=%d\n"
>"__builtin_types_compatible_p(int, long)=%d\n",
>   __has_builtin(__builtin_types_compatible_p),
> __builtin_types_compatible_p(int, int),
> __builtin_types_compatible_p(int, long)) ;
> }
>
> outputs:
>
> __has_builtin(__builtin_types_compatible_p)=0
> __builtin_types_compatible_p(int, int)=1
> __builtin_types_compatible_p(int, long)=0
>
> I hope I haven't missed something blindingly obvious this time.
>

This is a historical accident.

__has_builtin detects builtin *functions*. We also have a bunch of things
that start with __builtin and look somewhat like functions, but that take
types as arguments so can't actually be functions -- instead, they're
keywords with custom parsing rules. __has_builtin doesn't detect those
(because they're not builtin functions).

We've fixed this for such things we added recently, such as
__builtin_bit_cast and __builtin_FILE, but the older ones like
__builtin_types_compatible_p and __builtin_choose_expr and
__builtin_offsetof are unfortunately not detectable by __has_builtin.

There is another way to detect these: use
!__is_identifier(__builtin_types_compatible_p). That will evaluate to 1
whenever __builtin_types_compatible_p is not a valid identifier (because
it's a keyword) -- that is, whenever the feature is available. However,
__is_identifier was added in April 2014, and nearly all the builtins that
__has_builtin can't detect are older than that. So this technique isn't
really useful.

In practice, every version of Clang from the past 10 years supports
__builtin_types_compatible_p (in C mode). So you can just assume it exists.
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Should clang++ -g produce debugging info for all types?

2019-08-09 Thread Bob Eastbrook via cfe-users
On Mon, Aug 5, 2019 at 1:36 PM David Blaikie  wrote:

> Does it work with gdb?

It works with gdb.  More info:

g++ & gdb -- works, even without debuginfo for libstdc++
clang++ & gdb -- works
g++ & lldb -- works
clang++ & lldb -- fails

I now notice these warnings in lldb after installing the debuginfo packages:

warning: (x86_64) /lib64/libstdc++.so.6 unsupported DW_FORM values:
0x1f20 0x1f21
warning: (x86_64) /lib64/libgcc_s.so.1 unsupported DW_FORM values: 0x1f20 0x1f21

I searched the web for details on that error, but came up empty.
Could it be that the debuginfo packages are just not compatible with
lldb?

> I'd try gdb + gcc + binutils ld (or gold) + libstdc++ (use std::fstream as an 
> example of something that gcc will home to the libstdc++ debug info - 
> dwarfdump your executable and you'll see it doesn't contain the definition of 
> basic_fstream, but verify the debugger can still render the full definition). 
> If that works, swap out various parts of that & see where it falls apart.

Good strategy.  I don't quite have the hang of dwarfdump yet though,
but I'll continue to investigate.
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] Should clang++ -g produce debugging info for all types?

2019-08-09 Thread David Blaikie via cfe-users
On Fri, Aug 9, 2019 at 6:03 PM Bob Eastbrook 
wrote:

> On Mon, Aug 5, 2019 at 1:36 PM David Blaikie  wrote:
>
> > Does it work with gdb?
>
> It works with gdb.  More info:
>
> g++ & gdb -- works, even without debuginfo for libstdc++
>

^ for std::string I'd expect this. For std::fstream, I expect you'd see the
same problem/failure (gcc and clang both rely on fstream being homed in the
standard library's debug info (because of vtables/key functions), but clang
takes it a step further and does this for std::string too (because of
template explicit instantiation decl/def))


> clang++ & gdb -- works
> g++ & lldb -- works
>

^ again, I expect that would fail with std::fstream, demonstrating that the
same problem exists for both clang and GCC, just clang takes it a bit
further - but it's not fundamentally different between the two.


> clang++ & lldb -- fails
>
> I now notice these warnings in lldb after installing the debuginfo
> packages:
>
> warning: (x86_64) /lib64/libstdc++.so.6 unsupported DW_FORM values:
> 0x1f20 0x1f21
> warning: (x86_64) /lib64/libgcc_s.so.1 unsupported DW_FORM values: 0x1f20
> 0x1f21
>
> I searched the web for details on that error, but came up empty.
> Could it be that the debuginfo packages are just not compatible with
> lldb?
>

Ooh, yeah, that's possible/likely. Unknown forms can't be ignored because
forms dictate the encoding, so without recognizing the form, the DWARF
can't be parsed (unknown /attributes/ using known forms are fine - because
they can be parsed and the values ignored).

Yeah, looks like 1f20 (DW_FORM_GNU_ref_alt) and 1f21 (DW_FORM_GNU_strp_alt)
are results of the 'dwz' tool that compacts DWARF debug info.

Not sure if it'd be enough to teach lldb how to parse but ignore any
attribute using these forms - I would guess not, I suspect that would
result in holes in the debug info where these forms are used. So you'd
probably have to modify/fix/patch lldb to actually be able to understand
these forms - which might not be too hard. Hmm, nope, probably fairly
involved, since it means reading a new/different file (judging by this
patch and the link to the DWARF standards proposal in it:
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20150518/277186.html
 ).

Summary:
Yeah, short of making some relatively significant changes to lldb, I think
you'll probably just have to stick with larger debug info by using
-fstandalone-debug, since the debug info provided by your distribution uses
GNU extensions that lldb doesn't currently support. :/


>
> > I'd try gdb + gcc + binutils ld (or gold) + libstdc++ (use std::fstream
> as an example of something that gcc will home to the libstdc++ debug info -
> dwarfdump your executable and you'll see it doesn't contain the definition
> of basic_fstream, but verify the debugger can still render the full
> definition). If that works, swap out various parts of that & see where it
> falls apart.
>
> Good strategy.  I don't quite have the hang of dwarfdump yet though,
> but I'll continue to investigate.
>
___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users


Re: [cfe-users] __builtin_constant_p(), __builtin_expect() and __builtin_types_compatible_p() and __has_builtin()

2019-08-09 Thread Matthew Fernandez via cfe-users

> On Aug 9, 2019, at 14:58, Richard Smith via cfe-users 
>  wrote:
> 
> On Fri, 9 Aug 2019 at 10:32, Chris Hall via cfe-users 
> mailto:cfe-users@lists.llvm.org>> wrote:
> On 09/08/2019 15:00, Matthew Fernandez wrote:
> >> On Aug 9, 2019, at 05:23, Chris Hall via cfe-users wrote:
> >>
> >> I find that __builtin_constant_p() works as expected, but 
> >> __has_builtin(constant_p) denies it !
> 
> > I believe you need __has_builtin(__builtin_constant_p).
> 
> Ah :-(  So you do... sorry... I have no idea why I thought otherwise :-(
> 
> >> Similarly __builtin_expect() and __builtin_types_compatible_p() !
> 
> Except that __has_builtin(__builtin_types_compatible_p) also denies it.
> 
> #include 
> 
> int
> main(int argc, char* argv[])
> {
>   printf("__has_builtin(__builtin_types_compatible_p)=%d\n"
>"__builtin_types_compatible_p(int, int)=%d\n"
>"__builtin_types_compatible_p(int, long)=%d\n",
>   __has_builtin(__builtin_types_compatible_p),
> __builtin_types_compatible_p(int, int),
> __builtin_types_compatible_p(int, long)) ;
> }
> 
> outputs:
> 
> __has_builtin(__builtin_types_compatible_p)=0
> __builtin_types_compatible_p(int, int)=1
> __builtin_types_compatible_p(int, long)=0
> 
> I hope I haven't missed something blindingly obvious this time.
> 
> This is a historical accident.
> 
> __has_builtin detects builtin *functions*. We also have a bunch of things 
> that start with __builtin and look somewhat like functions, but that take 
> types as arguments so can't actually be functions -- instead, they're 
> keywords with custom parsing rules. __has_builtin doesn't detect those 
> (because they're not builtin functions).
> 
> We've fixed this for such things we added recently, such as 
> __builtin_bit_cast and __builtin_FILE, but the older ones like 
> __builtin_types_compatible_p and __builtin_choose_expr and __builtin_offsetof 
> are unfortunately not detectable by __has_builtin.
> 
> There is another way to detect these: use 
> !__is_identifier(__builtin_types_compatible_p). That will evaluate to 1 
> whenever __builtin_types_compatible_p is not a valid identifier (because it's 
> a keyword) -- that is, whenever the feature is available. However, 
> __is_identifier was added in April 2014, and nearly all the builtins that 
> __has_builtin can't detect are older than that. So this technique isn't 
> really useful.

This thread taught me something too, thanks :) The __is_identifier trick seems 
even more tricky to use than this implies. E.g. it returns true for 
__builtin_constant_p because that one is implemented as a function, as you 
describe. Does this mean to fully detect support for __builtin_foo I need 
something like `__has_builtin(foo) || __has_builtin(__builtin_foo) || 
!__is_identifier(__builtin_foo)`?

While we’re on this topic, are the semantics of __is_identifier just “is not a 
keyword”? I ask because even when it returns true for a __-prefixed symbol, 
it’s not an indication you can use it in user code because it’s still reserved 
for use by the implementation. In fact __is_identifier even returns true for 
itself, which I guess is technically correct.

> In practice, every version of Clang from the past 10 years supports 
> __builtin_types_compatible_p (in C mode). So you can just assume it exists.

This is what I do too, as it’s widely supported back to every reasonable 
version of GCC as well.___
cfe-users mailing list
cfe-users@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users