diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2017-10-13 21:02:16 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2017-10-13 21:02:16 +0000 |
commit | 39ba348795c0552ee59468805f19363b588f74ca (patch) | |
tree | 6c988d3b8a95b3601200293cb2c1df1da27131aa /lib/Transforms/IPO | |
parent | 7aa4aa680d6b4a1c5ce3e08f4a5c6885bbf87064 (diff) |
LowerTypeTests: Give imported symbols a type with size 0 so that they are not assumed not to alias.
It is possible for both a base and a derived class to be satisfied
with a unique vtable. If a program contains casts of the same pointer
to both of those types, the CFI checks will be lowered to this
(with ThinLTO):
if (p != &__typeid_base_global_addr)
trap();
if (p != &__typeid_derived_global_addr)
trap();
The optimizer may then use the first condition combined
with the assumption that __typeid_base_global_addr and
__typeid_derived_global_addr may not alias to optimize away the second
comparison, resulting in an unconditional trap.
This patch fixes the bug by giving imported globals the type [0 x i8]*,
which prevents the optimizer from assuming that they do not alias.
Differential Revision: https://reviews.llvm.org/D38873
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315753 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO')
-rw-r--r-- | lib/Transforms/IPO/LowerTypeTests.cpp | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/lib/Transforms/IPO/LowerTypeTests.cpp b/lib/Transforms/IPO/LowerTypeTests.cpp index 027f426649c..ab205f4285e 100644 --- a/lib/Transforms/IPO/LowerTypeTests.cpp +++ b/lib/Transforms/IPO/LowerTypeTests.cpp @@ -259,6 +259,7 @@ class LowerTypeTestsModule { IntegerType *Int1Ty = Type::getInt1Ty(M.getContext()); IntegerType *Int8Ty = Type::getInt8Ty(M.getContext()); PointerType *Int8PtrTy = Type::getInt8PtrTy(M.getContext()); + ArrayType *Int8Arr0Ty = ArrayType::get(Type::getInt8Ty(M.getContext()), 0); IntegerType *Int32Ty = Type::getInt32Ty(M.getContext()); PointerType *Int32PtrTy = PointerType::getUnqual(Int32Ty); IntegerType *Int64Ty = Type::getInt64Ty(M.getContext()); @@ -803,10 +804,13 @@ LowerTypeTestsModule::importTypeId(StringRef TypeId) { TIL.TheKind = TTRes.TheKind; auto ImportGlobal = [&](StringRef Name) { - Constant *C = - M.getOrInsertGlobal(("__typeid_" + TypeId + "_" + Name).str(), Int8Ty); + // Give the global a type of length 0 so that it is not assumed not to alias + // with any other global. + Constant *C = M.getOrInsertGlobal(("__typeid_" + TypeId + "_" + Name).str(), + Int8Arr0Ty); if (auto *GV = dyn_cast<GlobalVariable>(C)) GV->setVisibility(GlobalValue::HiddenVisibility); + C = ConstantExpr::getBitCast(C, Int8PtrTy); return C; }; |