Help with code

Hi,

  I have this call instruction to printf inserted which is causing
an assertion failure. Any pointers to where I am wrong :

Code Dump :

Function *printFn=M.getNamedFunction(std::string("printf"));
Constant *str=ConstantArray::get("Value : %d\n");
std::vector<Value *> Args(2);
std::vector<Constant *> GEPIndices(2);
GEPIndices[0]=Constant::getNullValue(Type::LongTy);
GEPIndices[1]=Constant::getNullValue(Type::LongTy);
Args[0]=ConstantExpr::getGetElementPtr(strcon,GEPIndices);
Args[1]=ConstantInt::get(Type::IntTy, id);
Instruction * cI= new CallInst(printFn, Args, "retprintf",instr);

Thanks

I have this call instruction to printf inserted which is causing
an assertion failure. Any pointers to where I am wrong :

Function *printFn=M.getNamedFunction(std::string("printf"));

std::string() is unnecessary here as it's implicit.

Constant *str=ConstantArray::get("Value : %d\n");
std::vector<Value *> Args(2);
std::vector<Constant *> GEPIndices(2);
GEPIndices[0]=Constant::getNullValue(Type::LongTy);
GEPIndices[1]=Constant::getNullValue(Type::LongTy);
Args[0]=ConstantExpr::getGetElementPtr(strcon,GEPIndices);

You are using 'strcon', but you defined 'str' above. Where is 'strcon'
coming from?

Constant *strcon==ConstantArray::get("Value : %d\n");

Sorry Typo.

OK, then what's the assertion?

You can also see the resulting module by using -disable-verify:

$ opt -yourpass -disable-verify < file.bc | llvm-dis

You may see what the problem is by looking at the LLVM assembly.

I have a feeling that my getElementPtr is wrongly framed.

Thanks.

opt: Constants.cpp:1142: static llvm::Constant*
llvm::ConstantExpr::getGetElementPtr(llvm::Constant*, const
std::vector<llvm::Constant*, std::allocator<llvm::Constant*> >&):
Assertion `Ty && "GEP indices invalid!"' failed.

This is the llvm gcc error.

I'll try the disable-verify option. Thanks.

The problem here is that you are forming a getelementptr instruction where the first operand is an array, not a pointer. In particular, given a pointer to an aggregate, GEP returns a pointer to one of its elements.

To solve this problem, you need to create a new GlobalVariable object, initializing it with your constant array. Instead of using strcon, you use the global variable as the address of the string constant.

If you add this line above the ConstantExpr::getGetElementPtr line, things should work better for you (untested, but it should show the idea):

strcon = new GlobalVariable(strcon->getType(), true,
                             GlobalVariable::InternalLinkage, strcon, "", &M);

-Chris