diff options
author | Chris Lattner <sabre@nondot.org> | 2003-05-08 03:47:33 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-05-08 03:47:33 +0000 |
commit | dd035d188a80f560ff4193391a9e8df64c993369 (patch) | |
tree | 2882c32f8a0fc1fc9a6425b1c406a24acc156a8c /lib/VMCore/Verifier.cpp | |
parent | 6d95257a919574e448c069061e2a03c6132bbb6b (diff) | |
download | external_llvm-dd035d188a80f560ff4193391a9e8df64c993369.zip external_llvm-dd035d188a80f560ff4193391a9e8df64c993369.tar.gz external_llvm-dd035d188a80f560ff4193391a9e8df64c993369.tar.bz2 |
Add more support for intrinsic functions and for varargs stuff
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6035 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/Verifier.cpp')
-rw-r--r-- | lib/VMCore/Verifier.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 66ee9de..dfb71be 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -43,6 +43,7 @@ #include "llvm/iMemory.h" #include "llvm/SymbolTable.h" #include "llvm/PassManager.h" +#include "llvm/Intrinsics.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Support/CFG.h" #include "llvm/Support/InstVisitor.h" @@ -140,6 +141,7 @@ namespace { // Anonymous namespace for class void visitReturnInst(ReturnInst &RI); void visitUserOp1(Instruction &I); void visitUserOp2(Instruction &I) { visitUserOp1(I); } + void visitIntrinsicFunctionCall(LLVMIntrinsic::ID ID, CallInst &CI); // CheckFailed - A check failed, so print out the condition and the message // that failed. This provides a nice place to put a breakpoint if you want @@ -359,6 +361,10 @@ void Verifier::visitCallInst(CallInst &CI) { "Call parameter type does not match function signature!", CI.getOperand(i+1), FTy->getParamType(i)); + if (Function *F = CI.getCalledFunction()) + if (LLVMIntrinsic::ID ID = (LLVMIntrinsic::ID)F->getIntrinsicID()) + visitIntrinsicFunctionCall(ID, CI); + visitInstruction(CI); } @@ -495,6 +501,37 @@ void Verifier::visitInstruction(Instruction &I) { "Instruction does not dominate all uses!", &I, Use); } } + + // Check to make sure that the "address of" an intrinsic function is never + // taken. + for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) + if (Function *F = dyn_cast<Function>(I.getOperand(i))) + Assert1(!F->isIntrinsic() || (i == 0 && isa<CallInst>(I)), + "Cannot take the address of an intrinsic!", &I); +} + +/// visitIntrinsicFunction - Allow intrinsics to be verified in different ways. +void Verifier::visitIntrinsicFunctionCall(LLVMIntrinsic::ID ID, CallInst &CI) { + Function *IF = CI.getCalledFunction(); + const FunctionType *FT = IF->getFunctionType(); + Assert1(IF->isExternal(), "Intrinsic functions should never be defined!", IF); + unsigned NumArgs; + + switch (ID) { + case LLVMIntrinsic::va_start: + Assert1(isa<Argument>(CI.getOperand(2)), + "va_start second argument should be a function argument!", &CI); + NumArgs = 2; + break; + case LLVMIntrinsic::va_end: NumArgs = 1; break; + case LLVMIntrinsic::va_copy: NumArgs = 2; break; + case LLVMIntrinsic::not_intrinsic: + assert(0 && "Invalid intrinsic!"); NumArgs = 0; break; + } + + Assert1(FT->getNumParams() == NumArgs || (FT->getNumParams() < NumArgs && + FT->isVarArg()), + "Illegal # arguments for intrinsic function!", IF); } |