Search code examples
llvmllvm-clangllvm-irllvm-c++-apillvm-gcc

LLVM - How to pass arguments to a function call | error: Calling a function with a bad signature


void print(char *s) {
    printf("%s\n", s);
}

I want to insert a call to the function above in an llvm pass. Here's my llvm pass code

            Function *printFunc = M.getFunction("print");
            if (printFunc) {
              IRBuilder<> B(BB);
              errs() << "print function: " << printFunc << "\n";
              Value *v = B.CreateGlobalString("hi", "str");
              ArrayRef<Value *> args(v);
              Instruction *newInst = CallInst::Create(printFunc, args, "");
              BB->getInstList().insert(I->getNextNode(), newInst);
            }

Got the following error message:

opt: /workspace/LLVM_package/src/lib/IR/Instructions.cpp:279: void llvm::CallInst::init(llvm::Value*, llvm::ArrayRef<llvm::Value*>, const llvm::Twine&): Assertion `(i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad signature!"' failed.
0  opt             0x0000560a880abc62 llvm::sys::PrintStackTrace(_IO_FILE*) + 50
1  opt             0x0000560a880ab43c
2  libpthread.so.0 0x00007f8bd59d6800
3  libc.so.6       0x00007f8bd5476ce5 gsignal + 325
4  libc.so.6       0x00007f8bd5460857 abort + 299
5  libc.so.6       0x00007f8bd5460727
6  libc.so.6       0x00007f8bd546f426
7  opt             0x0000560a880177c1 llvm::CallInst::init(llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::Twine const&) + 465
8  MyLLVMPass.so   0x00007f8bd5431377
9  opt             0x0000560a88036636 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 822
10 opt             0x0000560a8724d072 main + 2626
11 libc.so.6       0x00007f8bd5462023 __libc_start_main + 243
12 opt             0x0000560a87267afe _start + 46
Stack dump:
0.      Program arguments: opt -S -analyze -load ./build/Release+Asserts/lib/MyLLVMPass.so -MyLLVMPass 
1.      Running pass 'MyLLVMPass' on module '<stdin>'.
run_myllvmpass.sh: line 11: 60257 Aborted                 (core dumped) opt -S -analyze -load ./build/Release+Asserts/lib/MyLLVMPass.so -MyLLVMPass < ${var1} > ${var2}

Can anyone point out what I did wrong?


Solution

  • Your print function expects a pointer of type i8* but B.CreateGlobalString("hi", "str"); returns a pointer to an array of type i8. Use B.CreateGlobalStringPtr("hi", "str"); instead.