[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 &LT, 
                                     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