summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-10-22 19:26:13 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-10-22 19:26:13 +0000
commit208b5c0fa5caa5716a78a04e856bf39ef8f38732 (patch)
tree0d11ed81ffe224ee4c8a2a5e589092213952e6ca /clang/lib/CodeGen/CodeGenModule.cpp
parentbe38b9e15fde35e15cf87f28540bd34edfce4db6 (diff)
downloadbcm5719-llvm-208b5c0fa5caa5716a78a04e856bf39ef8f38732.tar.gz
bcm5719-llvm-208b5c0fa5caa5716a78a04e856bf39ef8f38732.zip
New fix for pr17535.
This is a fixed version of r193161. In order to handle void foo() __attribute__((alias("bar"))); void bar() {} void zed() __attribute__((alias("foo"))); it is not enough to delay aliases to the end of the TU, we have to do two passes over them to find if they are defined or not. This can be implemented by producing alias as we go and just doing the second pass at the end. This has the advantage that other parts of clang that were expecting alias to be processed in order don't have to be changed. This patch also handles cyclic aliases. llvm-svn: 193188
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 96ae437ff46..d0f34dddca3 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -37,6 +37,7 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/CallingConv.h"
@@ -171,8 +172,42 @@ void CodeGenModule::createCUDARuntime() {
CUDARuntime = CreateNVCUDARuntime(*this);
}
+void CodeGenModule::checkAliases() {
+ bool Error = false;
+ for (std::vector<GlobalDecl>::iterator I = Aliases.begin(),
+ E = Aliases.end(); I != E; ++I) {
+ const GlobalDecl &GD = *I;
+ const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
+ const AliasAttr *AA = D->getAttr<AliasAttr>();
+ StringRef MangledName = getMangledName(GD);
+ llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
+ llvm::GlobalAlias *Alias = cast<llvm::GlobalAlias>(Entry);
+ llvm::GlobalValue *GV = Alias->getAliasedGlobal();
+ if (GV->isDeclaration()) {
+ Error = true;
+ getDiags().Report(AA->getLocation(), diag::err_alias_to_undefined);
+ } else if (!Alias->resolveAliasedGlobal(/*stopOnWeak*/ false)) {
+ Error = true;
+ getDiags().Report(AA->getLocation(), diag::err_cyclic_alias);
+ }
+ }
+ if (!Error)
+ return;
+
+ for (std::vector<GlobalDecl>::iterator I = Aliases.begin(),
+ E = Aliases.end(); I != E; ++I) {
+ const GlobalDecl &GD = *I;
+ StringRef MangledName = getMangledName(GD);
+ llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
+ llvm::GlobalAlias *Alias = cast<llvm::GlobalAlias>(Entry);
+ Alias->replaceAllUsesWith(llvm::UndefValue::get(Alias->getType()));
+ Alias->eraseFromParent();
+ }
+}
+
void CodeGenModule::Release() {
EmitDeferred();
+ checkAliases();
EmitCXXGlobalInitFunc();
EmitCXXGlobalDtorFunc();
EmitCXXThreadLocalInitFunc();
@@ -2088,6 +2123,8 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
if (Entry && !Entry->isDeclaration())
return;
+ Aliases.push_back(GD);
+
llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
// Create a reference to the named value. This ensures that it is emitted
OpenPOWER on IntegriCloud