aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-06-21 14:00:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-06-21 14:00:56 +0000
commit2e645aa5697838f16ec570eb07c2bee7e13d0e0b (patch)
treea764184c2fc9486979b074250b013a0937ee64e5 /lib/CodeGen/CGClass.cpp
parent798321d8eb5630cd4a8f490a4f25e32ef195fb07 (diff)
downloadsrc-2e645aa5697838f16ec570eb07c2bee7e13d0e0b.tar.gz
src-2e645aa5697838f16ec570eb07c2bee7e13d0e0b.zip
Vendor import of clang trunk r240225:vendor/clang/clang-trunk-r240225
Notes
Notes: svn path=/vendor/clang/dist/; revision=284679 svn path=/vendor/clang/clang-trunk-r240225/; revision=284680; tag=vendor/clang/clang-trunk-r240225
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r--lib/CodeGen/CGClass.cpp66
1 files changed, 44 insertions, 22 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index cd75da276287..1d2b7875d8f7 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -370,25 +370,25 @@ namespace {
/// A visitor which checks whether an initializer uses 'this' in a
/// way which requires the vtable to be properly set.
- struct DynamicThisUseChecker : EvaluatedExprVisitor<DynamicThisUseChecker> {
- typedef EvaluatedExprVisitor<DynamicThisUseChecker> super;
+ struct DynamicThisUseChecker : ConstEvaluatedExprVisitor<DynamicThisUseChecker> {
+ typedef ConstEvaluatedExprVisitor<DynamicThisUseChecker> super;
bool UsesThis;
- DynamicThisUseChecker(ASTContext &C) : super(C), UsesThis(false) {}
+ DynamicThisUseChecker(const ASTContext &C) : super(C), UsesThis(false) {}
// Black-list all explicit and implicit references to 'this'.
//
// Do we need to worry about external references to 'this' derived
// from arbitrary code? If so, then anything which runs arbitrary
// external code might potentially access the vtable.
- void VisitCXXThisExpr(CXXThisExpr *E) { UsesThis = true; }
+ void VisitCXXThisExpr(const CXXThisExpr *E) { UsesThis = true; }
};
}
static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) {
DynamicThisUseChecker Checker(C);
- Checker.Visit(const_cast<Expr*>(Init));
+ Checker.Visit(Init);
return Checker.UsesThis;
}
@@ -2134,17 +2134,21 @@ LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD) {
}
void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXMethodDecl *MD,
- llvm::Value *VTable) {
+ llvm::Value *VTable,
+ CFITypeCheckKind TCK,
+ SourceLocation Loc) {
const CXXRecordDecl *ClassDecl = MD->getParent();
if (!SanOpts.has(SanitizerKind::CFICastStrict))
ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl);
- EmitVTablePtrCheck(ClassDecl, VTable);
+ EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc);
}
void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T,
llvm::Value *Derived,
- bool MayBeNull) {
+ bool MayBeNull,
+ CFITypeCheckKind TCK,
+ SourceLocation Loc) {
if (!getLangOpts().CPlusPlus)
return;
@@ -2184,7 +2188,7 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T,
}
llvm::Value *VTable = GetVTablePtr(Derived, Int8PtrTy);
- EmitVTablePtrCheck(ClassDecl, VTable);
+ EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc);
if (MayBeNull) {
Builder.CreateBr(ContBlock);
@@ -2193,11 +2197,15 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T,
}
void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
- llvm::Value *VTable) {
+ llvm::Value *VTable,
+ CFITypeCheckKind TCK,
+ SourceLocation Loc) {
// FIXME: Add blacklisting scheme.
if (RD->isInStdNamespace())
return;
+ SanitizerScope SanScope(this);
+
std::string OutName;
llvm::raw_string_ostream Out(OutName);
CGM.getCXXABI().getMangleContext().mangleCXXVTableBitSet(RD, Out);
@@ -2205,20 +2213,34 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
llvm::Value *BitSetName = llvm::MetadataAsValue::get(
getLLVMContext(), llvm::MDString::get(getLLVMContext(), Out.str()));
- llvm::Value *BitSetTest = Builder.CreateCall(
- CGM.getIntrinsic(llvm::Intrinsic::bitset_test),
- {Builder.CreateBitCast(VTable, CGM.Int8PtrTy), BitSetName});
+ llvm::Value *CastedVTable = Builder.CreateBitCast(VTable, Int8PtrTy);
+ llvm::Value *BitSetTest =
+ Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::bitset_test),
+ {CastedVTable, BitSetName});
- llvm::BasicBlock *ContBlock = createBasicBlock("vtable.check.cont");
- llvm::BasicBlock *TrapBlock = createBasicBlock("vtable.check.trap");
-
- Builder.CreateCondBr(BitSetTest, ContBlock, TrapBlock);
-
- EmitBlock(TrapBlock);
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::trap), {});
- Builder.CreateUnreachable();
+ SanitizerMask M;
+ switch (TCK) {
+ case CFITCK_VCall:
+ M = SanitizerKind::CFIVCall;
+ break;
+ case CFITCK_NVCall:
+ M = SanitizerKind::CFINVCall;
+ break;
+ case CFITCK_DerivedCast:
+ M = SanitizerKind::CFIDerivedCast;
+ break;
+ case CFITCK_UnrelatedCast:
+ M = SanitizerKind::CFIUnrelatedCast;
+ break;
+ }
- EmitBlock(ContBlock);
+ llvm::Constant *StaticData[] = {
+ EmitCheckSourceLocation(Loc),
+ EmitCheckTypeDescriptor(QualType(RD->getTypeForDecl(), 0)),
+ llvm::ConstantInt::get(Int8Ty, TCK),
+ };
+ EmitCheck(std::make_pair(BitSetTest, M), "cfi_bad_type", StaticData,
+ CastedVTable);
}
// FIXME: Ideally Expr::IgnoreParenNoopCasts should do this, but it doesn't do