-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[ubsan] Assert that each check only has one SanitizerKind #122392
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
The `Checked` parameter of `CodeGenFunction::EmitCheck` is of type `ArrayRef<std::pair<llvm::Value *, SanitizerMask>>`. In the general case, SanitizerMask can denote that zero or more sanitizers are enabled, but I believe (from tests and inspecting the code) that `EmitCheck` assumes exactly one sanitizer enabled per SanitizerMask. This patch adds an assertion for this invariant. This is not intended to change the functionality of the code, but will make it easier for maintainers to reason about and extend the `EmitCheck` function.
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Thurston Dang (thurstond) ChangesThe This is not intended to change the functionality of UBSan, but will make it easier for maintainers to reason about and extend the Full diff: https://github.com/llvm/llvm-project/pull/122392.diff 1 Files Affected:
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 1bad7a722da07a..792fe05025e393 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3603,6 +3603,8 @@ void CodeGenFunction::EmitCheck(
llvm::Value *TrapCond = nullptr;
bool NoMerge = false;
for (int i = 0, n = Checked.size(); i < n; ++i) {
+ assert(Checked[i].second.isPowerOf2());
+
llvm::Value *Check = Checked[i].first;
// -fsanitize-trap= overrides -fsanitize-recover=.
llvm::Value *&Cond =
|
@@ -3603,6 +3603,8 @@ void CodeGenFunction::EmitCheck( | |||
llvm::Value *TrapCond = nullptr; | |||
bool NoMerge = false; | |||
for (int i = 0, n = Checked.size(); i < n; ++i) { |
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 instead switch SanitizerMask -> SanitizerOrdinal?
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 `Checked` parameter of `CodeGenFunction::EmitCheck` is of type `ArrayRef<std::pair<llvm::Value *, SanitizerMask>>`, which is overly generalized: SanitizerMask can denote that zero or more sanitizers are enabled, but `EmitCheck` requires that exactly one sanitizer is specified in the SanitizerMask (e.g., `SanitizeTrap.has(Checked[i].second)` enforces that). This patch replaces SanitizerMask with SanitizerOrdinal for `EmitCheck` and code that calls it transitively. This should not affect the behavior of UBSan, but it has the advantage that specifying the wrong number of sanitizers in `Checked[i].second` will be detected as a compile-time error, rather than a runtime assertion failure. Suggested by Vitaly in llvm#122392 as an alternative to adding an explicit runtime assertion that the SanitizerMask contains exactly one sanitizer.
…heck (exactly one sanitizer is required) (#122511) The `Checked` parameter of `CodeGenFunction::EmitCheck` is of type `ArrayRef<std::pair<llvm::Value *, SanitizerMask>>`, which is overly generalized: SanitizerMask can denote that zero or more sanitizers are enabled, but `EmitCheck` requires that exactly one sanitizer is specified in the SanitizerMask (e.g., `SanitizeTrap.has(Checked[i].second)` enforces that). This patch replaces SanitizerMask with SanitizerOrdinal in the `Checked` parameter of `EmitCheck` and code that transitively relies on it. This should not affect the behavior of UBSan, but it has the advantages that: - the code is clearer: it avoids ambiguity in EmitCheck about what to do if multiple bits are set - specifying the wrong number of sanitizers in `Checked[i].second` will be detected as a compile-time error, rather than a runtime assertion failure Suggested by Vitaly in #122392 as an alternative to adding an explicit runtime assertion that the SanitizerMask contains exactly one sanitizer.
…k for EmitCheck (exactly one sanitizer is required) (#122511) The `Checked` parameter of `CodeGenFunction::EmitCheck` is of type `ArrayRef<std::pair<llvm::Value *, SanitizerMask>>`, which is overly generalized: SanitizerMask can denote that zero or more sanitizers are enabled, but `EmitCheck` requires that exactly one sanitizer is specified in the SanitizerMask (e.g., `SanitizeTrap.has(Checked[i].second)` enforces that). This patch replaces SanitizerMask with SanitizerOrdinal in the `Checked` parameter of `EmitCheck` and code that transitively relies on it. This should not affect the behavior of UBSan, but it has the advantages that: - the code is clearer: it avoids ambiguity in EmitCheck about what to do if multiple bits are set - specifying the wrong number of sanitizers in `Checked[i].second` will be detected as a compile-time error, rather than a runtime assertion failure Suggested by Vitaly in llvm/llvm-project#122392 as an alternative to adding an explicit runtime assertion that the SanitizerMask contains exactly one sanitizer.
…heck (exactly one sanitizer is required) (llvm#122511) The `Checked` parameter of `CodeGenFunction::EmitCheck` is of type `ArrayRef<std::pair<llvm::Value *, SanitizerMask>>`, which is overly generalized: SanitizerMask can denote that zero or more sanitizers are enabled, but `EmitCheck` requires that exactly one sanitizer is specified in the SanitizerMask (e.g., `SanitizeTrap.has(Checked[i].second)` enforces that). This patch replaces SanitizerMask with SanitizerOrdinal in the `Checked` parameter of `EmitCheck` and code that transitively relies on it. This should not affect the behavior of UBSan, but it has the advantages that: - the code is clearer: it avoids ambiguity in EmitCheck about what to do if multiple bits are set - specifying the wrong number of sanitizers in `Checked[i].second` will be detected as a compile-time error, rather than a runtime assertion failure Suggested by Vitaly in llvm#122392 as an alternative to adding an explicit runtime assertion that the SanitizerMask contains exactly one sanitizer.
The
Checked
parameter ofCodeGenFunction::EmitCheck
is of typeArrayRef<std::pair<llvm::Value *, SanitizerMask>>
. In the general case, SanitizerMask is used to denote that zero or more sanitizers are enabled, but I believe thatEmitCheck
assumes there is exactly one sanitizer enabled per SanitizerMask (e.g.,SanitizeTrap.has(Checked[i].second)
is called, whereby.has
checks that there is only one sanitizer enabled). This patch adds an assertion for this invariant.This is not intended to change the functionality of UBSan, but will make it easier for maintainers to reason about and extend the
EmitCheck
function.