[llvm-branch-commits] [llvm-branch] r134481 - /llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp
Chris Lattner
sabre at nondot.org
Wed Jul 6 00:17:20 PDT 2011
Author: lattner
Date: Wed Jul 6 02:17:20 2011
New Revision: 134481
URL: http://llvm.org/viewvc/llvm-project?rev=134481&view=rev
Log:
teach getLinkageResult to properly treat GlobalAliases as always being definitions
even though GlobalAlias::isDeclaration is completely broken. GlobalAlias's should
always considered to be a symbol definition. This allows removal of some logic
and fixes some broken cases. For example a weak alias in the destination module
should be linkable with a strong external function in the source module. Previously
this would be rejected.
Modified:
llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp
Modified: llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp?rev=134481&r1=134480&r2=134481&view=diff
==============================================================================
--- llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp (original)
+++ llvm/branches/type-system-rewrite/lib/Linker/LinkModules.cpp Wed Jul 6 02:17:20 2011
@@ -407,18 +407,21 @@
bool ModuleLinker::getLinkageResult(GlobalValue *Dest, const GlobalValue *Src,
GlobalValue::LinkageTypes <,
bool &LinkFromSrc) {
- assert((!Dest || !Src->hasLocalLinkage()) &&
+ assert(Dest && "Must have two globals being queried");
+ assert(!Src->hasLocalLinkage() &&
"If Src has internal linkage, Dest shouldn't be set!");
- if (!Dest) {
- // Linking something to nothing.
- LinkFromSrc = true;
- LT = Src->getLinkage();
- } else if (Src->isDeclaration()) {
+
+ // FIXME: GlobalAlias::isDeclaration is broken, should always be
+ // false.
+ bool SrcIsDeclaration = Src->isDeclaration() && !isa<GlobalAlias>(Src);
+ bool DestIsDeclaration = Dest->isDeclaration() && !isa<GlobalAlias>(Dest);
+
+ if (SrcIsDeclaration) {
// If Src is external or if both Src & Dest are external.. Just link the
// external globals, we aren't adding anything.
if (Src->hasDLLImportLinkage()) {
// If one of GVs has DLLImport linkage, result should be dllimport'ed.
- if (Dest->isDeclaration()) {
+ if (DestIsDeclaration) {
LinkFromSrc = true;
LT = Src->getLinkage();
}
@@ -430,7 +433,7 @@
LinkFromSrc = false;
LT = Dest->getLinkage();
}
- } else if (Dest->isDeclaration() && !Dest->hasDLLImportLinkage()) {
+ } else if (DestIsDeclaration && !Dest->hasDLLImportLinkage()) {
// If Dest is external but Src is not:
LinkFromSrc = true;
LT = Src->getLinkage();
@@ -467,11 +470,11 @@
}
// Check visibility
- if (Dest && Src->getVisibility() != Dest->getVisibility() &&
- !Src->isDeclaration() && !Dest->isDeclaration() &&
+ if (Src->getVisibility() != Dest->getVisibility() &&
+ !SrcIsDeclaration && !DestIsDeclaration &&
!Src->hasAvailableExternallyLinkage() &&
!Dest->hasAvailableExternallyLinkage())
- return emitError("Linking globals named '" + Src->getName() +
+ return emitError("Linking globals named '" + Src->getName() +
"': symbols have different visibilities!");
return false;
}
@@ -619,10 +622,6 @@
return true;
if (LinkFromSrc) {
- if (isa<GlobalAlias>(DGV))
- return emitError("Global alias collision on '" + SGV->getName() +
- "': symbol multiple defined");
-
// Clear the name of DGV so we don't get a name conflict.
DGV->setName("");
@@ -640,11 +639,7 @@
CopyGVAttributes(NewDGV, SGV);
DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV, DGV->getType()));
-
- if (GlobalVariable *Var = dyn_cast<GlobalVariable>(DGV))
- Var->eraseFromParent();
- else
- cast<Function>(DGV)->eraseFromParent();
+ DGV->eraseFromParent();
// Make sure to remember this mapping.
ValueMap[SGV] = NewDGV;
@@ -658,16 +653,6 @@
if (DGVar->isDeclaration() && SGV->isConstant() && !DGVar->isConstant())
DGVar->setConstant(true);
- // SGV is global, but DGV is alias.
- if (isa<GlobalAlias>(DGV)) {
- // The only valid mappings are:
- // - SGV is external declaration, which is effectively a no-op.
- // - SGV is weak, when we just need to throw SGV out.
- if (!SGV->isDeclaration() && !SGV->isWeakForLinker())
- return emitError("Global alias collision on '" + SGV->getName() +
- "': symbol multiple defined");
- }
-
// Set calculated linkage.
DGV->setLinkage(NewLinkage);
@@ -711,10 +696,6 @@
return true;
if (LinkFromSrc) {
- if (isa<GlobalAlias>(DGV))
- return emitError("Function alias collision on '" + SF->getName() +
- "': symbol multiple defined");
-
// Clear the name so we don't get a conflict.
DGV->setName("");
@@ -727,11 +708,7 @@
// Any uses of DF need to change to NewDF, with cast.
DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDF, DGV->getType()));
-
- if (GlobalVariable *Var = dyn_cast<GlobalVariable>(DGV))
- Var->eraseFromParent();
- else
- cast<Function>(DGV)->eraseFromParent();
+ DGV->eraseFromParent();
// Remember this mapping so uses in the source module get remapped
// later by MapValue.
@@ -739,17 +716,6 @@
return false;
}
- // Not "link from source", keep the one in the DestModule and remap the
- // input onto it.
- if (isa<GlobalAlias>(DGV)) {
- // The only valid mappings are:
- // - SF is external declaration, which is effectively a no-op.
- // - SF is weak, when we just need to throw SF out.
- if (!SF->isDeclaration() && !SF->isWeakForLinker())
- return emitError("Function alias collision on '" + SF->getName() +
- "': symbol multiple defined");
- }
-
// Set calculated linkage
DGV->setLinkage(NewLinkage);
@@ -782,7 +748,7 @@
if (SL == GlobalValue::LinkerPrivateWeakDefAutoLinkage &&
DL == GlobalValue::LinkerPrivateWeakDefAutoLinkage)
return GlobalValue::LinkerPrivateWeakDefAutoLinkage;
-
+
assert(SL == GlobalValue::PrivateLinkage &&
DL == GlobalValue::PrivateLinkage && "Unexpected linkage type");
return GlobalValue::PrivateLinkage;
More information about the llvm-branch-commits
mailing list