From f31ea30694af66ffbd7e2e265090c97e1b91e8d9 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Wed, 3 Feb 2016 22:18:55 +0000 Subject: [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 llvm-svn: 259716 --- clang/lib/CodeGen/CGClass.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'clang/lib/CodeGen/CGClass.cpp') diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 0853d6aa1fb..2adb74aa0fc 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/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 -- cgit v1.2.3