-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[sanitizer] Add plumbing for -fsanitize-annotate-debug-info and partly replace '-mllvm -array-bounds-pseudofn' #138577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ly replace '-mllvm -array-bounds-pseudofn' Florian1 introduced '-mllvm -array-bounds-pseudofn' (llvm#128977) to make it easier to see why crashes occurred, and to estimate with a profiler the cycles spent on these array-bounds checks. This functionality could be usefully generalized to other checks in future work. This patch adds the plumbing for -fsanitize-add-pseudo-functions, and connects it to the existing array-bounds-pseudo-fn functionality i.e., -fsanitize-add-pseudo-functions=array-bounds can be used as a replacement for '-mllvm -array-bounds-pseudofn', though we do not yet delete the latter. Note: we replaced '-mllvm -array-bounds-pseudofn' in clang/test/CodeGen/bounds-checking-debuginfo.c, because adding test cases would modify the line numbers in the test assertions, and therefore obscure that the test output is the same between '-mllvm -array-bounds-pseudofn' and -fsanitize-add-pseudo-functions=array-bounds.
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: Thurston Dang (thurstond) ChangesFlorian1 introduced '-mllvm -array-bounds-pseudofn' (#128977) to make it easier to see why crashes occurred, and to estimate with a profiler the cycles spent on these array-bounds checks. This functionality could be usefully generalized to other checks in future work. This patch adds the plumbing for -fsanitize-add-pseudo-functions, and connects it to the existing array-bounds-pseudo-fn functionality i.e., -fsanitize-add-pseudo-functions=array-bounds can be used as a replacement for '-mllvm -array-bounds-pseudofn', though we do not yet delete the latter. Note: we replaced '-mllvm -array-bounds-pseudofn' in clang/test/CodeGen/bounds-checking-debuginfo.c, because adding test cases would modify the line numbers in the test assertions, and therefore obscure that the test output is the same between '-mllvm -array-bounds-pseudofn' and -fsanitize-add-pseudo-functions=array-bounds. Patch is 23.01 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138577.diff 8 Files Affected:
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index e39a73bdb13ac..be17c81876ddf 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -399,6 +399,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// (0.0 [default] to skip none, 1.0 to skip all).
SanitizerMaskCutoffs SanitizeSkipHotCutoffs;
+ /// Set of sanitizer checks that will be wrapped inside pseudofunctions.
+ SanitizerSet SanitizeAddPseudoFunctions;
+
/// List of backend command-line options for -fembed-bitcode.
std::vector<uint8_t> CmdArgs;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 11677626dbf1f..c06bc5cfcbfa8 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2533,6 +2533,21 @@ def fno_sanitize_merge_handlers : Flag<["-"], "fno-sanitize-merge">, Group<f_cla
Alias<fno_sanitize_merge_handlers_EQ>, AliasArgs<["all"]>,
Visibility<[ClangOption, CLOption]>,
HelpText<"Do not allow compiler to merge handlers for any sanitizers">;
+def fsanitize_add_pseudo_functions_EQ
+ : CommaJoined<["-"], "fsanitize-add-pseudo-functions=">,
+ Group<f_clang_Group>,
+ HelpText<"Add pseudo-functions to checks for specified sanitizers">;
+def fno_sanitize_add_pseudo_functions_EQ
+ : CommaJoined<["-"], "fno-sanitize-add-pseudo-functions=">,
+ Group<f_clang_Group>,
+ HelpText<"Do not allow compiler to add pseudo-functions to checks for specified sanitizers">;
+def fsanitize_add_pseudo_functions : Flag<["-"], "fsanitize-add-pseudo-functions">, Group<f_clang_Group>,
+ Alias<fsanitize_add_pseudo_functions_EQ>, AliasArgs<["all"]>,
+ HelpText<"Allow compiler to add pseudo-functions to checks for all sanitizers">;
+def fno_sanitize_add_pseudo_functions : Flag<["-"], "fno-sanitize-add-pseudo-functions">, Group<f_clang_Group>,
+ Alias<fno_sanitize_add_pseudo_functions_EQ>, AliasArgs<["all"]>,
+ Visibility<[ClangOption, CLOption]>,
+ HelpText<"Do not allow compiler to add pseudo-functions to checks for any sanitizers">;
def fsanitize_undefined_trap_on_error
: Flag<["-"], "fsanitize-undefined-trap-on-error">, Group<f_clang_Group>,
Alias<fsanitize_trap_EQ>, AliasArgs<["undefined"]>;
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index 528e3b400f3dc..1c11706639aba 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -27,6 +27,7 @@ class SanitizerArgs {
SanitizerSet TrapSanitizers;
SanitizerSet MergeHandlers;
SanitizerMaskCutoffs SkipHotCutoffs;
+ SanitizerSet AddPseudoFunctions;
std::vector<std::string> UserIgnorelistFiles;
std::vector<std::string> SystemIgnorelistFiles;
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 2e01adc51fdf0..4ea41662af296 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1228,7 +1228,7 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
SanitizerScope SanScope(this);
llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
- if (ClArrayBoundsPseudoFn && CheckDI) {
+ if ((ClArrayBoundsPseudoFn || CGM.getCodeGenOpts().SanitizeAddPseudoFunctions.has(SanitizerKind::SO_ArrayBounds)) && CheckDI) {
CheckDI = getDebugInfo()->CreateSyntheticInlineAt(
Builder.getCurrentDebugLocation(), "__ubsan_check_array_bounds");
}
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index ff08bffdbde1f..fd456ea0674af 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -76,6 +76,7 @@ static const SanitizerMask MergeDefault =
SanitizerKind::Undefined | SanitizerKind::Vptr;
static const SanitizerMask TrappingDefault =
SanitizerKind::CFI | SanitizerKind::LocalBounds;
+static const SanitizerMask AddPseudoFunctionsDefault;
static const SanitizerMask CFIClasses =
SanitizerKind::CFIVCall | SanitizerKind::CFINVCall |
SanitizerKind::CFIMFCall | SanitizerKind::CFIDerivedCast |
@@ -738,6 +739,13 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
// Parse -fno-sanitize-top-hot flags
SkipHotCutoffs = parseSanitizeSkipHotCutoffArgs(D, Args, DiagnoseErrors);
+ // Parse -f(no-)?sanitize-add-pseudo-functions flags
+ SanitizerMask AddPseudoFunctionsKinds =
+ parseSanitizeArgs(D, Args, DiagnoseErrors, AddPseudoFunctionsDefault, {}, {},
+ options::OPT_fsanitize_add_pseudo_functions_EQ,
+ options::OPT_fno_sanitize_add_pseudo_functions_EQ);
+ AddPseudoFunctionsKinds &= Kinds;
+
// Setup ignorelist files.
// Add default ignorelist from resource directory for activated sanitizers,
// and validate special case lists format.
@@ -1157,6 +1165,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
MergeHandlers.Mask |= MergeKinds;
+ AddPseudoFunctions.Mask |= AddPseudoFunctionsKinds;
+
// Zero out SkipHotCutoffs for unused sanitizers
SkipHotCutoffs.clear(~Sanitizers.Mask);
}
@@ -1335,6 +1345,10 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
CmdArgs.push_back(
Args.MakeArgString("-fsanitize-skip-hot-cutoff=" + SkipHotCutoffsStr));
+ if (!AddPseudoFunctions.empty())
+ CmdArgs.push_back(
+ Args.MakeArgString("-fsanitize-add-pseudo-functions=" + toString(AddPseudoFunctions)));
+
addSpecialCaseListOpt(Args, CmdArgs,
"-fsanitize-ignorelist=", UserIgnorelistFiles);
addSpecialCaseListOpt(Args, CmdArgs,
@@ -1518,7 +1532,9 @@ SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
A->getOption().matches(options::OPT_fno_sanitize_trap_EQ) ||
A->getOption().matches(options::OPT_fsanitize_merge_handlers_EQ) ||
- A->getOption().matches(options::OPT_fno_sanitize_merge_handlers_EQ)) &&
+ A->getOption().matches(options::OPT_fno_sanitize_merge_handlers_EQ) ||
+ A->getOption().matches(options::OPT_fsanitize_add_pseudo_functions_EQ) ||
+ A->getOption().matches(options::OPT_fno_sanitize_add_pseudo_functions_EQ)) &&
"Invalid argument in parseArgValues!");
SanitizerMask Kinds;
for (int i = 0, n = A->getNumValues(); i != n; ++i) {
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index c7d11e6027ccf..d79b0546d41ce 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1838,6 +1838,10 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
for (std::string Sanitizer : Values)
GenerateArg(Consumer, OPT_fsanitize_skip_hot_cutoff_EQ, Sanitizer);
+ for (StringRef Sanitizer :
+ serializeSanitizerKinds(Opts.SanitizeAddPseudoFunctions))
+ GenerateArg(Consumer, OPT_fsanitize_add_pseudo_functions_EQ, Sanitizer);
+
if (!Opts.EmitVersionIdentMetadata)
GenerateArg(Consumer, OPT_Qn);
@@ -2332,6 +2336,10 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
"-fsanitize-skip-hot-cutoff=",
Args.getAllArgValues(OPT_fsanitize_skip_hot_cutoff_EQ), Diags);
+ parseSanitizerKinds("-fsanitize-add-pseudo-functions=",
+ Args.getAllArgValues(OPT_fsanitize_add_pseudo_functions_EQ),
+ Diags, Opts.SanitizeAddPseudoFunctions);
+
Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
if (!LangOpts->CUDAIsDevice)
diff --git a/clang/test/CodeGen/bounds-checking-debuginfo.c b/clang/test/CodeGen/bounds-checking-debuginfo.c
index 4f5ba2b76eeeb..f31a40d86dac4 100644
--- a/clang/test/CodeGen/bounds-checking-debuginfo.c
+++ b/clang/test/CodeGen/bounds-checking-debuginfo.c
@@ -1,7 +1,7 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
-// RUN: %clang_cc1 -mllvm -array-bounds-pseudofn -emit-llvm -fdebug-prefix-map=%S/= -fno-ident -fdebug-compilation-dir=%S -fsanitize=array-bounds -fsanitize-trap=array-bounds -triple x86_64 -debug-info-kind=limited %s -o - | FileCheck --check-prefix=CHECK-TRAP %s
-// RUN: %clang_cc1 -mllvm -array-bounds-pseudofn -emit-llvm -fdebug-prefix-map=%S/= -fno-ident -fdebug-compilation-dir=%S -fsanitize=array-bounds -triple x86_64 -debug-info-kind=limited %s -o - | FileCheck --check-prefix=CHECK-NOTRAP %s
+// RUN: %clang_cc1 -emit-llvm -fdebug-prefix-map=%S/= -fno-ident -fdebug-compilation-dir=%S -fsanitize=array-bounds -fsanitize-trap=array-bounds -fsanitize-add-pseudo-functions=array-bounds -triple x86_64 -debug-info-kind=limited %s -o - | FileCheck --check-prefix=CHECK-TRAP %s
+// RUN: %clang_cc1 -emit-llvm -fdebug-prefix-map=%S/= -fno-ident -fdebug-compilation-dir=%S -fsanitize=array-bounds -fsanitize-add-pseudo-functions=array-bounds -triple x86_64 -debug-info-kind=limited %s -o - | FileCheck --check-prefix=CHECK-NOTRAP %s
int f();
void d(double*);
diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c
index eb72140fb1315..ca58d4a50bc79 100644
--- a/clang/test/Driver/fsanitize.c
+++ b/clang/test/Driver/fsanitize.c
@@ -1,3 +1,5 @@
+// * Test -fsanitize-trap */
+
// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-trap=signed-integer-overflow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP2
// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
@@ -9,6 +11,9 @@
// CHECK-UNDEFINED-TRAP: "-fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound"
// CHECK-UNDEFINED-TRAP2: "-fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,unreachable,vla-bound"
+
+// * Test -fsanitize-merge *
+
// The trailing -fsanitize-merge takes precedence
// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-MERGE
// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-merge %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-MERGE
@@ -62,6 +67,59 @@
// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-merge=signed-integer-overflow -fno-sanitize-merge=undefined -fsanitize-merge=alignment,null %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-MERGE5
// CHECK-UNDEFINED-MERGE5: "-fsanitize-merge=alignment,null"
+
+// * Test -fsanitize-add-pseudo-functions *
+
+// The trailing -fsanitize-add-pseudo-functions takes precedence
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions -fsanitize-add-pseudo-functions %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions -fsanitize-add-pseudo-functions=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions=undefined -fsanitize-add-pseudo-functions %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions=undefined -fsanitize-add-pseudo-functions=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions=signed-integer-overflow -fsanitize-add-pseudo-functions %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions=bool -fsanitize-add-pseudo-functions=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions=undefined -fsanitize-add-pseudo-functions=bool %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO
+// CHECK-UNDEFINED-PSEUDO: "-fsanitize-add-pseudo-functions=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound"
+
+// The trailing arguments (-fsanitize-add-pseudo-functions -fno-sanitize-add-pseudo-functions=signed-integer-overflow) take precedence
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions -fno-sanitize-add-pseudo-functions=signed-integer-overflow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO2
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions=undefined -fno-sanitize-add-pseudo-functions=signed-integer-overflow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO2
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions -fsanitize-add-pseudo-functions -fno-sanitize-add-pseudo-functions=signed-integer-overflow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO2
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions -fsanitize-add-pseudo-functions=undefined -fno-sanitize-add-pseudo-functions=signed-integer-overflow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO2
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions=signed-integer-overflow -fsanitize-add-pseudo-functions -fno-sanitize-add-pseudo-functions=signed-integer-overflow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO2
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions=signed-integer-overflow -fsanitize-add-pseudo-functions=undefined -fno-sanitize-add-pseudo-functions=signed-integer-overflow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO2
+// CHECK-UNDEFINED-PSEUDO2: "-fsanitize-add-pseudo-functions=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,unreachable,vla-bound"
+
+// The trailing -fno-sanitize-add-pseudo-functions takes precedence
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions %s -### 2>&1 | not FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO3
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions=undefined %s -### 2>&1 | not FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO3
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions -fno-sanitize-add-pseudo-functions=bool %s -### 2>&1 | not FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO3
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions=undefined -fno-sanitize-add-pseudo-functions=bool %s -### 2>&1 | not FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO3
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions -fno-sanitize-add-pseudo-functions %s -### 2>&1 | not FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO3
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions -fno-sanitize-add-pseudo-functions=undefined %s -### 2>&1 | not FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO3
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions=undefined -fno-sanitize-add-pseudo-functions %s -### 2>&1 | not FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO3
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions=undefined -fno-sanitize-add-pseudo-functions=undefined %s -### 2>&1 | not FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO3
+// CHECK-UNDEFINED-PSEUDO3: "-fsanitize-add-pseudo-functions"
+
+// The trailing arguments (-fsanitize-add-pseudo-functions -fno-sanitize-add-pseudo-functions=alignment,null) take precedence
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions -fno-sanitize-add-pseudo-functions=alignment,null %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO4
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fsanitize-add-pseudo-functions=undefined -fno-sanitize-add-pseudo-functions=alignment,null %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO4
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions -fsanitize-add-pseudo-functions -fno-sanitize-add-pseudo-functions=alignment,null %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-PSEUDO4
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -fno-sanitize-add-pseudo-functions -fsanitize-add-pseudo-functions=undefined -fno-sanitize-add-pseudo-functions=alignment,null %s -### 2>&1 | FileChe...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
def fsanitize_add_pseudo_functions_EQ | ||
: CommaJoined<["-"], "fsanitize-add-pseudo-functions=">, | ||
Group<f_clang_Group>, | ||
HelpText<"Add pseudo-functions to checks for specified sanitizers">; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit confusing because we currently only support one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added ", if supported"
@@ -1228,7 +1228,10 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound, | |||
SanitizerScope SanScope(this); | |||
|
|||
llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation(); | |||
if (ClArrayBoundsPseudoFn && CheckDI) { | |||
if ((ClArrayBoundsPseudoFn || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add TODO to clean up mllvm flag
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be nice to make clear that SO_ArrayBounds here is the same as on line 1252
E.g. auto CurrentCheck = SO_ArrayBounds;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added CurrentCheckKind (there is already a Check
variable that contains the instructions)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would drop the Current then for symmety
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -2533,6 +2533,31 @@ def fno_sanitize_merge_handlers : Flag<["-"], "fno-sanitize-merge">, Group<f_cla | |||
Alias<fno_sanitize_merge_handlers_EQ>, AliasArgs<["all"]>, | |||
Visibility<[ClangOption, CLOption]>, | |||
HelpText<"Do not allow compiler to merge handlers for any sanitizers">; | |||
def fsanitize_add_pseudo_functions_EQ | |||
: CommaJoined<["-"], "fsanitize-add-pseudo-functions=">, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe -fsanitize-add-pseudo-functions
-> -fsanitize-pseudo-function
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-fsanitize-pseudo-function
is slightly ambiguous: it sounds like it is an option to sanitize any existing pseudo-functions, rather than sanitizers adding pseudo-functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
convention is -fsanitize-=, so I think it's not a problem.
But unless someone step in, either name is fine to me, your call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with vitaly.
-fsanitize-trap doesn't sanitize traps either
def fno_sanitize_add_pseudo_functions_EQ | ||
: CommaJoined<["-"], "fno-sanitize-add-pseudo-functions=">, | ||
Group<f_clang_Group>, | ||
HelpText<"Do not allow compiler to add pseudo-functions to checks for " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doc mention debug info?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but I'd prefer shorted name, e.g.
e.g. we have -fsanitize-trap
, not -fsanitize-report-with-trap
so -add-
is unnecessary
plural functions as well
maybe pseudofn is good enough
of fakefn?
In description ?
@fmayer would be nicer for cross-linking |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable. My main issue is the "add pseudo functions" name which isn't clear and isn't documented.
Group<f_clang_Group>, | ||
HelpText<"Do not allow compiler to add pseudo-functions to checks for " | ||
"specified sanitizers">; | ||
def fsanitize_add_pseudo_functions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit. I don't think "add pseudo functions" is very helpful name. It's not clear at all what this means. Glancing at the implementation it looks like this is adding fake inline frames in the debug info with the name __ubsan_check_array_bounds
. If the intention is to always use debug info as the implementation and to it will always annotate instrumentation a name like -fsanitize-annotate-debug-info
might be more descriptive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation should also really explain this too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a much better name. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks all for the reviews and naming suggestions! I will rename it.
Done |
@@ -1228,7 +1228,10 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound, | |||
SanitizerScope SanScope(this); | |||
|
|||
llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation(); | |||
if (ClArrayBoundsPseudoFn && CheckDI) { | |||
if ((ClArrayBoundsPseudoFn || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would drop the Current then for symmety
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the fsanitize test is failing now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making changes. I have some very minor suggestions but I'll approve now and you can decide if it's worth making my suggested changes.
HelpText<"Annotate checks with debug info for specified sanitizers, if " | ||
"supported">; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can afford to be a bit more verbose in the help text. What about something like this?
HelpText<"Annotate checks with debug info for specified sanitizers, if " | |
"supported">; | |
HelpText<"Annotate sanitizer instrumentation with extra debug info for the specified sanitizers, if " | |
"supported">; |
My thinking is
- Replace
checks
withinstrumentation
because not all instrumentation is necessarily a check. E.g. I think stack poisoning is done with instrumentation and that's not a "check". - Say "extra debug info" since this is additional information on top of normal debug info
- Add missing "the"
HelpText<"Do not allow compiler to annotate checks with debug info for " | ||
"specified sanitizers">; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HelpText<"Do not allow compiler to annotate checks with debug info for " | |
"specified sanitizers">; | |
HelpText<"Do not allow compiler to annotate checks with debug info for " | |
"the specified sanitizers">; |
@@ -399,6 +399,9 @@ class CodeGenOptions : public CodeGenOptionsBase { | |||
/// (0.0 [default] to skip none, 1.0 to skip all). | |||
SanitizerMaskCutoffs SanitizeSkipHotCutoffs; | |||
|
|||
/// Set of sanitizer checks that will be annotated with debug info. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Set of sanitizer checks that will be annotated with debug info. | |
/// Set of sanitizer checks that will be annotated with extra debug info. |
debug info for the specified sanitizers ..." per delcypher's feedback
Thanks, I like your wording improvements! I've modified the HelpText and comment. |
Fixed |
YOLO |
@fmayer introduced '-mllvm -array-bounds-pseudofn' (#128977) to make it easier to see why crashes occurred, and to estimate with a profiler the cycles spent on these array-bounds checks. This functionality could be usefully generalized to other checks in future work.
This patch adds the plumbing for -fsanitize-annotate-debug-info, and connects it to the existing array-bounds-pseudo-fn functionality i.e., -fsanitize-annotate-debug-info=array-bounds can be used as a replacement for '-mllvm -array-bounds-pseudofn', though we do not yet delete the latter.
Note: we replaced '-mllvm -array-bounds-pseudofn' in clang/test/CodeGen/bounds-checking-debuginfo.c, because adding test cases would modify the line numbers in the test assertions, and therefore obscure that the test output is the same between '-mllvm -array-bounds-pseudofn' and -fsanitize-annotate-debug-info=array-bounds.