From e9efecaa5232becbb7e55484443b78637d58d54a Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 9 Dec 2014 05:43:56 +0000 Subject: [PATCH] AsmParser: Reject invalid mismatch between forward ref and def Don't assume that the forward referenced entity was of the same global-kind as the new entity. This fixes PR21779. llvm-svn: 223754 --- llvm/lib/AsmParser/LLParser.cpp | 13 ++++++++----- llvm/test/Assembler/invalid-fwdref2.ll | 4 ++++ 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 llvm/test/Assembler/invalid-fwdref2.ll diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index e1c00cc..df4a16a 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -787,33 +787,36 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, if (Ty->isFunctionTy() || Ty->isLabelTy()) return Error(TyLoc, "invalid type for global variable"); - GlobalVariable *GV = nullptr; + GlobalValue *GVal = nullptr; // See if the global was forward referenced, if so, use the global. if (!Name.empty()) { - if (GlobalValue *GVal = M->getNamedValue(Name)) { + GVal = M->getNamedValue(Name); + if (GVal) { if (!ForwardRefVals.erase(Name) || !isa(GVal)) return Error(NameLoc, "redefinition of global '@" + Name + "'"); - GV = cast(GVal); } } else { std::map >::iterator I = ForwardRefValIDs.find(NumberedVals.size()); if (I != ForwardRefValIDs.end()) { - GV = cast(I->second.first); + GVal = I->second.first; ForwardRefValIDs.erase(I); } } + GlobalVariable *GV; if (!GV) { GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, nullptr, Name, nullptr, GlobalVariable::NotThreadLocal, AddrSpace); } else { - if (GV->getType()->getElementType() != Ty) + if (GVal->getType()->getElementType() != Ty) return Error(TyLoc, "forward reference and definition of global have different types"); + GV = cast(GVal); + // Move the forward-reference to the correct spot in the module. M->getGlobalList().splice(M->global_end(), M->getGlobalList(), GV); } diff --git a/llvm/test/Assembler/invalid-fwdref2.ll b/llvm/test/Assembler/invalid-fwdref2.ll new file mode 100644 index 0000000..d823481 --- /dev/null +++ b/llvm/test/Assembler/invalid-fwdref2.ll @@ -0,0 +1,4 @@ +; RUN: not llvm-as %s -disable-output 2>&1 | grep "forward reference and definition of global have different types" + +@a2 = alias void ()* @g2 +@g2 = internal global i8 42 -- 2.7.4