https://github.com/ojhunt updated https://github.com/llvm/llvm-project/pull/153912
>From ea731927d6bdf85a3cdb333b756447658f2c2ea6 Mon Sep 17 00:00:00 2001 From: Oliver Hunt <oli...@apple.com> Date: Fri, 15 Aug 2025 18:40:12 -0700 Subject: [PATCH 1/6] [clang][PAC] Make ptrauth_qualifier and ptrauth_intrinsic Darwin only features For backwards compatibility reasons the ptrauth_qualifier and ptrauth_intrinsic features need to be testable with __has_feature() on Apple platforms, but for other platforms this backwards compatibility issue does not exist. This PR resolves these issues by making the ptrauth_qualifier and ptrauth_intrinsic tests conditional upon a darwin target. This also allows us to revert the ptrauth_qualifier check from an extension to a feature test again, as is required on these platforms. At the same time we introduce a new predefined macro __PTRAUTH__ that answers the same question as __has_feature(ptrauth_qualifier) and __has_feature(ptrauth_intrinsic) as those tests are synonymous and only exist separately for compatibility reasons. The requirement to test for the __PTRAUTH__ macro also resolves the hazard presented by mixing the ptrauth_qualifier flag (that impacts ABI and security policies) with -pedantics-errors, which makes __has_extension return false for all extensions. --- clang/include/clang/Basic/Features.def | 4 +-- clang/lib/Frontend/FrontendActions.cpp | 1 + clang/lib/Frontend/InitPreprocessor.cpp | 3 +++ clang/lib/Headers/ptrauth.h | 4 +-- clang/lib/Lex/PPMacroExpansion.cpp | 1 + clang/test/Preprocessor/ptrauth_extension.c | 30 ++++++++++++++++++--- clang/test/Preprocessor/ptrauth_feature.c | 2 +- clang/test/Sema/ptrauth-qualifier.c | 16 +++++++++-- clang/test/SemaObjC/ptrauth-qualifier.m | 16 +++++++++-- 9 files changed, 64 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index b9efc6a6a2e9d..6f414105d7c36 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -147,8 +147,8 @@ FEATURE(type_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Type)) FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) -FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics) -EXTENSION(ptrauth_qualifier, LangOpts.PointerAuthIntrinsics) +FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics && Target.getTriple().isOSDarwin()) +FEATURE(ptrauth_qualifier, LangOpts.PointerAuthIntrinsics && Target.getTriple().isOSDarwin()) FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls) FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns) FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination) diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 685a9bbf2cde9..d29a08c43fc12 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -1159,6 +1159,7 @@ void DumpCompilerOptionsAction::ExecuteAction() { raw_ostream &OS = *OSP; const Preprocessor &PP = CI.getPreprocessor(); const LangOptions &LangOpts = PP.getLangOpts(); + const TargetInfo &Target = CI.getTarget(); // FIXME: Rather than manually format the JSON (which is awkward due to // needing to remove trailing commas), this should make use of a JSON library. diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 008a35d5265e1..accddfebc0f6f 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1528,6 +1528,9 @@ static void InitializePredefinedMacros(const TargetInfo &TI, #undef TARGET_OS } + if (LangOpts.PointerAuthIntrinsics) + Builder.defineMacro("__PTRAUTH__"); + // Get other target #defines. TI.getTargetDefines(LangOpts, Builder); } diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h index 7f7d387cbdfda..f902ca1e3bbd3 100644 --- a/clang/lib/Headers/ptrauth.h +++ b/clang/lib/Headers/ptrauth.h @@ -95,7 +95,7 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; __ptrauth qualifier; the compiler will perform this check automatically. */ -#if __has_feature(ptrauth_intrinsics) +#if __has_feature(ptrauth_intrinsics) || defined(__PTRAUTH__) /* Strip the signature from a value without authenticating it. @@ -388,6 +388,6 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; #define __ptrauth_objc_isa_uintptr #define __ptrauth_objc_super_pointer -#endif /* __has_feature(ptrauth_intrinsics) */ +#endif /* __has_feature(ptrauth_intrinsics) || defined(__PTRAUTH__) */ #endif /* __PTRAUTH_H */ diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 6f12ac80d677e..f9dfd0eb14bc0 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1089,6 +1089,7 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc, /// specified by the identifier as a standard language feature. static bool HasFeature(const Preprocessor &PP, StringRef Feature) { const LangOptions &LangOpts = PP.getLangOpts(); + const TargetInfo &Target = PP.getTargetInfo(); // Normalize the feature name, __foo__ becomes foo. if (Feature.starts_with("__") && Feature.ends_with("__") && diff --git a/clang/test/Preprocessor/ptrauth_extension.c b/clang/test/Preprocessor/ptrauth_extension.c index d6b79187ba62d..3267b0786c28f 100644 --- a/clang/test/Preprocessor/ptrauth_extension.c +++ b/clang/test/Preprocessor/ptrauth_extension.c @@ -4,10 +4,32 @@ // RUN: %clang_cc1 -E %s -triple=aarch64 -fptrauth-calls | \ // RUN: FileCheck %s --check-prefixes=NOINTRIN -#if __has_extension(ptrauth_qualifier) -// INTRIN: has_ptrauth_qualifier -void has_ptrauth_qualifier() {} -#else +// RUN: %clang_cc1 -E %s -DIS_DARWIN -triple=arm64e-apple-darwin -fptrauth-intrinsics | \ +// RUN: FileCheck %s --check-prefixes=INTRIN,INTRIN_MAC + +// RUN: %clang_cc1 -E %s -DIS_DARWIN -triple=arm64e-apple-darwin -fptrauth-calls | \ +// RUN: FileCheck %s --check-prefixes=NOINTRIN + +#if defined(IS_DARWIN) && __has_extension(ptrauth_qualifier) +// INTRIN_MAC: has_ptrauth_qualifier1 +void has_ptrauth_qualifier1() {} +#ifndef __PTRAUTH__ +#error ptrauth_qualifier extension present without predefined test macro +#endif +#endif +#if defined(IS_DARWIN) && __has_feature(ptrauth_qualifier) +// INTRIN_MAC: has_ptrauth_qualifier2 +void has_ptrauth_qualifier2() {} +#ifndef __PTRAUTH__ +#error ptrauth_qualifier extension present without predefined test macro +#endif +#endif +#if defined(__PTRAUTH__) +// INTRIN: has_ptrauth_qualifier3 +void has_ptrauth_qualifier3() {} +#endif + +#if !defined(__PTRAUTH__) && !__has_feature(ptrauth_qualifier) && !__has_extension(ptrauth_qualifier) // NOINTRIN: no_ptrauth_qualifier void no_ptrauth_qualifier() {} #endif diff --git a/clang/test/Preprocessor/ptrauth_feature.c b/clang/test/Preprocessor/ptrauth_feature.c index a440791d6cc69..45d9cd4245dba 100644 --- a/clang/test/Preprocessor/ptrauth_feature.c +++ b/clang/test/Preprocessor/ptrauth_feature.c @@ -34,7 +34,7 @@ // RUN: %clang_cc1 -E %s -triple=aarch64 -fptrauth-elf-got | \ // RUN: FileCheck %s --check-prefixes=NOINTRIN,NOCALLS,NORETS,NOVPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,NOTYPE_INFO_DISCR,NOFUNC,NOINITFINI,NOINITFINI_ADDR_DISCR,NOGOTOS,ELFGOT -#if __has_feature(ptrauth_intrinsics) +#if defined(__PTRAUTH__) // INTRIN: has_ptrauth_intrinsics void has_ptrauth_intrinsics() {} #else diff --git a/clang/test/Sema/ptrauth-qualifier.c b/clang/test/Sema/ptrauth-qualifier.c index 5d932b724f07a..3e568ce9f37e3 100644 --- a/clang/test/Sema/ptrauth-qualifier.c +++ b/clang/test/Sema/ptrauth-qualifier.c @@ -1,13 +1,25 @@ -// RUN: %clang_cc1 -triple arm64-apple-ios -std=c23 -fsyntax-only -verify -fptrauth-intrinsics %s +// RUN: %clang_cc1 -triple arm64-apple-ios -DIS_DARWIN -std=c23 -fsyntax-only -verify -fptrauth-intrinsics %s // RUN: %clang_cc1 -triple aarch64-linux-gnu -std=c23 -fsyntax-only -verify -fptrauth-intrinsics %s -#if !__has_extension(ptrauth_qualifier) +#if defined(IS_DARWIN) && !__has_extension(ptrauth_qualifier) // This error means that the __ptrauth qualifier availability test says that it // is not available. This error is not expected in the output, if it is seen // there is a feature detection regression. #error __ptrauth qualifier not enabled #endif +#if defined(IS_DARWIN) && !__has_feature(ptrauth_qualifier) +// This error means that the __has_feature test for ptrauth_qualifier has +// failed, despite it being expected on darwin. +#error __ptrauth qualifier not enabled +#elif !defined(IS_DARWIN) && (__has_feature(ptrauth_qualifier) || __has_extension(ptrauth_qualifier)) +#error ptrauth_qualifier labeled a feature on a non-darwin platform +#endif + +#if !defined (__PTRAUTH__) +#error __PTRAUTH__ test macro not defined when ptrauth is enabled +#endif + #if __aarch64__ #define VALID_CODE_KEY 0 #define VALID_DATA_KEY 2 diff --git a/clang/test/SemaObjC/ptrauth-qualifier.m b/clang/test/SemaObjC/ptrauth-qualifier.m index 74bbe6f09899b..67a73bbe45777 100644 --- a/clang/test/SemaObjC/ptrauth-qualifier.m +++ b/clang/test/SemaObjC/ptrauth-qualifier.m @@ -1,13 +1,25 @@ -// RUN: %clang_cc1 -triple arm64-apple-ios -fsyntax-only -verify -fptrauth-intrinsics %s +// RUN: %clang_cc1 -triple arm64-apple-ios -DIS_DARWIN -fsyntax-only -verify -fptrauth-intrinsics %s // RUN: %clang_cc1 -triple aarch64-linux-gnu -fsyntax-only -verify -fptrauth-intrinsics %s -#if !__has_extension(ptrauth_qualifier) +#if defined(IS_DARWIN) && !__has_extension(ptrauth_qualifier) // This error means that the __ptrauth qualifier availability test says that it // is not available. This error is not expected in the output, if it is seen // there is a feature detection regression. #error __ptrauth qualifier not enabled #endif +#if defined(IS_DARWIN) && !__has_feature(ptrauth_qualifier) +// This error means that the __has_feature test for ptrauth_qualifier has +// failed, despite it being expected on darwin. +#error __ptrauth qualifier not enabled +#elif !defined(IS_DARWIN) && (__has_feature(ptrauth_qualifier) || __has_extension(ptrauth_qualifier)) +#error ptrauth_qualifier labeled a feature on a non-darwin platform +#endif + +#if !defined (__PTRAUTH__) +#error __PTRAUTH__ test macro not defined when ptrauth is enabled +#endif + @interface Foo // expected-warning@-1 {{class 'Foo' defined without specifying a base class}} // expected-note@-2 {{add a super class to fix this problem}} >From ee8c1ae5072d014fc60656a073f30f61d402d7d3 Mon Sep 17 00:00:00 2001 From: Oliver Hunt <oli...@apple.com> Date: Sun, 17 Aug 2025 22:32:32 -0700 Subject: [PATCH 2/6] Add release note --- clang/docs/ReleaseNotes.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 604b4c3f714b7..3106fe7b7797c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -144,6 +144,11 @@ New Compiler Flags Deprecated Compiler Flags ------------------------- +- Use of `__has_feature` to detect the `ptrauth_qualifier` and `ptrauth_intrinsics` + features has been deprecated, and is restricted to the arm64e target only. The + correct method to check for these features is to test for the `__PTRAUTH__` + macro. + Modified Compiler Flags ----------------------- >From b1b2de3f797b6dc81ec671cc462bc863a8895a35 Mon Sep 17 00:00:00 2001 From: Oliver Hunt <oli...@apple.com> Date: Mon, 18 Aug 2025 06:14:03 -0700 Subject: [PATCH 3/6] Update clang/docs/ReleaseNotes.rst Co-authored-by: Aaron Ballman <aa...@aaronballman.com> --- clang/docs/ReleaseNotes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3106fe7b7797c..e474c14816d9d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -144,9 +144,9 @@ New Compiler Flags Deprecated Compiler Flags ------------------------- -- Use of `__has_feature` to detect the `ptrauth_qualifier` and `ptrauth_intrinsics` +- Use of ``__has_feature`` to detect the ``ptrauth_qualifier`` and ``ptrauth_intrinsics`` features has been deprecated, and is restricted to the arm64e target only. The - correct method to check for these features is to test for the `__PTRAUTH__` + correct method to check for these features is to test for the ``__PTRAUTH__`` macro. Modified Compiler Flags >From bade8f37d3c4ba78baadc5391be2f5530231e761 Mon Sep 17 00:00:00 2001 From: Oliver Hunt <oli...@apple.com> Date: Mon, 18 Aug 2025 06:21:46 -0700 Subject: [PATCH 4/6] Revert addition of a new declaration requirement --- clang/include/clang/Basic/Features.def | 6 ++++-- clang/lib/Frontend/FrontendActions.cpp | 2 +- clang/lib/Lex/PPMacroExpansion.cpp | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 6f414105d7c36..7039844aaf270 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -147,8 +147,10 @@ FEATURE(type_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Type)) FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) -FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics && Target.getTriple().isOSDarwin()) -FEATURE(ptrauth_qualifier, LangOpts.PointerAuthIntrinsics && Target.getTriple().isOSDarwin()) +FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics && + PP.getTargetInfo().getTriple().isOSDarwin()) +FEATURE(ptrauth_qualifier, LangOpts.PointerAuthIntrinsics && + PP.getTargetInfo().getTriple().isOSDarwin()) FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls) FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns) FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination) diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index d29a08c43fc12..815bdc0bb54c3 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -1159,7 +1159,7 @@ void DumpCompilerOptionsAction::ExecuteAction() { raw_ostream &OS = *OSP; const Preprocessor &PP = CI.getPreprocessor(); const LangOptions &LangOpts = PP.getLangOpts(); - const TargetInfo &Target = CI.getTarget(); + // FIXME: Rather than manually format the JSON (which is awkward due to // needing to remove trailing commas), this should make use of a JSON library. diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index f9dfd0eb14bc0..6f12ac80d677e 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1089,7 +1089,6 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc, /// specified by the identifier as a standard language feature. static bool HasFeature(const Preprocessor &PP, StringRef Feature) { const LangOptions &LangOpts = PP.getLangOpts(); - const TargetInfo &Target = PP.getTargetInfo(); // Normalize the feature name, __foo__ becomes foo. if (Feature.starts_with("__") && Feature.ends_with("__") && >From 3316f385c8fc0432373e261fb0bb154b169d29ab Mon Sep 17 00:00:00 2001 From: Oliver Hunt <oli...@apple.com> Date: Mon, 18 Aug 2025 06:27:27 -0700 Subject: [PATCH 5/6] remove added lines --- clang/lib/Frontend/FrontendActions.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 815bdc0bb54c3..685a9bbf2cde9 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -1160,7 +1160,6 @@ void DumpCompilerOptionsAction::ExecuteAction() { const Preprocessor &PP = CI.getPreprocessor(); const LangOptions &LangOpts = PP.getLangOpts(); - // FIXME: Rather than manually format the JSON (which is awkward due to // needing to remove trailing commas), this should make use of a JSON library. // FIXME: Instead of printing enums as an integral value and specifying the >From e99378244d9e48e7a04c60d98bbb43d52b7341e4 Mon Sep 17 00:00:00 2001 From: Oliver Hunt <oli...@apple.com> Date: Mon, 18 Aug 2025 12:08:04 -0700 Subject: [PATCH 6/6] Move release note --- clang/docs/ReleaseNotes.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e474c14816d9d..23059bfda0f68 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -137,6 +137,12 @@ Non-comprehensive list of changes in this release - ``__builtin_elementwise_max`` and ``__builtin_elementwise_min`` functions for integer types can now be used in constant expressions. +- Use of ``__has_feature`` to detect the ``ptrauth_qualifier`` and ``ptrauth_intrinsics`` + features has been deprecated, and is restricted to the arm64e target only. The + correct method to check for these features is to test for the ``__PTRAUTH__`` + macro. + + New Compiler Flags ------------------ - New option ``-fno-sanitize-annotate-debug-info-traps`` added to disable emitting trap reasons into the debug info when compiling with trapping UBSan (e.g. ``-fsanitize-trap=undefined``). @@ -144,11 +150,6 @@ New Compiler Flags Deprecated Compiler Flags ------------------------- -- Use of ``__has_feature`` to detect the ``ptrauth_qualifier`` and ``ptrauth_intrinsics`` - features has been deprecated, and is restricted to the arm64e target only. The - correct method to check for these features is to test for the ``__PTRAUTH__`` - macro. - Modified Compiler Flags ----------------------- _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits