[clang] [Clang] __has_builtin should return false for aux triple builtins (PR #121839)

Nick Sarnie via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 8 09:35:23 PST 2025


================
@@ -1818,8 +1819,21 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
             // usual allocation and deallocation functions. Required by libc++
             return 201802;
           default:
+            // We may get here because of aux builtins which may not be
+            // supported on the default target, for example if we have an X86
+            // specific builtin and the current target is SPIR-V. Sometimes we
+            // rely on __has_builtin returning true when passed a builtin that
+            // is not supported on the default target due to LangOpts but is
+            // supported on the aux target. See
+            // test/Headers/__cpuidex_conflict.c for an example. If the builtin
+            // is an aux builtin and it can never be supported on the default
+            // target, __has_builtin should return false.
+            if (getBuiltinInfo().isAuxBuiltinID(BuiltinID) &&
+                getBuiltinInfo().isAuxBuiltinIDAlwaysUnsupportedOnDefaultTarget(
----------------
sarnex wrote:

> Why do we need this extra logic? I figured it would simply be if the builtin is only in the aux target, then we return false.

If you mean why isn't the check just `if (getBuiltinInfo().isAuxBuiltinID(BuiltinID))`, it's because doing that breaks `test/Headers/__cpuidex_conflict.c` (the last `RUN` line in the test). 

That test has x86 for both the default and aux target, but the builtin the test cares about is MSVC only and the default target env isn't MSVC, so that builtin considered unsupported and not registered, but the aux target is MSVC, so it is registered and `isAuxBuiltinID` returns true, and then returning false in `__has_builtin` breaks the test. 

https://github.com/llvm/llvm-project/pull/121839


More information about the cfe-commits mailing list