diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2018-10-12 17:22:10 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2018-10-12 17:22:10 +0000 |
commit | 92d8a29ca0d506cea28718644527c4711ee3e694 (patch) | |
tree | bc12494cc31b7eaba6255a3e80b3460c60520e40 /clang/lib/CodeGen/CGObjCMac.cpp | |
parent | 727891c9182aabd39cef9998ab7be365cb5ab19b (diff) | |
download | bcm5719-llvm-92d8a29ca0d506cea28718644527c4711ee3e694.tar.gz bcm5719-llvm-92d8a29ca0d506cea28718644527c4711ee3e694.zip |
[CodeGen] Handle extern references to OBJC_CLASS_$_*
Some ObjC users declare a extern variable named OBJC_CLASS_$_Foo, then use it's
address as a Class. I.e., one could define isInstanceOfF:
BOOL isInstanceOfF(id c) {
extern void OBJC_CLASS_$_F;
return [c class] == (Class)&OBJC_CLASS_$_F;
}
This leads to asserts in clang CodeGen if there is an @implementation of F in
the same TU as an instance of this pattern, because CodeGen assumes that a
variable named OBJC_CLASS_$_* has the right type. This commit fixes the problem
by RAUWing the old (incorrectly typed) global with a new global, then removing
the old global.
rdar://45077269
Differential revision: https://reviews.llvm.org/D53154
llvm-svn: 344373
Diffstat (limited to 'clang/lib/CodeGen/CGObjCMac.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 2b6d895f93c..fffa62d7d23 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -7188,15 +7188,21 @@ CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name, Weak ? llvm::GlobalValue::ExternalWeakLinkage : llvm::GlobalValue::ExternalLinkage; - - llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); - if (!GV) { - GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy, - false, L, nullptr, Name); + if (!GV || GV->getType() != ObjCTypes.ClassnfABITy->getPointerTo()) { + auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L, + nullptr, Name); if (DLLImport) - GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + + if (GV) { + GV->replaceAllUsesWith( + llvm::ConstantExpr::getBitCast(NewGV, GV->getType())); + GV->eraseFromParent(); + } + GV = NewGV; + CGM.getModule().getGlobalList().push_back(GV); } assert(GV->getLinkage() == L); |