summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-02-03 22:18:55 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-02-03 22:18:55 +0000
commit388a05440159ef6cad1fa76ceb0d28237cbc5071 (patch)
tree5cd887c783b7d830b048ae466385ab351ed5465c /lib/CodeGen/CGClass.cpp
parent9feb9642d681f1cfdcb3d3ffe3a25cd599758593 (diff)
[cfi] Safe handling of unaddressable vtable pointers (clang).
Avoid crashing when printing diagnostics for vtable-related CFI errors. In diagnostic mode, the frontend does an additional check of the vtable pointer against the set of all known vtable addresses and lets the runtime handler know if it is safe to inspect the vtable. http://reviews.llvm.org/D16823 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@259716 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r--lib/CodeGen/CGClass.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 0853d6aa1f..2adb74aa0f 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -2607,10 +2607,22 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
auto TypeId = CGM.CreateCfiIdForTypeMetadata(MD);
if (CGM.getCodeGenOpts().SanitizeCfiCrossDso && TypeId) {
EmitCfiSlowPathCheck(M, BitSetTest, TypeId, CastedVTable, StaticData);
- } else {
- EmitCheck(std::make_pair(BitSetTest, M), "cfi_check_fail", StaticData,
- CastedVTable);
+ return;
}
+
+ if (CGM.getCodeGenOpts().SanitizeTrap.has(M)) {
+ EmitTrapCheck(BitSetTest);
+ return;
+ }
+
+ llvm::Value *AllVtables = llvm::MetadataAsValue::get(
+ CGM.getLLVMContext(),
+ llvm::MDString::get(CGM.getLLVMContext(), "all-vtables"));
+ llvm::Value *ValidVtable =
+ Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::bitset_test),
+ {CastedVTable, AllVtables});
+ EmitCheck(std::make_pair(BitSetTest, M), "cfi_check_fail", StaticData,
+ {CastedVTable, ValidVtable});
}
// FIXME: Ideally Expr::IgnoreParenNoopCasts should do this, but it doesn't do