llvm.org GIT mirror llvm / ec91ccb
Fix an error handling redefinition of linkonce functions where the types differ. Patch by Nathan Keynes! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52527 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 12 years ago
3 changed file(s) with 23 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
896896 const Function *SF = I; // SrcFunction
897897
898898 Function *DF = 0;
899 Value *MappedDF;
899900
900901 // If this function is internal or has no name, it doesn't participate in
901902 // linkage.
972973 // Remember this mapping so uses in the source module get remapped
973974 // later by RemapOperand.
974975 ValueMap[SF] = NewDF;
975 } else if (SF->isDeclaration()) {
976 // We have two functions of the same name but different type and the
977 // source is a declaration while the destination is not. Any use of
978 // the source must be mapped to the destination, with a cast.
979 ValueMap[SF] = ConstantExpr::getBitCast(DF, SF->getType());
976 continue;
980977 } else {
981 // We have two functions of the same name but different types and they
982 // are both definitions. This is an error.
983 return Error(Err, "Function '" + DF->getName() + "' defined as both '" +
984 ToStr(SF->getFunctionType(), Src) + "' and '" +
985 ToStr(DF->getFunctionType(), Dest) + "'");
978 // We have two functions of the same name but different type. Any use
979 // of the source must be mapped to the destination, with a cast.
980 MappedDF = ConstantExpr::getBitCast(DF, SF->getType());
986981 }
987 continue;
982 } else {
983 MappedDF = DF;
988984 }
989985
990986 if (SF->isDeclaration()) {
992988 // the declarations, we aren't adding anything.
993989 if (SF->hasDLLImportLinkage()) {
994990 if (DF->isDeclaration()) {
995 ValueMap[SF] = DF;
991 ValueMap[SF] = MappedDF;
996992 DF->setLinkage(SF->getLinkage());
997993 }
998994 } else {
999 ValueMap[SF] = DF;
995 ValueMap[SF] = MappedDF;
1000996 }
1001997 continue;
1002998 }
10041000 // If DF is external but SF is not, link the external functions, update
10051001 // linkage qualifiers.
10061002 if (DF->isDeclaration() && !DF->hasDLLImportLinkage()) {
1007 ValueMap.insert(std::make_pair(SF, DF));
1003 ValueMap.insert(std::make_pair(SF, MappedDF));
10081004 DF->setLinkage(SF->getLinkage());
10091005 continue;
10101006 }
10121008 // At this point we know that DF has LinkOnce, Weak, or External* linkage.
10131009 if (SF->hasWeakLinkage() || SF->hasLinkOnceLinkage() ||
10141010 SF->hasCommonLinkage()) {
1015 ValueMap[SF] = DF;
1011 ValueMap[SF] = MappedDF;
10161012
10171013 // Linkonce+Weak = Weak
10181014 // *+External Weak = *
10261022 if (DF->hasWeakLinkage() || DF->hasLinkOnceLinkage() ||
10271023 DF->hasCommonLinkage()) {
10281024 // At this point we know that SF has LinkOnce or External* linkage.
1029 ValueMap[SF] = DF;
1025 ValueMap[SF] = MappedDF;
10301026
10311027 // If the source function has stronger linkage than the destination,
10321028 // its body and linkage should override ours.
11051101 // go
11061102 for (Module::iterator SF = Src->begin(), E = Src->end(); SF != E; ++SF) {
11071103 if (!SF->isDeclaration()) { // No body if function is external
1108 Function *DF = cast(ValueMap[SF]); // Destination function
1104 Function *DF = dyn_cast(ValueMap[SF]); // Destination function
11091105
11101106 // DF not external SF external?
1111 if (DF->isDeclaration())
1107 if (DF && DF->isDeclaration())
11121108 // Only provide the function body if there isn't one already.
11131109 if (LinkFunctionBody(DF, SF, ValueMap, Err))
11141110 return true;
0 ; Test linking two functions with different prototypes and two globals
1 ; in different modules.
2 ; RUN: llvm-as %s -o %t.foo1.bc -f
3 ; RUN: llvm-as %s -o %t.foo2.bc -f
4 ; RUN: echo {define linkonce void @foo(i32 %x) { ret void }} | llvm-as -o %t.foo3.bc -f
5 ; RUN: llvm-link %t.foo1.bc %t.foo2.bc | llvm-dis
6 ; RUN: llvm-link %t.foo1.bc %t.foo3.bc | llvm-dis
7 define linkonce void @foo() { ret void }
55 ; RUN: not llvm-link %t.foo1.bc %t.foo2.bc -o %t.bc |& \
66 ; RUN: grep {Function is already defined}
77 ; RUN: not llvm-link %t.foo1.bc %t.foo3.bc -o %t.bc |& \
8 ; RUN: grep {Function 'foo' defined as both}
8 ; RUN: grep {Function is already defined}
99 define void @foo() { ret void }