Skip to content

Conversation

pcc
Copy link
Contributor

@pcc pcc commented Aug 15, 2025

Per discussion with @ojhunt and @AaronBallman we are moving towards
predefined macros and away from __has_feature and __has_extension
for detecting sanitizers and other similar features. The rationale
is that __has_feature is only really meant for standardized features
(see the comment at the top of clang/include/clang/Basic/Features.def),
and __has_extension has the issues discovered as part of #153104.

Let's start by defining macros for ASan, HWASan and TSan, consistently
with gcc.

Created using spr 1.3.6-beta.1
@pcc pcc requested a review from ojhunt August 15, 2025 22:19
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Aug 15, 2025
@pcc pcc requested review from AaronBallman and fmayer August 15, 2025 22:19
@llvmbot
Copy link
Member

llvmbot commented Aug 15, 2025

@llvm/pr-subscribers-clang

Author: Peter Collingbourne (pcc)

Changes

Per discussion with @ojhunt and @AaronBallman we are moving towards
predefined macros and away from __has_feature and __has_extension for
detecting sanitizers and other similar features. Let's start by defining
macros for ASan, HWASan and TSan, consistently with gcc.


Full diff: https://github.com/llvm/llvm-project/pull/153888.diff

2 Files Affected:

  • (modified) clang/lib/Frontend/InitPreprocessor.cpp (+7)
  • (added) clang/test/Preprocessor/sanitizer-predefines.c (+8)
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 008a35d5265e1..81d798d8e27c6 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1519,6 +1519,13 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
   if (TI.getTriple().isOSBinFormatELF())
     Builder.defineMacro("__ELF__");
 
+  if (LangOpts.Sanitize.has(SanitizerKind::Address))
+    Builder.defineMacro("__SANITIZE_ADDRESS__");
+  if (LangOpts.Sanitize.has(SanitizerKind::HWAddress))
+    Builder.defineMacro("__SANITIZE_HWADDRESS__");
+  if (LangOpts.Sanitize.has(SanitizerKind::Thread))
+    Builder.defineMacro("__SANITIZE_THREAD__");
+  
   // Target OS macro definitions.
   if (PPOpts.DefineTargetOSMacros) {
     const llvm::Triple &Triple = TI.getTriple();
diff --git a/clang/test/Preprocessor/sanitizer-predefines.c b/clang/test/Preprocessor/sanitizer-predefines.c
new file mode 100644
index 0000000000000..9d2f6bf2517a2
--- /dev/null
+++ b/clang/test/Preprocessor/sanitizer-predefines.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -E -dM -triple aarch64-unknown-linux -fsanitize=address %s | FileCheck %s --check-prefix=ASAN
+// ASAN: #define __SANITIZE_ADDRESS__ 1
+
+// RUN: %clang_cc1 -E -dM -triple aarch64-unknown-linux -fsanitize=hwaddress %s | FileCheck %s --check-prefix=HWASAN
+// HWASAN: #define __SANITIZE_HWADDRESS__ 1
+
+// RUN: %clang_cc1 -E -dM -triple aarch64-unknown-linux -fsanitize=thread %s | FileCheck %s --check-prefix=TSAN
+// TSAN: #define __SANITIZE_THREAD__ 1

@pcc pcc requested a review from vitalybuka August 15, 2025 22:21
Copy link

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff HEAD~1 HEAD --extensions cpp,c -- clang/test/Preprocessor/sanitizer-predefines.c clang/lib/Frontend/InitPreprocessor.cpp
View the diff from clang-format here.
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 81d798d8e..5980806fb 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1525,7 +1525,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
     Builder.defineMacro("__SANITIZE_HWADDRESS__");
   if (LangOpts.Sanitize.has(SanitizerKind::Thread))
     Builder.defineMacro("__SANITIZE_THREAD__");
-  
+
   // Target OS macro definitions.
   if (PPOpts.DefineTargetOSMacros) {
     const llvm::Triple &Triple = TI.getTriple();

Copy link
Contributor

@fmayer fmayer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if formatted properly.

Is there some record of this conversation? If not, could you summarize the rationale somewhere?

if (TI.getTriple().isOSBinFormatELF())
Builder.defineMacro("__ELF__");

if (LangOpts.Sanitize.has(SanitizerKind::Address))
Copy link
Collaborator

@vitalybuka vitalybuka Aug 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

msan?
ubsan is hard

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we likely want to add the rest of the sanitizers here as well (in a followup). I started with the ones that are already supported by GCC with a macro.

For UBSan, we may consider reverting #148322 and redoing it here.

Created using spr 1.3.6-beta.1
@pcc pcc merged commit 568c23b into main Aug 15, 2025
7 of 9 checks passed
@pcc pcc deleted the users/pcc/spr/frontend-define-__sanitize___-macros-for-certain-sanitizers branch August 15, 2025 23:13
@pcc
Copy link
Contributor Author

pcc commented Aug 15, 2025

LGTM if formatted properly.

Is there some record of this conversation? If not, could you summarize the rationale somewhere?

Added to commit message.

llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Aug 15, 2025
…ers.

Per discussion with @ojhunt and @AaronBallman we are moving towards
predefined macros and away from __has_feature and __has_extension
for detecting sanitizers and other similar features. The rationale
is that __has_feature is only really meant for standardized features
(see the comment at the top of clang/include/clang/Basic/Features.def),
and __has_extension has the issues discovered as part of #153104.

Let's start by defining macros for ASan, HWASan and TSan, consistently
with gcc.

Reviewers: vitalybuka, ojhunt, AaronBallman, fmayer

Reviewed By: fmayer, vitalybuka

Pull Request: llvm/llvm-project#153888
nathanchance added a commit that referenced this pull request Sep 8, 2025
…56543)

GCC defines these macros for both userspace and kernel address
sanitizers:

$ gcc -E -dM -fsanitize=address -x c /dev/null &| string match -er
SANITIZE
    #define __SANITIZE_ADDRESS__ 1
$ gcc -E -dM -fsanitize=kernel-address -x c /dev/null &| string match
-er SANITIZE
    #define __SANITIZE_ADDRESS__ 1
$ gcc -E -dM -fsanitize=hwaddress -x c /dev/null &| string match -er
SANITIZE
    #define __SANITIZE_HWADDRESS__ 1
$ gcc -E -dM -fsanitize=kernel-hwaddress -x c /dev/null &| string match
-er SANITIZE
    #define __SANITIZE_HWADDRESS__ 1

PR #153888 added these same defines for clang but only for the userspace
address sanitizers:

$ clang -E -dM -fsanitize=address -x c /dev/null &| string match -er
SANITIZE
    #define __SANITIZE_ADDRESS__ 1
$ clang -E -dM -fsanitize=kernel-address -x c /dev/null &| string match
-er SANITIZE
$ clang -E -dM -fsanitize=hwaddress -x c /dev/null &| string match -er
SANITIZE
    #define __SANITIZE_HWADDRESS__ 1
$ clang -E -dM -fsanitize=kernel-hwaddress -x c /dev/null &| string
match -er SANITIZE

Match GCC's behavior so that the Linux kernel can eventually drop its
own internal defines.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants