diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-03-27 15:27:20 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-03-27 15:27:20 +0000 |
commit | a39fc6dd2afab9cb14286e00f2f6ef2370002c40 (patch) | |
tree | f69a30a34f74928d8628a0163d866a38de7a320e /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | 24a669d225f9cacf1cd3846e333f9690a06d1e1c (diff) | |
download | llvm-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.cpp | 30 |
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; |