[llvm-commits] [llvm] r48179 - /llvm/trunk/lib/Linker/LinkModules.cpp

Anton Korobeynikov asl at math.spbu.ru
Mon Mar 10 15:34:29 PDT 2008


Author: asl
Date: Mon Mar 10 17:34:28 2008
New Revision: 48179

URL: http://llvm.org/viewvc/llvm-project?rev=48179&view=rev
Log:
Properly link globals with aliases

Modified:
    llvm/trunk/lib/Linker/LinkModules.cpp

Modified: llvm/trunk/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=48179&r1=48178&r2=48179&view=diff

==============================================================================
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)
+++ llvm/trunk/lib/Linker/LinkModules.cpp Mon Mar 10 17:34:28 2008
@@ -462,8 +462,9 @@
   for (Module::const_global_iterator I = Src->global_begin(), E = Src->global_end();
        I != E; ++I) {
     const GlobalVariable *SGV = I;
-    GlobalVariable *DGV = 0;
-    // Check to see if may have to link the global.
+    GlobalValue *DGV = 0;
+
+    // Check to see if may have to link the global with the global
     if (SGV->hasName() && !SGV->hasInternalLinkage()) {
       DGV = Dest->getGlobalVariable(SGV->getName());
       if (DGV && DGV->getType() != SGV->getType())
@@ -472,6 +473,15 @@
                               &Dest->getTypeSymbolTable(), "");
     }
 
+    // Check to see if may have to link the global with the alias
+    if (SGV->hasName() && !SGV->hasInternalLinkage()) {
+      DGV = Dest->getNamedAlias(SGV->getName());
+      if (DGV && DGV->getType() != SGV->getType())
+        // If types don't agree due to opaque types, try to resolve them.
+        RecursiveResolveTypes(SGV->getType(), DGV->getType(), 
+                              &Dest->getTypeSymbolTable(), "");
+    }
+
     if (DGV && DGV->hasInternalLinkage())
       DGV = 0;
 
@@ -526,26 +536,37 @@
 
       // Keep track that this is an appending variable...
       AppendingVars.insert(std::make_pair(SGV->getName(), NewDGV));
-    } else {
+    } else if (GlobalAlias *DGA = dyn_cast<GlobalAlias>(DGV)) {
+      // SGV is global, but DGV is alias. The only valid mapping is when SGV is
+      // external declaration, which is effectively a no-op. Also make sure
+      // linkage is correct.
+      if (SGV->isDeclaration() && !LinkFromSrc) {
+        // Make sure to remember this mapping...
+        ValueMap.insert(std::make_pair(SGV, DGA));
+      } else
+        return Error(Err, "Global-Alias Collision on '" +
+                     ToStr(SGV->getType(), Src) +"':%"+SGV->getName()+
+                     " - symbol multiple defined");
+    } else if (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV)) {
       // Otherwise, perform the mapping as instructed by GetLinkageResult.
       if (LinkFromSrc) {
         // Propagate alignment, section, and visibility info.
-        CopyGVAttributes(DGV, SGV);
+        CopyGVAttributes(DGVar, SGV);
 
         // If the types don't match, and if we are to link from the source, nuke
         // DGV and create a new one of the appropriate type.
-        if (SGV->getType() != DGV->getType()) {
+        if (SGV->getType() != DGVar->getType()) {
           GlobalVariable *NewDGV =
             new GlobalVariable(SGV->getType()->getElementType(),
-                               DGV->isConstant(), DGV->getLinkage(),
-                               /*init*/0, DGV->getName(), Dest);
-          CopyGVAttributes(NewDGV, DGV);
+                               DGVar->isConstant(), DGVar->getLinkage(),
+                               /*init*/0, DGVar->getName(), Dest);
+          CopyGVAttributes(NewDGV, DGVar);
           DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV,
-                                                           DGV->getType()));
-          // DGV will conflict with NewDGV because they both had the same
+                                                           DGVar->getType()));
+          // DGVar will conflict with NewDGV because they both had the same
           // name. We must erase this now so ForceRenaming doesn't assert
           // because DGV might not have internal linkage.
-          DGV->eraseFromParent();
+          DGVar->eraseFromParent();
 
           // If the symbol table renamed the global, but it is an externally
           // visible symbol, DGV must be an existing global with internal
@@ -554,26 +575,26 @@
               !NewDGV->hasInternalLinkage())
             ForceRenaming(NewDGV, SGV->getName());
 
-          DGV = NewDGV;
+          DGVar = NewDGV;
         }
 
         // Inherit const as appropriate
-        DGV->setConstant(SGV->isConstant());
+        DGVar->setConstant(SGV->isConstant());
 
         // Set initializer to zero, so we can link the stuff later
-        DGV->setInitializer(0);
+        DGVar->setInitializer(0);
       } else {
         // Special case for const propagation
-        if (DGV->isDeclaration() && SGV->isConstant() && !DGV->isConstant())
-          DGV->setConstant(true);
+        if (DGVar->isDeclaration() && SGV->isConstant() && !DGVar->isConstant())
+          DGVar->setConstant(true);
       }
 
       // Set calculated linkage
-      DGV->setLinkage(NewLinkage);
+      DGVar->setLinkage(NewLinkage);
 
       // Make sure to remember this mapping...
       ValueMap.insert(std::make_pair(SGV,
-                                     ConstantExpr::getBitCast(DGV,
+                                     ConstantExpr::getBitCast(DGVar,
                                                               SGV->getType())));
     }
   }
@@ -659,7 +680,7 @@
 
         // Proceed to 'common' steps
       } else
-        return Error(Err, "Alias Collision on '" +
+        return Error(Err, "Global-Alias Collision on '" +
                      ToStr(SGA->getType(), Src) +"':%"+SGA->getName()+
                      " - symbol multiple defined");
     } else if (Function *DF = Dest->getFunction(SGA->getName())) {
@@ -686,7 +707,7 @@
 
         // Proceed to 'common' steps
       } else
-        return Error(Err, "Alias Collision on '" +
+        return Error(Err, "Function-Alias Collision on '" +
                      ToStr(SGA->getType(), Src) +"':%"+SGA->getName()+
                      " - symbol multiple defined");
     } else {





More information about the llvm-commits mailing list