[cfi] Don't emit checks for disabled CFI kinds.
In the cross-DSO CFI mode clang emits __cfi_check_fail that handles
errors triggered from other modules with targets in the current
module. With this change, __cfi_check_fail will handle errors for
CFI kinds that are not enabled in the current module as if they
have the trapping behaviour (-fsanitize-trap=...).
This fixes a bug where some combinations of -fsanitize* flags may
result in a link failure due to a missing sanitizer runtime library
for the diagnostic calls in __cfi_check_fail.
llvm-svn: 263578
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index ccda7f4..1b99f10 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2479,16 +2479,12 @@
assert(JointCond);
CheckRecoverableKind RecoverKind = getRecoverableKind(Checked[0].second);
- // In cross-DSO CFI mode this code is used to generate __cfi_check_fail, which
- // includes all checks, even those that are not in SanOpts.
- assert(CGM.getCodeGenOpts().SanitizeCfiCrossDso ||
- SanOpts.has(Checked[0].second));
+ assert(SanOpts.has(Checked[0].second));
#ifndef NDEBUG
for (int i = 1, n = Checked.size(); i < n; ++i) {
assert(RecoverKind == getRecoverableKind(Checked[i].second) &&
"All recoverable kinds in a single check must be same!");
- assert(CGM.getCodeGenOpts().SanitizeCfiCrossDso ||
- SanOpts.has(Checked[i].second));
+ assert(SanOpts.has(Checked[i].second));
}
#endif
@@ -2670,8 +2666,11 @@
SanitizerMask Mask = CheckKindMaskPair.second;
llvm::Value *Cond =
Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(Int8Ty, Kind));
- EmitCheck(std::make_pair(Cond, Mask), "cfi_check_fail", {},
- {Data, Addr, ValidVtable});
+ if (CGM.getLangOpts().Sanitize.has(Mask))
+ EmitCheck(std::make_pair(Cond, Mask), "cfi_check_fail", {},
+ {Data, Addr, ValidVtable});
+ else
+ EmitTrapCheck(Cond);
}
FinishFunction();