From 463ff6d823704634d00282d5f6b0b2d435d172c6 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 25 Nov 2015 02:54:07 +0000 Subject: [PATCH] AsmParser: Make the code for parsing unnamed aliases more closely resemble that for unnamed globals. This fixes parsing of forward references to unnamed aliases. While here, remove an unnecessary isa check. llvm-svn: 254054 --- llvm/lib/AsmParser/LLParser.cpp | 45 ++++++++++++++--------- llvm/test/Assembler/alias-redefinition.ll | 2 +- llvm/test/Assembler/unnamed-alias.ll | 4 +- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 399364e5eb24..307ed397834c 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -713,6 +713,24 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, ExplicitTypeLoc, "explicit pointee type doesn't match operand's pointee type"); + GlobalValue *GVal = nullptr; + + // See if the alias was forward referenced, if so, prepare to replace the + // forward reference. + if (!Name.empty()) { + GVal = M->getNamedValue(Name); + if (GVal) { + if (!ForwardRefVals.erase(Name)) + return Error(NameLoc, "redefinition of global '@" + Name + "'"); + } + } else { + auto I = ForwardRefValIDs.find(NumberedVals.size()); + if (I != ForwardRefValIDs.end()) { + GVal = I->second.first; + ForwardRefValIDs.erase(I); + } + } + // Okay, create the alias but do not insert it into the module yet. std::unique_ptr GA( GlobalAlias::create(Ty, AddrSpace, (GlobalValue::LinkageTypes)Linkage, @@ -725,26 +743,17 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, if (Name.empty()) NumberedVals.push_back(GA.get()); - // See if this value already exists in the symbol table. If so, it is either - // a redefinition or a definition of a forward reference. - if (GlobalValue *Val = M->getNamedValue(Name)) { - // See if this was a redefinition. If so, there is no entry in - // ForwardRefVals. - auto I = ForwardRefVals.find(Name); - if (I == ForwardRefVals.end()) - return Error(NameLoc, "redefinition of global named '@" + Name + "'"); - - // Otherwise, this was a definition of forward ref. Verify that types - // agree. - if (Val->getType() != GA->getType()) - return Error(NameLoc, - "forward reference and definition of alias have different types"); + if (GVal) { + // Verify that types agree. + if (GVal->getType() != GA->getType()) + return Error( + ExplicitTypeLoc, + "forward reference and definition of alias have different types"); // If they agree, just RAUW the old value with the alias and remove the // forward ref info. - Val->replaceAllUsesWith(GA.get()); - Val->eraseFromParent(); - ForwardRefVals.erase(I); + GVal->replaceAllUsesWith(GA.get()); + GVal->eraseFromParent(); } // Insert into the module, we know its name won't collide now. @@ -809,7 +818,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, if (!Name.empty()) { GVal = M->getNamedValue(Name); if (GVal) { - if (!ForwardRefVals.erase(Name) || !isa(GVal)) + if (!ForwardRefVals.erase(Name)) return Error(NameLoc, "redefinition of global '@" + Name + "'"); } } else { diff --git a/llvm/test/Assembler/alias-redefinition.ll b/llvm/test/Assembler/alias-redefinition.ll index 7c57b63b66f6..3c36c81d8138 100644 --- a/llvm/test/Assembler/alias-redefinition.ll +++ b/llvm/test/Assembler/alias-redefinition.ll @@ -1,6 +1,6 @@ ; RUN: not llvm-as %s 2>&1 | FileCheck %s -; CHECK: error: redefinition of global named '@bar' +; CHECK: error: redefinition of global '@bar' @foo = global i32 0 @bar = alias i32, i32* @foo diff --git a/llvm/test/Assembler/unnamed-alias.ll b/llvm/test/Assembler/unnamed-alias.ll index ebba091d7700..121e54b7d079 100644 --- a/llvm/test/Assembler/unnamed-alias.ll +++ b/llvm/test/Assembler/unnamed-alias.ll @@ -5,7 +5,7 @@ @1 = private constant i32 1 ; CHECK: @1 = private constant i32 1 -@2 = private alias i32, i32* @0 -; CHECK: @2 = private alias i32, i32* @0 +@2 = private alias i32, i32* @3 +; CHECK: @2 = private alias i32, i32* @3 @3 = private alias i32, i32* @1 ; CHECK: @3 = private alias i32, i32* @1