[cfe-users] __builtin_constant_p(), __builtin_expect() and __builtin_types_compatible_p() and __has_builtin()
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()
> 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()
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()
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?
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?
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()
> 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