diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index fc4cfcfe45d..65d0a8236b9 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -1024,6 +1024,31 @@ void Verifier::VerifyCallSite(CallSite CS) { "Call parameter type does not match function signature!", CS.getArgument(i), FTy->getParamType(i), I); + Assert2(CS.getType() == FTy->getReturnType(), + "Call return type does not match function signature!", + CS.getInstruction(), FTy->getReturnType()); + + // Verify calling convention for direct calls + Value *CalledF = CS.getCalledValue()->stripPointerCasts(); + if (Function *F = dyn_cast(CalledF)) { + unsigned CC1 = CS.getCallingConv(); + unsigned CC2 = F->getCallingConv(); + if(CC1 != CC2) { + // tolerate some mismatch among C prototype and LLVM-specific calling conv + if (CC2 >= CallingConv::FirstTargetCC || + CC1 >= CallingConv::FirstTargetCC) { + Instruction *I = CS.getInstruction()->clone(); + if (CallInst *CI = dyn_cast(I)) { + CI->setCallingConv(F->getCallingConv()); + } else + cast(I)->setCallingConv(F->getCallingConv()); + Assert2(0,"Calling convention does not match function signature!", + CS.getInstruction(), I); + delete I; + } + } + } + if (CS.getCalledValue()->getNameLen() < 5 || strncmp(CS.getCalledValue()->getNameStart(), "llvm.", 5) != 0) { // Verify that none of the arguments are metadata... diff --git a/test/Assembler/2009-05-22-CC.ll b/test/Assembler/2009-05-22-CC.ll new file mode 100644 index 00000000000..ba80d64ac28 --- /dev/null +++ b/test/Assembler/2009-05-22-CC.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s + +; Verify that calls with correct calling conv are accepted +declare x86_stdcallcc i32 @re_string_construct(i8* inreg %pstr, i8* inreg %str, i32 inreg %len, i8* %trans, i32 %icase, i8* %dfa); +define void @main() { +entry: + %0 = call x86_stdcallcc i32 (...)* bitcast (i32 (i8*, i8*, i32, i8*, i32, i8*)* @re_string_construct to i32 (...)*)(i32 inreg 0, i32 inreg 0, i32 inreg 0, i32 0, i32 0, i8* inttoptr (i32 673194176 to i8*)); + ret void +} diff --git a/test/Verifier/2009-05-22-CC.ll b/test/Verifier/2009-05-22-CC.ll new file mode 100644 index 00000000000..7775dede03a --- /dev/null +++ b/test/Verifier/2009-05-22-CC.ll @@ -0,0 +1,11 @@ +; RUN: not llvm-as < %s |& grep {Calling convention does not match function signature} +; PR 4239 + +; Verify that the calling convention on the call instruction matches the +; declared calling convention +declare x86_stdcallcc i32 @re_string_construct(i8* inreg %pstr, i8* inreg %str, i32 inreg %len, i8* %trans, i32 %icase, i8* %dfa); +define void @main() { +entry: + %0 = call i32 (...)* bitcast (i32 (i8*, i8*, i32, i8*, i32, i8*)* @re_string_construct to i32 (...)*)(i32 inreg 0, i32 inreg 0, i32 inreg 0, i32 0, i32 0, i8* inttoptr (i32 673194176 to i8*)) + ret void +}