From: Chris Lattner Date: Sun, 22 Mar 2009 21:39:12 +0000 (+0000) Subject: make alias definition logic more similar to functions/globals. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=35f6c136dd5201b87831dcdacc1eb4d2c2de0744;p=clang make alias definition logic more similar to functions/globals. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67481 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index f5ce056046..21f67901d1 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -343,8 +343,8 @@ void CodeGenModule::EmitAliases() { const char *AliaseeName = AA->getAliasee().c_str(); AliaseeName = getContext().Idents.get(AliaseeName).getName(); - - + // Create a reference to the named value. This ensures that it is emitted + // if a deferred decl. llvm::Constant *Aliasee; if (isa(DeclTy)) Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, 0); @@ -352,24 +352,41 @@ void CodeGenModule::EmitAliases() { Aliasee = GetOrCreateLLVMGlobal(AliaseeName, llvm::PointerType::getUnqual(DeclTy), 0); - const char *MangledName = getMangledName(D); + // Create the new alias itself, but don't set a name yet. llvm::GlobalValue *GA = new llvm::GlobalAlias(Aliasee->getType(), llvm::Function::ExternalLinkage, - MangledName, Aliasee, &getModule()); + "", Aliasee, &getModule()); + // See if there is already something with the alias' name in the module. + const char *MangledName = getMangledName(D); llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName]; + + if (Entry && !Entry->isDeclaration()) { + // If there is a definition in the module, then it wins over the alias. + // This is dubious, but allow it to be safe. Just ignore the alias. + delete GA; + continue; + } + if (Entry) { - // If we created a dummy function for this then replace it. - GA->takeName(Entry); - - llvm::Value *Casted = - llvm::ConstantExpr::getBitCast(GA, Entry->getType()); - Entry->replaceAllUsesWith(Casted); + // If there is a declaration in the module, then we had an extern followed + // by the alias, as in: + // extern int test6(); + // ... + // int test6() __attribute__((alias("test7"))); + // + // Remove it and replace uses of it with the alias. + + Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA, + Entry->getType())); + // FIXME: What if it was attribute used? Dangling pointer from LLVMUsed. Entry->eraseFromParent(); - - Entry = GA; } + + // Now we know that there is no conflict, set the name. + Entry = GA; + GA->setName(MangledName); // Alias should never be internal or inline. SetGlobalValueAttributes(D, false, false, GA, true); diff --git a/test/CodeGen/alias.c b/test/CodeGen/alias.c index 9de1676f4d..8fa788a6a2 100644 --- a/test/CodeGen/alias.c +++ b/test/CodeGen/alias.c @@ -23,3 +23,10 @@ int foo() __attribute__((alias("foo1"))); static inline int bar1 = 42; int bar() __attribute__((alias("bar1"))); + +extern int test6(); +void test7() { test6(); } // test6 is emitted as extern. + +// test6 changes to alias. +int test6() __attribute__((alias("test7"))); +