From eadf3e52072fbae01e8de8f7f59883aec1b2c9bc Mon Sep 17 00:00:00 2001 From: Anthony Tran Date: Thu, 10 Jul 2025 09:18:50 -0700 Subject: [PATCH 1/6] Added warning and warning group for sanitizer argument mismatch --- clang/include/clang/Basic/DiagnosticDriverKinds.td | 5 +++++ clang/include/clang/Basic/DiagnosticGroups.td | 3 +++ 2 files changed, 8 insertions(+) diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 34b6c0d7a8acd..49a8bdf06bda4 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -874,4 +874,9 @@ def warn_drv_openacc_without_cir : Warning<"OpenACC directives will result in no runtime behavior; use " "-fclangir to enable runtime effect">, InGroup; + +def warn_drv_sanitize_trap_mismatch : Warning< + "-fsanitize-trap=%0 has no effect because the matching sanitizer is not enabled; " + "did you mean to pass \"-fsanitize=%0\" as well?">, + InGroup; } diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index f54a830b0103e..a79562cd9c2e0 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1752,3 +1752,6 @@ def ExplicitSpecializationStorageClass : DiagGroup<"explicit-specialization-stor // A warning for options that enable a feature that is not yet complete def ExperimentalOption : DiagGroup<"experimental-option">; + +// Warnings for sanitizer arguments +def SanitizeTrapMismatch : DiagGroup<"sanitize-trap-mismatch">; From f1bf9b34daca5d23d1a3f518847f3ccbc8f069a7 Mon Sep 17 00:00:00 2001 From: Anthony Tran Date: Thu, 10 Jul 2025 13:35:52 -0700 Subject: [PATCH 2/6] Emit warning and parse mismatched arguments --- clang/lib/Driver/SanitizerArgs.cpp | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 4bd61c2f8deef..8b78d850e0018 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -348,6 +348,30 @@ parseSanitizeSkipHotCutoffArgs(const Driver &D, const llvm::opt::ArgList &Args, return Cutoffs; } +// Given a set of mismatched bits, TrapOnly (bits the user asked to trap but +// that aren’t actually enabled), emit a warning based on -fsanitize-trap=NAME +static void diagnoseTrapOnly(const Driver &D, SanitizerMask &TrapOnly) { +// Double pass: one for sanitizer groupings, one for leaves (ex: undefined vs. +// signed-integer-overflow) +#define SANITIZER(NAME, ID) +#define SANITIZER_GROUP(NAME, ID, ALIAS) \ + if (TrapOnly & SanitizerKind::ID##Group) { \ + D.Diag(diag::warn_drv_sanitize_trap_mismatch) << NAME; \ + TrapOnly &= ~SanitizerKind::ID##Group; \ + TrapOnly &= ~SanitizerKind::ID; \ + } +#include "clang/Basic/Sanitizers.def" + +#undef SANITIZER_GROUP +#define SANITIZER_GROUP(NAME, ID, ALIAS) +#define SANITIZER(NAME, ID) \ + if (TrapOnly & SanitizerKind::ID) { \ + D.Diag(diag::warn_drv_sanitize_trap_mismatch) << NAME; \ + TrapOnly &= ~SanitizerKind::ID; \ + } +#include "clang/Basic/Sanitizers.def" +} + bool SanitizerArgs::needsFuzzerInterceptors() const { return needsFuzzer() && !needsAsanRt() && !needsTsanRt() && !needsMsanRt(); } @@ -730,6 +754,18 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, options::OPT_fno_sanitize_recover_EQ); RecoverableKinds &= Kinds; + // Parse any -fsanitize-trap=<...> flags the user provided, then + // diagnose any which do not have a matching -fsanitize=<...> + if (DiagnoseErrors) { + SanitizerMask ExplicitTrap = parseSanitizeArgs( + D, Args, false, {}, {}, {}, options::OPT_fsanitize_trap_EQ, + options::OPT_fno_sanitize_trap_EQ); + SanitizerMask TrapOnly = ExplicitTrap & ~Kinds; + + if (TrapOnly) + diagnoseTrapOnly(D, TrapOnly); + } + TrappingKinds &= Kinds; RecoverableKinds &= ~TrappingKinds; From c7b44099357ee78329f6e289ef6feb321b9b121c Mon Sep 17 00:00:00 2001 From: Anthony Tran Date: Mon, 14 Jul 2025 03:36:11 -0700 Subject: [PATCH 3/6] Modify warning message --- clang/include/clang/Basic/DiagnosticDriverKinds.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 49a8bdf06bda4..f2a0582a364bf 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -876,7 +876,7 @@ def warn_drv_openacc_without_cir InGroup; def warn_drv_sanitize_trap_mismatch : Warning< - "-fsanitize-trap=%0 has no effect because the matching sanitizer is not enabled; " - "did you mean to pass \"-fsanitize=%0\" as well?">, + "-fsanitize-trap=%0 has no effect because the \"%0\" sanitizer is disabled; " + "consider passing \"fsanitize=%0\" to enable the sanitizer">, InGroup; } From 2610c329a75c61cf9c009389fb23cce30d412431 Mon Sep 17 00:00:00 2001 From: Anthony Tran Date: Mon, 14 Jul 2025 04:42:14 -0700 Subject: [PATCH 4/6] Added test case (still missing warning test case for warning suppression) --- clang/test/Driver/fsanitize-trap-mismatch.c | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 clang/test/Driver/fsanitize-trap-mismatch.c diff --git a/clang/test/Driver/fsanitize-trap-mismatch.c b/clang/test/Driver/fsanitize-trap-mismatch.c new file mode 100644 index 0000000000000..8568458f1f3b8 --- /dev/null +++ b/clang/test/Driver/fsanitize-trap-mismatch.c @@ -0,0 +1,7 @@ +// RUN: %clang -fsyntax-only %s -fsanitize-trap=undefined 2>&1 | FileCheck %s --check-prefix=WARN +// RUN: %clang -fsyntax-only %s -fsanitize=undefined -fsanitize-trap=undefined 2>&1 | FileCheck %s --check-prefix=NOWARN +// +// WARN: warning: -fsanitize-trap=undefined has no effect because the "undefined" sanitizer is disabled; consider passing "fsanitize=undefined" to enable the sanitizer +// NOWARN-NOT: warning: -fsanitize-trap=undefined has no effect because the "undefined" sanitizer is disabled; consider passing "fsanitize=undefined" to enable the sanitizer + +int main(void) { return 0; } From a1a1c32efd15e6733ab611ce2073326c82d23a24 Mon Sep 17 00:00:00 2001 From: Anthony Tran Date: Mon, 14 Jul 2025 04:50:47 -0700 Subject: [PATCH 5/6] Add comments for clarity --- clang/lib/Driver/SanitizerArgs.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 8b78d850e0018..a72aaaec02f8b 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -351,8 +351,7 @@ parseSanitizeSkipHotCutoffArgs(const Driver &D, const llvm::opt::ArgList &Args, // Given a set of mismatched bits, TrapOnly (bits the user asked to trap but // that aren’t actually enabled), emit a warning based on -fsanitize-trap=NAME static void diagnoseTrapOnly(const Driver &D, SanitizerMask &TrapOnly) { -// Double pass: one for sanitizer groupings, one for leaves (ex: undefined vs. -// signed-integer-overflow) +// One pass for sanitizer groupings #define SANITIZER(NAME, ID) #define SANITIZER_GROUP(NAME, ID, ALIAS) \ if (TrapOnly & SanitizerKind::ID##Group) { \ @@ -363,6 +362,7 @@ static void diagnoseTrapOnly(const Driver &D, SanitizerMask &TrapOnly) { #include "clang/Basic/Sanitizers.def" #undef SANITIZER_GROUP +// One pass for individual sanitizer names/leaves #define SANITIZER_GROUP(NAME, ID, ALIAS) #define SANITIZER(NAME, ID) \ if (TrapOnly & SanitizerKind::ID) { \ @@ -754,9 +754,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, options::OPT_fno_sanitize_recover_EQ); RecoverableKinds &= Kinds; + // FIXME: `DiagnoseErrors` name seems a little wrong as we emit warnings here, + // not errors but that seems to be done elsewhere in this method. + // Parse any -fsanitize-trap=<...> flags the user provided, then // diagnose any which do not have a matching -fsanitize=<...> if (DiagnoseErrors) { + // parseSanitizeTrapArgs was not used because it sets a TrappingDefault + // which causes the emission of warnings beyond what the user entered SanitizerMask ExplicitTrap = parseSanitizeArgs( D, Args, false, {}, {}, {}, options::OPT_fsanitize_trap_EQ, options::OPT_fno_sanitize_trap_EQ); From f76394134f8d0c85ba5dbe872767691dc124686b Mon Sep 17 00:00:00 2001 From: Anthony Tran Date: Mon, 14 Jul 2025 05:05:57 -0700 Subject: [PATCH 6/6] Modify test case and add suppression test case --- clang/test/Driver/fsanitize-trap-mismatch.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/test/Driver/fsanitize-trap-mismatch.c b/clang/test/Driver/fsanitize-trap-mismatch.c index 8568458f1f3b8..d22177fc54c28 100644 --- a/clang/test/Driver/fsanitize-trap-mismatch.c +++ b/clang/test/Driver/fsanitize-trap-mismatch.c @@ -1,7 +1,9 @@ -// RUN: %clang -fsyntax-only %s -fsanitize-trap=undefined 2>&1 | FileCheck %s --check-prefix=WARN -// RUN: %clang -fsyntax-only %s -fsanitize=undefined -fsanitize-trap=undefined 2>&1 | FileCheck %s --check-prefix=NOWARN +// RUN: %clang -S -emit-llvm -g -O0 %s -fsanitize-trap=undefined -o - 2>&1 | FileCheck %s --check-prefix=WARN +// RUN: %clang -S -emit-llvm -g -O0 %s -fsanitize=undefined -fsanitize-trap=undefined -o - 2>&1 | FileCheck %s --check-prefix=NOWARN +// RUN: %clang -S -emit-llvm -g -O0 %s -fsanitize-trap=undefined -Wno-sanitize-trap-mismatch -o - 2>&1 | FileCheck %s --check-prefix=SUPPRESS // // WARN: warning: -fsanitize-trap=undefined has no effect because the "undefined" sanitizer is disabled; consider passing "fsanitize=undefined" to enable the sanitizer // NOWARN-NOT: warning: -fsanitize-trap=undefined has no effect because the "undefined" sanitizer is disabled; consider passing "fsanitize=undefined" to enable the sanitizer +// SUPPRESS-NOT: warning: -fsanitize-trap=undefined has no effect because the "undefined" sanitizer is disabled; consider passing "fsanitize=undefined" to enable the sanitizer int main(void) { return 0; }