I have the following snippet of code:
static LLVMContext TempContext;
Type * RetTy = Type::getVoidTy(TempContext)
for (Instruction *I : ListOfInstructions) {
if (isa<ReturnInst>(I)) {
RetTy = I->getOperand(0)->getType();
break
}
}
Where I am trying to capture the RetTy of a instruction, void or not, so I can use it on
getOrInsertFunction("TempF", FunctionType::get(RetTy, ArgsTys,false));
This code works as long as the ret instruction is not a ret void
.
I tried to add a second if
to check the void
case, but this does not seem to work, and execution stops on the in the FunctionType::get(...)
function, printing a back trace.
for (Instruction *I : ListOfInstructions) {
if (isa<ReturnInst>(I)) {
if ( I->getOperand(0)->getType() != Type::getVoidTy(TempContext)) {
RetTy = I->getOperand(0)->getType();
break
}
}
}
Note that removing the for
loop all together works and execution continues, as the function FunctionType::get(...)
handles the initialized Type * RetTy = Type::getVoidTy(TempContext)
"void" value for RetTy
just fine. But then I can't capture when a llvm function returns non-void values.
How do I know when an instruction I is a return instruction and it is returning Void in LLVM IR?
The problem with your current code is that ret void
does not have an operand, so calling getOperand(0)
accesses invalid data.
Replacing your if with:
if (ReturnInst *ri = dyn_cast<ReturnInst>(I))
{
if (ri->getNumOperands() == 0)
{
errs() << "VOID: " << *ri << "\n";
}
else
{
errs() << "NON-VOID: " << *ri << "\n";
}
}
Now, this code will output VOID: ret void
, having correctly detected the instruction.
As an alternative, you could retrieve the return type for the function using any instruction by relying on instructions being contained by a function I->getFunction()->getReturnType()
; however, this would assume that the function is well-formed and its ReturnInst matches its type and the instruction is part of a function.