aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-03-27 15:27:20 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-03-27 15:27:20 +0000
commita39fc6dd2afab9cb14286e00f2f6ef2370002c40 (patch)
treef69a30a34f74928d8628a0163d866a38de7a320e /clang/lib/CodeGen/CodeGenModule.cpp
parent24a669d225f9cacf1cd3846e333f9690a06d1e1c (diff)
downloadllvm-a39fc6dd2afab9cb14286e00f2f6ef2370002c40.zip
llvm-a39fc6dd2afab9cb14286e00f2f6ef2370002c40.tar.gz
llvm-a39fc6dd2afab9cb14286e00f2f6ef2370002c40.tar.bz2
Handle and warn on aliases to weak aliases.
This produces valid IR now that llvm rejects aliases to weak aliases and warns the user that the resolution is not changed if the weak alias is overridden. llvm-svn: 204935
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp30
1 files changed, 29 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c0fbdbe..addf8d0 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -208,6 +208,9 @@ void CodeGenModule::applyReplacements() {
}
void CodeGenModule::checkAliases() {
+ // Check if the constructed aliases are well formed. It is really unfortunate
+ // that we have to do this in CodeGen, but we only construct mangled names
+ // and aliases during codegen.
bool Error = false;
for (std::vector<GlobalDecl>::iterator I = Aliases.begin(),
E = Aliases.end(); I != E; ++I) {
@@ -217,7 +220,7 @@ void CodeGenModule::checkAliases() {
StringRef MangledName = getMangledName(GD);
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
llvm::GlobalAlias *Alias = cast<llvm::GlobalAlias>(Entry);
- llvm::GlobalValue *GV = Alias->resolveAliasedGlobal(/*stopOnWeak*/ false);
+ llvm::GlobalValue *GV = Alias->getAliasedGlobal();
if (!GV) {
Error = true;
getDiags().Report(AA->getLocation(), diag::err_cyclic_alias);
@@ -225,6 +228,31 @@ void CodeGenModule::checkAliases() {
Error = true;
getDiags().Report(AA->getLocation(), diag::err_alias_to_undefined);
}
+
+ // We have to handle alias to weak aliases in here. LLVM itself disallows
+ // this since the object semantics would not match the IL one. For
+ // compatibility with gcc we implement it by just pointing the alias
+ // to its aliasee's aliasee. We also warn, since the user is probably
+ // expecting the link to be weak.
+ llvm::Constant *Aliasee = Alias->getAliasee();
+ llvm::GlobalValue *AliaseeGV;
+ if (auto CE = dyn_cast<llvm::ConstantExpr>(Aliasee)) {
+ assert((CE->getOpcode() == llvm::Instruction::BitCast ||
+ CE->getOpcode() == llvm::Instruction::AddrSpaceCast) &&
+ "Unsupported aliasee");
+ AliaseeGV = cast<llvm::GlobalValue>(CE->getOperand(0));
+ } else {
+ AliaseeGV = cast<llvm::GlobalValue>(Aliasee);
+ }
+ if (auto GA = dyn_cast<llvm::GlobalAlias>(AliaseeGV)) {
+ if (GA->mayBeOverridden()) {
+ getDiags().Report(AA->getLocation(), diag::warn_alias_to_weak_alias)
+ << GA->getAliasedGlobal()->getName() << GA->getName();
+ Aliasee = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
+ GA->getAliasee(), Alias->getType());
+ Alias->setAliasee(Aliasee);
+ }
+ }
}
if (!Error)
return;