From a8dedff39c4118d4eb1c29fe745ed47f6bbaddb8 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Mon, 31 Jul 2017 20:45:14 +0000 Subject: [PATCH] Fix logic for generating llvm.type.test()s CodeGenFunction::EmitTypeMetadataCodeForVCall() could output an llvm.assume(llvm.type.test())when CFI was enabled, optimizing out the vcall check. This case was only reached when: 1) CFI-vcall was enabled, 2) -fwhole-program-tables was specified, and 3) -fno-sanitize-trap=cfi-vcall was specified. Patch by Vlad Tsyrklevich! Differential Revision: https://reviews.llvm.org/D36013 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@309622 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGClass.cpp | 9 ++++----- test/CodeGenCXX/cfi-vcall-no-trap.cpp | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 test/CodeGenCXX/cfi-vcall-no-trap.cpp diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 50d702c622..e27e518c7e 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -2523,8 +2523,10 @@ LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD) { void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc) { - if (CGM.getCodeGenOpts().WholeProgramVTables && - CGM.HasHiddenLTOVisibility(RD)) { + if (SanOpts.has(SanitizerKind::CFIVCall)) + EmitVTablePtrCheckForCall(RD, VTable, CodeGenFunction::CFITCK_VCall, Loc); + else if (CGM.getCodeGenOpts().WholeProgramVTables && + CGM.HasHiddenLTOVisibility(RD)) { llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)); llvm::Value *TypeId = @@ -2536,9 +2538,6 @@ void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, {CastedVTable, TypeId}); Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest); } - - if (SanOpts.has(SanitizerKind::CFIVCall)) - EmitVTablePtrCheckForCall(RD, VTable, CodeGenFunction::CFITCK_VCall, Loc); } void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, diff --git a/test/CodeGenCXX/cfi-vcall-no-trap.cpp b/test/CodeGenCXX/cfi-vcall-no-trap.cpp new file mode 100644 index 0000000000..dbfe558065 --- /dev/null +++ b/test/CodeGenCXX/cfi-vcall-no-trap.cpp @@ -0,0 +1,15 @@ +// Only output llvm.assume(llvm.type.test()) if cfi-vcall is disabled and whole-program-vtables is enabled +// RUN: %clang_cc1 -fvisibility hidden -fsanitize=cfi-vcall -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=CFI %s +// RUN: %clang_cc1 -fvisibility hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOCFI %s + +struct S1 { + virtual void f(); +}; + +// CHECK: define{{.*}}s1f +// CHECK: llvm.type.test +// CFI-NOT: llvm.assume +// NOCFI: llvm.assume +void s1f(S1 *s1) { + s1->f(); +} -- 2.40.0