On Tue, Oct 01, 2019 at 11:16:10AM -0600, Martin Sebor wrote: > Attached is an implementation of the __has_builtin special > preprocessor operator/macro analogous to __has_attribute and > (hopefully) compatible with the synonymous Clang feature (I > couldn't actually find tests for it in the Clang test suite > but if someone points me at them I'll verify it).
For the __builtin_*/__sync_*/__atomic_* etc. builtins whether something is a builtin or not is quite clear, basically whether if using the right operands for it will compile and do something. For the library functions, what does it mean that something is a builtin though? In some cases we have them in the builtin tables only to have some predefined attributes for them, in other cases because the compiler is aware of some of their special properties, in other cases that the compiler will sometimes optimize them into something else or inline them and at other times keep them as a library calls, in some cases only for the compiler to be able to emit calls to those routines in generated code, in other cases to always optimize them/inline them and never emit the library function (which perhaps doesn't exist). I believe that for some builtins like stpcpy we treat them as builtins only if we see them prototyped first. And then for C++ with namespaces and symbol lookup rules, whether something is or isn't a builtin depends not just on the identifier, but namespace too and maybe argument types too. So, what do we want __has_builtin to mean for those? Say, do we want __has_builtin (_exit) just because we have it in the tables to 1) add noreturn/nothrow/leaf attributes to it 2) consider it in branch prediction heuristics, but otherwise don't do anything special with it? Jakub