summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp80
-rw-r--r--clang/lib/CodeGen/SanitizerBlacklist.cpp4
-rw-r--r--clang/lib/CodeGen/SanitizerBlacklist.h1
3 files changed, 47 insertions, 38 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c99e669f6ff..a43cf30da73 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -544,44 +544,48 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
llvm::raw_svector_ostream Out(MangledName);
CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty.getUnqualifiedType(),
Out);
- llvm::hash_code TypeHash = hash_value(Out.str());
-
- // Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
- llvm::Value *Low = llvm::ConstantInt::get(Int64Ty, TypeHash);
- llvm::Type *VPtrTy = llvm::PointerType::get(IntPtrTy, 0);
- llvm::Value *VPtrAddr = Builder.CreateBitCast(Address, VPtrTy);
- llvm::Value *VPtrVal = Builder.CreateLoad(VPtrAddr);
- llvm::Value *High = Builder.CreateZExt(VPtrVal, Int64Ty);
-
- llvm::Value *Hash = emitHash16Bytes(Builder, Low, High);
- Hash = Builder.CreateTrunc(Hash, IntPtrTy);
-
- // Look the hash up in our cache.
- const int CacheSize = 128;
- llvm::Type *HashTable = llvm::ArrayType::get(IntPtrTy, CacheSize);
- llvm::Value *Cache = CGM.CreateRuntimeVariable(HashTable,
- "__ubsan_vptr_type_cache");
- llvm::Value *Slot = Builder.CreateAnd(Hash,
- llvm::ConstantInt::get(IntPtrTy,
- CacheSize-1));
- llvm::Value *Indices[] = { Builder.getInt32(0), Slot };
- llvm::Value *CacheVal =
- Builder.CreateLoad(Builder.CreateInBoundsGEP(Cache, Indices));
-
- // If the hash isn't in the cache, call a runtime handler to perform the
- // hard work of checking whether the vptr is for an object of the right
- // type. This will either fill in the cache and return, or produce a
- // diagnostic.
- llvm::Constant *StaticData[] = {
- EmitCheckSourceLocation(Loc),
- EmitCheckTypeDescriptor(Ty),
- CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()),
- llvm::ConstantInt::get(Int8Ty, TCK)
- };
- llvm::Value *DynamicData[] = { Address, Hash };
- EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash),
- "dynamic_type_cache_miss", StaticData, DynamicData,
- CRK_AlwaysRecoverable);
+
+ // Blacklist based on the mangled type.
+ if (!CGM.getSanitizerBlacklist().isBlacklistedType(Out.str())) {
+ llvm::hash_code TypeHash = hash_value(Out.str());
+
+ // Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
+ llvm::Value *Low = llvm::ConstantInt::get(Int64Ty, TypeHash);
+ llvm::Type *VPtrTy = llvm::PointerType::get(IntPtrTy, 0);
+ llvm::Value *VPtrAddr = Builder.CreateBitCast(Address, VPtrTy);
+ llvm::Value *VPtrVal = Builder.CreateLoad(VPtrAddr);
+ llvm::Value *High = Builder.CreateZExt(VPtrVal, Int64Ty);
+
+ llvm::Value *Hash = emitHash16Bytes(Builder, Low, High);
+ Hash = Builder.CreateTrunc(Hash, IntPtrTy);
+
+ // Look the hash up in our cache.
+ const int CacheSize = 128;
+ llvm::Type *HashTable = llvm::ArrayType::get(IntPtrTy, CacheSize);
+ llvm::Value *Cache = CGM.CreateRuntimeVariable(HashTable,
+ "__ubsan_vptr_type_cache");
+ llvm::Value *Slot = Builder.CreateAnd(Hash,
+ llvm::ConstantInt::get(IntPtrTy,
+ CacheSize-1));
+ llvm::Value *Indices[] = { Builder.getInt32(0), Slot };
+ llvm::Value *CacheVal =
+ Builder.CreateLoad(Builder.CreateInBoundsGEP(Cache, Indices));
+
+ // If the hash isn't in the cache, call a runtime handler to perform the
+ // hard work of checking whether the vptr is for an object of the right
+ // type. This will either fill in the cache and return, or produce a
+ // diagnostic.
+ llvm::Constant *StaticData[] = {
+ EmitCheckSourceLocation(Loc),
+ EmitCheckTypeDescriptor(Ty),
+ CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()),
+ llvm::ConstantInt::get(Int8Ty, TCK)
+ };
+ llvm::Value *DynamicData[] = { Address, Hash };
+ EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash),
+ "dynamic_type_cache_miss", StaticData, DynamicData,
+ CRK_AlwaysRecoverable);
+ }
}
if (Done) {
diff --git a/clang/lib/CodeGen/SanitizerBlacklist.cpp b/clang/lib/CodeGen/SanitizerBlacklist.cpp
index 60bdbe1d92e..9f1ddc8e7d7 100644
--- a/clang/lib/CodeGen/SanitizerBlacklist.cpp
+++ b/clang/lib/CodeGen/SanitizerBlacklist.cpp
@@ -46,3 +46,7 @@ bool SanitizerBlacklist::isIn(const llvm::GlobalVariable &G,
SCL->inSection("global", G.getName(), Category) ||
SCL->inSection("type", GetGlobalTypeString(G), Category);
}
+
+bool SanitizerBlacklist::isBlacklistedType(StringRef MangledTypeName) const {
+ return SCL->inSection("type", MangledTypeName);
+}
diff --git a/clang/lib/CodeGen/SanitizerBlacklist.h b/clang/lib/CodeGen/SanitizerBlacklist.h
index b8c283ccf4f..659441dfe34 100644
--- a/clang/lib/CodeGen/SanitizerBlacklist.h
+++ b/clang/lib/CodeGen/SanitizerBlacklist.h
@@ -38,6 +38,7 @@ public:
bool isIn(const llvm::Function &F) const;
bool isIn(const llvm::GlobalVariable &G,
const StringRef Category = StringRef()) const;
+ bool isBlacklistedType(StringRef MangledTypeName) const;
};
} // end namespace CodeGen
} // end namespace clang
OpenPOWER on IntegriCloud