Gizmo
Gizmo

Reputation: 941

Adding a simple printf in a LLVM pass

I am trying to insert a printf call to a program via a LLVM pass. The printf function should just print "test". I've used getOrInsertFunction to get ahold of the printf function. Afterwards I tried to create the method with CreateCall. Sadly, I get a segmentation fault. Could anyone point out the error for me?

// Declaring some variables 
static LLVMContext context;
Module* module = F.getParent();
IRBuilder<> builder(call_inst);
Type *intType = Type::getInt32Ty(context);


// Declare C standard library printf 
std::vector<Type *> printfArgsTypes({Type::getInt8PtrTy(context)});
FunctionType *printfType = FunctionType::get(intType, printfArgsTypes, true);
Constant *printfFunc = module->getOrInsertFunction("printf", printfType);


// The format string for the printf function, declared as a global literal
Value *str = builder.CreateGlobalStringPtr("test\n", "str");

std::vector<Value *> argsV({str});
builder.CreateCall(printfFunc, argsV, "calltmp");

Part of the error message invoked by LLVM:

void llvm::CallInst::init(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >, const llvm::Twine&): Assertion `(i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad signature!"' failed. 

Upvotes: 1

Views: 2300

Answers (1)

Attila
Attila

Reputation: 28762

Based on Ismail Badawi's comment on the question, the code below worked for me:

Module* module = F.getParent();
LLVMContext & context = module->getContext();
IRBuilder<> builder(call_inst);
// The rest is unchanged

Note the way the context is obtained from the module (instead of declared as static)

Upvotes: 2

Related Questions