[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 Martin Sebor changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --- Comment #24 from Martin Sebor --- Committed in r277544. Unlike in Clang, arguments to the GCC __has_builtin operator are subject to macro expansion. Also unlike in Clang (as of today), in GCC __has_builtin (__is_aggregate) && __has_builtin (__builtin_launder) && __has_builtin (__builtin_offsetof) evaluates to non-zero.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #23 from Martin Sebor --- Author: msebor Date: Mon Oct 28 22:46:28 2019 New Revision: 277544 URL: https://gcc.gnu.org/viewcvs?rev=277544=gcc=rev Log: PR c/66970 - Add __has_builtin() macro gcc/ChangeLog: PR c/66970 * doc/cpp.texi (__has_builtin): Document. * doc/extend.texi (__builtin_frob_return_addr): Correct spelling. gcc/c/ChangeLog: PR c/66970 * c-decl.c (names_builtin_p): Define a new function. gcc/c-family/ChangeLog: PR c/66970 * c-common.c (c_common_nodes_and_builtins): Call c_define_builtins even when only preprocessing. * c-common.h (names_builtin_p): Declare new function. * c-lex.c (init_c_lex): Set has_builtin. (c_common_has_builtin): Define a new function. * c-ppoutput.c (init_pp_output): Set has_builtin. gcc/cp/ChangeLog: PR c/66970 * cp-objcp-common.c (names_builtin_p): Define new function. gcc/testsuite/ChangeLog: PR c/66970 * c-c++-common/cpp/has-builtin-2.c: New test. * c-c++-common/cpp/has-builtin-3.c: New test. * c-c++-common/cpp/has-builtin.c: New test. Added: trunk/gcc/testsuite/c-c++-common/cpp/has-builtin-2.c trunk/gcc/testsuite/c-c++-common/cpp/has-builtin-3.c trunk/gcc/testsuite/c-c++-common/cpp/has-builtin.c Modified: trunk/gcc/ChangeLog trunk/gcc/c-family/ChangeLog trunk/gcc/c-family/c-common.c trunk/gcc/c-family/c-common.h trunk/gcc/c-family/c-lex.c trunk/gcc/c-family/c-ppoutput.c trunk/gcc/c/ChangeLog trunk/gcc/c/c-decl.c trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-objcp-common.c trunk/gcc/doc/cpp.texi trunk/gcc/doc/extend.texi trunk/gcc/testsuite/ChangeLog trunk/libcpp/include/cpplib.h trunk/libcpp/init.c trunk/libcpp/macro.c trunk/libcpp/traditional.c
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 Martin Sebor changed: What|Removed |Added Keywords||patch Target Milestone|--- |10.0 --- Comment #22 from Martin Sebor --- Patch: https://gcc.gnu.org/ml/gcc-patches/2019-10/msg00062.html
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #21 from Jonathan Wakely --- Clang is changing __has_builtin so it recognizes all function-like built-ins, not just the ones starting with "__builtin_". See https://reviews.llvm.org/D66100 This means __has_builtin yields true for all of __is_aggregate, __builtin_launder and __builtin_offsetof.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 frankhb1989 at gmail dot com changed: What|Removed |Added CC||frankhb1989 at gmail dot com --- Comment #20 from frankhb1989 at gmail dot com --- (In reply to Jonathan Wakely from comment #11) > I hate that behaviour. Having to use !__is_identifier(__builtin_launder) is > confusing (and not just to me, but to developers of LLVM's own libc++, who > I've had to explain the problem to). > > But consistency with Clang is probably more important than making > __has_builtin behave sanely. What if breaking that insane compatibility? How does it make things worse? `__has_builtin` is expected to be OK even with false negative results (but surely not false positive ones). Is there any real examples showing that relying on something like `!__has_builtin(__builtin_offsetof)` necessary for the needs in practice? Note that there is already no warranty by the standard with the use of `__`, and I don't ever find reasons that things like `int __builtin_abort = 0;` should work besides the leaked implementation details. Such abuse seems not documented at all. Even such use is eventually guaranteed to work, the extent should be justified by `__is_identifier`, with nothing to do with the `__builtin_` prefix.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #19 from Allan Jensen --- (In reply to felix from comment #18) > So even if this feature is adopted as-is, it will necessitate some changes > in the documentation. And while I can sympathise with claims that this > behaviour is surprising, what are the alternatives? If keywords should count > as built-ins, should __has_builtin(sizeof) expand to 1? Should > __has_builtin(volatile)? No just keywords that begin with __builtin_..
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #18 from felix --- Proper built-ins are ordinary identifiers subject to ordinary name resolution and shadowing, so the 'keyword built-in' case is impossible. If you don't know if (or don't want to depend on the fact that) a given built-in is a keyword or an intrinsic function, `__has_builtin(x) || !__is_identifier(x)` should suffice. In a way, that detail is already exposed to user code: `int __builtin_abort = 0;` compiles, but `int __builtin_choose_expr = 0;` doesn't. The documentation doesn't mention this, however; keyword built-ins are actually documented as being functions in the manual, either explicitly or implicitly (by being listed alongside true intrinsic functions with no discriminating features). So even if this feature is adopted as-is, it will necessitate some changes in the documentation. And while I can sympathise with claims that this behaviour is surprising, what are the alternatives? If keywords should count as built-ins, should __has_builtin(sizeof) expand to 1? Should __has_builtin(volatile)?
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #17 from Jonathan Wakely --- (In reply to felix from comment #7) > I made the feature closely mimic The Other Compiler's behaviour: only > function built-ins are recognised. This includes generic functions like > __builtin_add_overflow and C library functions specially handled by the > front-end like printf (unless -fno-builtin is used), but excludes types like > __builtin_va_list and function-like constructs (implemented as keywords) > like __builtin_offsetof and __builtin_types_compatible_p. This is not so > much of a problem for them, since they also provide __has_feature(), > __has_extension() and __is_identifier() macros. The former has been > requested in PR 60512 and rejected; it may be reasonable to revisit the > issue. I still hate this nonsense. __builtin_offsetof is a keyword not a built-in, similar to __is_aggregate. But __builtin_launder is a built-in not a keyword, like __builtin_add_overflow. Given a built-in name, how on earth am I supposed to know how to detect it? How does a user know whether something is a "function built-in" or a "function-like construct"? #if __has_builtin(__is_aggregate) # if __is_identifier(__is_aggregate) # pragma message("__is_aggregate is a builtin and an identifier") # else # pragma message("__is_aggregate is a builtin but not an identifier") # endif #elif __is_identifier(__is_aggregate) # pragma message("__is_aggregate is not a builtin or a keyword") #else # pragma message("__is_aggregate is not a builtin but is a keyword") #endif #if __has_builtin(__builtin_launder) # if __is_identifier(__builtin_launder) # pragma message("__builtin_launder is a builtin and an identifier") # else # pragma message("__builtin_launder is a builtin but not an identifier") # endif #elif __is_identifier(__builtin_launder) # pragma message("__builtin_launder is not a builtin or a keyword") #else # pragma message("__builtin_launder is not a builtin but is a keyword") #endif #if __has_builtin(__builtin_offsetof) # if __is_identifier(__builtin_offsetof) # pragma message("__builtin_offsetof is a builtin and an identifier") # else # pragma message("__builtin_offsetof is a builtin but not an identifier") # endif #elif __is_identifier(__builtin_offsetof) # pragma message("__builtin_offsetof is not a builtin or a keyword") #else # pragma message("__builtin_offsetof is not a builtin but is a keyword") #endif __is_aggregate is not a builtin but is a keyword __builtin_launder is a builtin and an identifier __builtin_offsetof is not a builtin but is a keyword Anybody who thinks this is a clean way to detect built-ins hasn't actually had to use it.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #16 from Martin Sebor --- No progress yet but I agree and I'm still planning to work on it for GCC 10.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #15 from Nick Desaulniers --- Any progress Martin? Just to keep beating the dead horse... Forgetting other compilers for a minute, __has_builtin allows for feature detection which is much better than compiler version checks which are brittle and error prone. As new builtins get added over time, their existence can be checked in a cleaner way with __has_builtin.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #14 from Eric Gallager --- (In reply to Martin Sebor from comment #13) > Let me look into this request for GCC 10. It's GCC 10 now.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 Martin Sebor changed: What|Removed |Added Status|NEW |ASSIGNED CC||msebor at gcc dot gnu.org Assignee|unassigned at gcc dot gnu.org |msebor at gcc dot gnu.org --- Comment #13 from Martin Sebor --- Let me look into this request for GCC 10.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #12 from Eric Gallager --- (In reply to Jonathan Wakely from comment #11) > (In reply to felix from comment #7) > > I made the feature closely mimic The Other Compiler's behaviour: only > > function built-ins are recognised. This includes generic functions like > > __builtin_add_overflow and C library functions specially handled by the > > front-end like printf (unless -fno-builtin is used), but excludes types like > > __builtin_va_list and function-like constructs (implemented as keywords) > > like __builtin_offsetof and __builtin_types_compatible_p. This is not so > > much of a problem for them, since they also provide __has_feature(), > > __has_extension() and __is_identifier() macros. > > I hate that behaviour. Having to use !__is_identifier(__builtin_launder) is > confusing (and not just to me, but to developers of LLVM's own libc++, who > I've had to explain the problem to). > > But consistency with Clang is probably more important than making > __has_builtin behave sanely. maybe have a separate __sane_has_builtin? That way __has_builtin could still be compatible with clang, but there'd also be a sane alternative
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #11 from Jonathan Wakely --- (In reply to felix from comment #7) > I made the feature closely mimic The Other Compiler's behaviour: only > function built-ins are recognised. This includes generic functions like > __builtin_add_overflow and C library functions specially handled by the > front-end like printf (unless -fno-builtin is used), but excludes types like > __builtin_va_list and function-like constructs (implemented as keywords) > like __builtin_offsetof and __builtin_types_compatible_p. This is not so > much of a problem for them, since they also provide __has_feature(), > __has_extension() and __is_identifier() macros. I hate that behaviour. Having to use !__is_identifier(__builtin_launder) is confusing (and not just to me, but to developers of LLVM's own libc++, who I've had to explain the problem to). But consistency with Clang is probably more important than making __has_builtin behave sanely.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #10 from Eric Gallager --- (In reply to H. Peter Anvin from comment #9) > Can I please second this request? This would be extremely useful in the > Linux kernel, *and* it would be extremely useful in any code that for > whatever reason cannot depend on any particular build system. Well, it's already been seconded, but you can... seventh it? I dunno, I can't count.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 H. Peter Anvin changed: What|Removed |Added CC||hpa at zytor dot com --- Comment #9 from H. Peter Anvin --- Can I please second this request? This would be extremely useful in the Linux kernel, *and* it would be extremely useful in any code that for whatever reason cannot depend on any particular build system.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 Eric Gallager changed: What|Removed |Added CC||egallager at gcc dot gnu.org --- Comment #8 from Eric Gallager --- (In reply to felix from comment #7) > Created attachment 42188 [details] > Preliminary patch > > Based on the already-existing __has_attribute() support, I've developed a > patch implementing this feature. Attached. > > After some superficial testing (./cc1 -E), it seems to be working correctly. > I don't really have the resources to run regression tests, so I didn't > (although I think regressions would be unlikely). I also didn't write any > new tests or documentation. (I noticed __has_attribute also doesn't seem to > have much of either.) > > I made the feature closely mimic The Other Compiler's behaviour: only > function built-ins are recognised. This includes generic functions like > __builtin_add_overflow and C library functions specially handled by the > front-end like printf (unless -fno-builtin is used), but excludes types like > __builtin_va_list and function-like constructs (implemented as keywords) > like __builtin_offsetof and __builtin_types_compatible_p. This is not so > much of a problem for them, since they also provide __has_feature(), > __has_extension() and __is_identifier() macros. The former has been > requested in PR 60512 and rejected; it may be reasonable to revisit the > issue. > > However, if more such preprocessor, er, built-ins are desired, it may start > becoming unwieldy to implement them the way I did in this patch; it involved > some amount of copy-pasting. Thank you for the patch! Please send it to the gcc-patches mailing list for review: https://gcc.gnu.org/ml/gcc-patches/
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #7 from felix --- Created attachment 42188 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42188=edit Preliminary patch Based on the already-existing __has_attribute() support, I've developed a patch implementing this feature. Attached. After some superficial testing (./cc1 -E), it seems to be working correctly. I don't really have the resources to run regression tests, so I didn't (although I think regressions would be unlikely). I also didn't write any new tests or documentation. (I noticed __has_attribute also doesn't seem to have much of either.) I made the feature closely mimic The Other Compiler's behaviour: only function built-ins are recognised. This includes generic functions like __builtin_add_overflow and C library functions specially handled by the front-end like printf (unless -fno-builtin is used), but excludes types like __builtin_va_list and function-like constructs (implemented as keywords) like __builtin_offsetof and __builtin_types_compatible_p. This is not so much of a problem for them, since they also provide __has_feature(), __has_extension() and __is_identifier() macros. The former has been requested in PR 60512 and rejected; it may be reasonable to revisit the issue. However, if more such preprocessor, er, built-ins are desired, it may start becoming unwieldy to implement them the way I did in this patch; it involved some amount of copy-pasting.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 Jason Merrill changed: What|Removed |Added Status|ASSIGNED|NEW Assignee|jason at gcc dot gnu.org |unassigned at gcc dot gnu.org
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 Jason Merrill changed: What|Removed |Added Status|UNCONFIRMED |ASSIGNED Last reconfirmed||2017-06-15 CC||jason at gcc dot gnu.org Assignee|unassigned at gcc dot gnu.org |jason at gcc dot gnu.org Ever confirmed|0 |1
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 kim.walisch at gmail dot com changed: What|Removed |Added CC||kim.walisch at gmail dot com --- Comment #6 from kim.walisch at gmail dot com --- > Why do you need this? 1) Because clang already supports it and people like myself would like to simplify their code i.e. have a single macro for both GCC and clang. 2) Without this macro one needs to check if a __builtin_* macro exists using the build system (Autotools, CMake) which requires more complicated code or one needs a nasty macro which checks the __GNUC__ and __GNUC_MINOR__ versions. The __has_attribute() macro is much more elegant than the other two options. > You still need to check for older versions of the > compilers (which don't support __has_attribute()) anyways. Not everybody needs to support old compiler versions. My company regularly upgrades to the latest Linux version. After such an upgrade we are allowed to use new compiler features. There are also lots of developers out there who only care if their program compiles with a fairly recent compiler (e.g. not older than 5 years). If GCC would implement __has_attribute() today than it would become very useful in just a few years.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 Allan Jensen changed: What|Removed |Added CC||linux at carewolf dot com --- Comment #5 from Allan Jensen --- This just hit us again, when a patch release removed __builtin_clzs or renamed it to __builtin_lzcnt_u16. We need to be able to detect which ones exist at compile-time otherwise we can't ship in headers that won't break when gcc updates.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #4 from Jonathan Wakely --- (In reply to Julian Taylor from comment #3) > Similarly useful would be the related __has_attribute, those especially tend > to cause a huge mess of version number checks. That's already supported: https://gcc.gnu.org/gcc-5/changes.html
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 Julian Taylor changed: What|Removed |Added CC||jtaylor.debian at googlemail dot c ||om --- Comment #3 from Julian Taylor --- It would also allow using builtins in installed headers more easily, e.g. for isnan, isfinite abstractions without the need of juggling version number checks. This simplifies work for stacks of software deriving from one common base library. The deriving applications could use the efficient builtins via the common base header instead of each having to add their own checks. Similarly useful would be the related __has_attribute, those especially tend to cause a huge mess of version number checks.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 Andy Lutomirski changed: What|Removed |Added CC||luto at mit dot edu --- Comment #2 from Andy Lutomirski --- I'd also like this feature. Not all standard open source projects use autoconf. For example, the Linux kernel doesn't. The Linux kernel *is* capable of probing for the existence of builtins, but it's a pain in the neck: it needs to write out a test .c file and try compiling it. This is slow, and it scales terribly: the configuration step wastes time proportional to the number of probed builtins probing for builtins, and the constant factor is pretty bad. It also means that the amount of work needed to use a new builtin is rather high: add a new config step and remember to use the result correctly in the code that uses the builtin. The name of the resulting macro can't really be standardized. Sure, with __has_builtin, users would still need to probe for __has_builtin itself, but that would be a single check. For builtins that are newer than __has_builtin, there would be no need to have a fallback and, for older builtins, a fallback could be added if needed. (Alternatively, the C code could simply not use the builtin on older gcc versions.)
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 Andrew Pinski pinskia at gcc dot gnu.org changed: What|Removed |Added Component|preprocessor|c --- Comment #1 from Andrew Pinski pinskia at gcc dot gnu.org --- Why do you need this? Why can't you check before doing a compiling if the builtin exists? That is use autoconfig like all standard open source products do. You still need to do that for older versions of the compilers anyways.