[llvm-commits] [llvm] r52527 - in /llvm/trunk: lib/Linker/LinkModules.cpp test/Linker/2008-06-13-LinkOnceRedefinition.ll test/Linker/redefinition.ll

Chris Lattner sabre at nondot.org
Thu Jun 19 22:29:39 PDT 2008


Author: lattner
Date: Fri Jun 20 00:29:39 2008
New Revision: 52527

URL: http://llvm.org/viewvc/llvm-project?rev=52527&view=rev
Log:
Fix an error handling redefinition of linkonce functions where the
types differ.  Patch by Nathan Keynes!

Added:
    llvm/trunk/test/Linker/2008-06-13-LinkOnceRedefinition.ll
Modified:
    llvm/trunk/lib/Linker/LinkModules.cpp
    llvm/trunk/test/Linker/redefinition.ll

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

==============================================================================
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)
+++ llvm/trunk/lib/Linker/LinkModules.cpp Fri Jun 20 00:29:39 2008
@@ -897,6 +897,7 @@
     const Function *SF = I;   // SrcFunction
     
     Function *DF = 0;
+    Value *MappedDF;
     
     // If this function is internal or has no name, it doesn't participate in
     // linkage.
@@ -973,19 +974,14 @@
         // Remember this mapping so uses in the source module get remapped
         // later by RemapOperand.
         ValueMap[SF] = NewDF;
-      } else if (SF->isDeclaration()) {
-        // We have two functions of the same name but different type and the
-        // source is a declaration while the destination is not. Any use of
-        // the source must be mapped to the destination, with a cast. 
-        ValueMap[SF] = ConstantExpr::getBitCast(DF, SF->getType());
+        continue;
       } else {
-        // We have two functions of the same name but different types and they
-        // are both definitions. This is an error.
-        return Error(Err, "Function '" + DF->getName() + "' defined as both '" +
-                     ToStr(SF->getFunctionType(), Src) + "' and '" +
-                     ToStr(DF->getFunctionType(), Dest) + "'");
+        // We have two functions of the same name but different type. Any use
+        // of the source must be mapped to the destination, with a cast. 
+        MappedDF = ConstantExpr::getBitCast(DF, SF->getType());
       }
-      continue;
+    } else {
+       MappedDF = DF;
     }
     
     if (SF->isDeclaration()) {
@@ -993,11 +989,11 @@
       // the declarations, we aren't adding anything.
       if (SF->hasDLLImportLinkage()) {
         if (DF->isDeclaration()) {
-          ValueMap[SF] = DF;
+          ValueMap[SF] = MappedDF;
           DF->setLinkage(SF->getLinkage());          
         }
       } else {
-        ValueMap[SF] = DF;
+        ValueMap[SF] = MappedDF;
       }
       continue;
     }
@@ -1005,7 +1001,7 @@
     // If DF is external but SF is not, link the external functions, update
     // linkage qualifiers.
     if (DF->isDeclaration() && !DF->hasDLLImportLinkage()) {
-      ValueMap.insert(std::make_pair(SF, DF));
+      ValueMap.insert(std::make_pair(SF, MappedDF));
       DF->setLinkage(SF->getLinkage());
       continue;
     }
@@ -1013,7 +1009,7 @@
     // At this point we know that DF has LinkOnce, Weak, or External* linkage.
     if (SF->hasWeakLinkage() || SF->hasLinkOnceLinkage() ||
         SF->hasCommonLinkage()) {
-      ValueMap[SF] = DF;
+      ValueMap[SF] = MappedDF;
 
       // Linkonce+Weak = Weak
       // *+External Weak = *
@@ -1027,7 +1023,7 @@
     if (DF->hasWeakLinkage() || DF->hasLinkOnceLinkage() ||
         DF->hasCommonLinkage()) {
       // At this point we know that SF has LinkOnce or External* linkage.
-      ValueMap[SF] = DF;
+      ValueMap[SF] = MappedDF;
       
       // If the source function has stronger linkage than the destination, 
       // its body and linkage should override ours.
@@ -1106,10 +1102,10 @@
   // go
   for (Module::iterator SF = Src->begin(), E = Src->end(); SF != E; ++SF) {
     if (!SF->isDeclaration()) {               // No body if function is external
-      Function *DF = cast<Function>(ValueMap[SF]); // Destination function
+      Function *DF = dyn_cast<Function>(ValueMap[SF]); // Destination function
 
       // DF not external SF external?
-      if (DF->isDeclaration())
+      if (DF && DF->isDeclaration())
         // Only provide the function body if there isn't one already.
         if (LinkFunctionBody(DF, SF, ValueMap, Err))
           return true;

Added: llvm/trunk/test/Linker/2008-06-13-LinkOnceRedefinition.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/2008-06-13-LinkOnceRedefinition.ll?rev=52527&view=auto

==============================================================================
--- llvm/trunk/test/Linker/2008-06-13-LinkOnceRedefinition.ll (added)
+++ llvm/trunk/test/Linker/2008-06-13-LinkOnceRedefinition.ll Fri Jun 20 00:29:39 2008
@@ -0,0 +1,8 @@
+; Test linking two functions with different prototypes and two globals 
+; in different modules.
+; RUN: llvm-as %s -o %t.foo1.bc -f
+; RUN: llvm-as %s -o %t.foo2.bc -f
+; RUN: echo {define linkonce void @foo(i32 %x) { ret void }} | llvm-as -o %t.foo3.bc -f
+; RUN: llvm-link %t.foo1.bc %t.foo2.bc | llvm-dis
+; RUN: llvm-link %t.foo1.bc %t.foo3.bc | llvm-dis
+define linkonce void @foo() { ret void }

Modified: llvm/trunk/test/Linker/redefinition.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/redefinition.ll?rev=52527&r1=52526&r2=52527&view=diff

==============================================================================
--- llvm/trunk/test/Linker/redefinition.ll (original)
+++ llvm/trunk/test/Linker/redefinition.ll Fri Jun 20 00:29:39 2008
@@ -6,5 +6,5 @@
 ; RUN: not llvm-link %t.foo1.bc %t.foo2.bc -o %t.bc |& \
 ; RUN:   grep {Function is already defined}
 ; RUN: not llvm-link %t.foo1.bc %t.foo3.bc -o %t.bc |& \
-; RUN:   grep {Function 'foo' defined as both}
+; RUN:   grep {Function is already defined}
 define void @foo() { ret void }





More information about the llvm-commits mailing list