From 0fec08eb58dd9fffeb72c584aa61a59d71111c8d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 21 Apr 2003 21:07:05 +0000 Subject: [PATCH] Fix linking a function with qualifiers to a external function declaration: Fixed bug: Linker/2003-04-21-Linkage.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5827 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/LinkModules.cpp | 24 ++++++++++++++++++------ lib/Transforms/Utils/Linker.cpp | 24 ++++++++++++++++++------ lib/VMCore/Linker.cpp | 24 ++++++++++++++++++------ 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index b5207a85429..3efb0b50faa 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -202,6 +202,9 @@ static bool LinkGlobals(Module *Dest, const Module *Src, assert(SGV->hasInitializer() || SGV->hasExternalLinkage() && "Global must either be external or have an initializer!"); + bool SGExtern = SGV->isExternal(); + bool DGExtern = DGV ? DGV->isExternal() : false; + if (!DGV || DGV->hasInternalLinkage() || SGV->hasInternalLinkage()) { // No linking to be performed, simply create an identical version of the // symbol over in the dest module... the initializer will be filled in @@ -213,7 +216,7 @@ static bool LinkGlobals(Module *Dest, const Module *Src, // Make sure to remember this mapping... ValueMap.insert(std::make_pair(SGV, DGV)); - } else if (SGV->getLinkage() != DGV->getLinkage()) { + } else if (!SGExtern && !DGExtern && SGV->getLinkage() !=DGV->getLinkage()){ return Error(Err, "Global variables named '" + SGV->getName() + "' have different linkage specifiers!"); } else if (SGV->hasExternalLinkage() || SGV->hasLinkOnceLinkage() || @@ -227,6 +230,9 @@ static bool LinkGlobals(Module *Dest, const Module *Src, return Error(Err, "Global Variable Collision on '" + SGV->getType()->getDescription() + "':%" + SGV->getName() + " - Global variables differ in const'ness"); + if (DGExtern) + DGV->setLinkage(SGV->getLinkage()); + // Okay, everything is cool, remember the mapping... ValueMap.insert(std::make_pair(SGV, DGV)); } else { @@ -301,20 +307,23 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, // DF = cast_or_null(ST->lookup(SF->getType(), SF->getName())); + bool SFExtern = SF->isExternal(); + bool DFExtern = DF ? DF->isExternal() : false; + if (!DF || SF->hasInternalLinkage() || DF->hasInternalLinkage()) { - // Function does not already exist, simply insert an external function - // signature identical to SF into the dest module... + // Function does not already exist, simply insert an function signature + // identical to SF into the dest module... Function *DF = new Function(SF->getFunctionType(), SF->getLinkage(), SF->getName(), Dest); // ... and remember this mapping... ValueMap.insert(std::make_pair(SF, DF)); - } else if (SF->getLinkage() != DF->getLinkage()) { - return Error(Err, "Functions named '" + SF->getName() + - "' have different linkage specifiers!"); } else if (SF->getLinkage() == GlobalValue::AppendingLinkage) { return Error(Err, "Functions named '" + SF->getName() + "' have appending linkage!"); + } else if (!SFExtern && !DFExtern && SF->getLinkage() != DF->getLinkage()) { + return Error(Err, "Functions named '" + SF->getName() + + "' have different linkage specifiers!"); } else if (SF->getLinkage() == GlobalValue::ExternalLinkage) { // If the function has a name, and that name is already in use in the Dest // module, make sure that the name is a compatible function... @@ -325,6 +334,9 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, SF->getFunctionType()->getDescription() + "':\"" + SF->getName() + "\" - Function is already defined!"); + if (DFExtern) + DF->setLinkage(SF->getLinkage()); + // Otherwise, just remember this mapping... ValueMap.insert(std::make_pair(SF, DF)); } else if (SF->getLinkage() == GlobalValue::LinkOnceLinkage) { diff --git a/lib/Transforms/Utils/Linker.cpp b/lib/Transforms/Utils/Linker.cpp index b5207a85429..3efb0b50faa 100644 --- a/lib/Transforms/Utils/Linker.cpp +++ b/lib/Transforms/Utils/Linker.cpp @@ -202,6 +202,9 @@ static bool LinkGlobals(Module *Dest, const Module *Src, assert(SGV->hasInitializer() || SGV->hasExternalLinkage() && "Global must either be external or have an initializer!"); + bool SGExtern = SGV->isExternal(); + bool DGExtern = DGV ? DGV->isExternal() : false; + if (!DGV || DGV->hasInternalLinkage() || SGV->hasInternalLinkage()) { // No linking to be performed, simply create an identical version of the // symbol over in the dest module... the initializer will be filled in @@ -213,7 +216,7 @@ static bool LinkGlobals(Module *Dest, const Module *Src, // Make sure to remember this mapping... ValueMap.insert(std::make_pair(SGV, DGV)); - } else if (SGV->getLinkage() != DGV->getLinkage()) { + } else if (!SGExtern && !DGExtern && SGV->getLinkage() !=DGV->getLinkage()){ return Error(Err, "Global variables named '" + SGV->getName() + "' have different linkage specifiers!"); } else if (SGV->hasExternalLinkage() || SGV->hasLinkOnceLinkage() || @@ -227,6 +230,9 @@ static bool LinkGlobals(Module *Dest, const Module *Src, return Error(Err, "Global Variable Collision on '" + SGV->getType()->getDescription() + "':%" + SGV->getName() + " - Global variables differ in const'ness"); + if (DGExtern) + DGV->setLinkage(SGV->getLinkage()); + // Okay, everything is cool, remember the mapping... ValueMap.insert(std::make_pair(SGV, DGV)); } else { @@ -301,20 +307,23 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, // DF = cast_or_null(ST->lookup(SF->getType(), SF->getName())); + bool SFExtern = SF->isExternal(); + bool DFExtern = DF ? DF->isExternal() : false; + if (!DF || SF->hasInternalLinkage() || DF->hasInternalLinkage()) { - // Function does not already exist, simply insert an external function - // signature identical to SF into the dest module... + // Function does not already exist, simply insert an function signature + // identical to SF into the dest module... Function *DF = new Function(SF->getFunctionType(), SF->getLinkage(), SF->getName(), Dest); // ... and remember this mapping... ValueMap.insert(std::make_pair(SF, DF)); - } else if (SF->getLinkage() != DF->getLinkage()) { - return Error(Err, "Functions named '" + SF->getName() + - "' have different linkage specifiers!"); } else if (SF->getLinkage() == GlobalValue::AppendingLinkage) { return Error(Err, "Functions named '" + SF->getName() + "' have appending linkage!"); + } else if (!SFExtern && !DFExtern && SF->getLinkage() != DF->getLinkage()) { + return Error(Err, "Functions named '" + SF->getName() + + "' have different linkage specifiers!"); } else if (SF->getLinkage() == GlobalValue::ExternalLinkage) { // If the function has a name, and that name is already in use in the Dest // module, make sure that the name is a compatible function... @@ -325,6 +334,9 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, SF->getFunctionType()->getDescription() + "':\"" + SF->getName() + "\" - Function is already defined!"); + if (DFExtern) + DF->setLinkage(SF->getLinkage()); + // Otherwise, just remember this mapping... ValueMap.insert(std::make_pair(SF, DF)); } else if (SF->getLinkage() == GlobalValue::LinkOnceLinkage) { diff --git a/lib/VMCore/Linker.cpp b/lib/VMCore/Linker.cpp index b5207a85429..3efb0b50faa 100644 --- a/lib/VMCore/Linker.cpp +++ b/lib/VMCore/Linker.cpp @@ -202,6 +202,9 @@ static bool LinkGlobals(Module *Dest, const Module *Src, assert(SGV->hasInitializer() || SGV->hasExternalLinkage() && "Global must either be external or have an initializer!"); + bool SGExtern = SGV->isExternal(); + bool DGExtern = DGV ? DGV->isExternal() : false; + if (!DGV || DGV->hasInternalLinkage() || SGV->hasInternalLinkage()) { // No linking to be performed, simply create an identical version of the // symbol over in the dest module... the initializer will be filled in @@ -213,7 +216,7 @@ static bool LinkGlobals(Module *Dest, const Module *Src, // Make sure to remember this mapping... ValueMap.insert(std::make_pair(SGV, DGV)); - } else if (SGV->getLinkage() != DGV->getLinkage()) { + } else if (!SGExtern && !DGExtern && SGV->getLinkage() !=DGV->getLinkage()){ return Error(Err, "Global variables named '" + SGV->getName() + "' have different linkage specifiers!"); } else if (SGV->hasExternalLinkage() || SGV->hasLinkOnceLinkage() || @@ -227,6 +230,9 @@ static bool LinkGlobals(Module *Dest, const Module *Src, return Error(Err, "Global Variable Collision on '" + SGV->getType()->getDescription() + "':%" + SGV->getName() + " - Global variables differ in const'ness"); + if (DGExtern) + DGV->setLinkage(SGV->getLinkage()); + // Okay, everything is cool, remember the mapping... ValueMap.insert(std::make_pair(SGV, DGV)); } else { @@ -301,20 +307,23 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, // DF = cast_or_null(ST->lookup(SF->getType(), SF->getName())); + bool SFExtern = SF->isExternal(); + bool DFExtern = DF ? DF->isExternal() : false; + if (!DF || SF->hasInternalLinkage() || DF->hasInternalLinkage()) { - // Function does not already exist, simply insert an external function - // signature identical to SF into the dest module... + // Function does not already exist, simply insert an function signature + // identical to SF into the dest module... Function *DF = new Function(SF->getFunctionType(), SF->getLinkage(), SF->getName(), Dest); // ... and remember this mapping... ValueMap.insert(std::make_pair(SF, DF)); - } else if (SF->getLinkage() != DF->getLinkage()) { - return Error(Err, "Functions named '" + SF->getName() + - "' have different linkage specifiers!"); } else if (SF->getLinkage() == GlobalValue::AppendingLinkage) { return Error(Err, "Functions named '" + SF->getName() + "' have appending linkage!"); + } else if (!SFExtern && !DFExtern && SF->getLinkage() != DF->getLinkage()) { + return Error(Err, "Functions named '" + SF->getName() + + "' have different linkage specifiers!"); } else if (SF->getLinkage() == GlobalValue::ExternalLinkage) { // If the function has a name, and that name is already in use in the Dest // module, make sure that the name is a compatible function... @@ -325,6 +334,9 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, SF->getFunctionType()->getDescription() + "':\"" + SF->getName() + "\" - Function is already defined!"); + if (DFExtern) + DF->setLinkage(SF->getLinkage()); + // Otherwise, just remember this mapping... ValueMap.insert(std::make_pair(SF, DF)); } else if (SF->getLinkage() == GlobalValue::LinkOnceLinkage) {