如何验证LLVM“ret”指令是否返回void?

时间:2017-09-29 21:48:02

标签: c++ compiler-construction llvm llvm-ir

我有以下代码片段:

static LLVMContext TempContext;
Type * RetTy = Type::getVoidTy(TempContext)
for (Instruction *I : ListOfInstructions) {
  if (isa<ReturnInst>(I)) {
    RetTy = I->getOperand(0)->getType();
    break
  }
}

我试图捕捉 Retty of a instruction ,无效或无效,所以我可以在

上使用它
getOrInsertFunction("TempF", FunctionType::get(RetTy, ArgsTys,false));

只要ret指令不是ret void

就可以使用此代码

我尝试添加第二个if来检查void情况,但这似乎不起作用,执行在FunctionType::get(...)函数中停止,打印后跟踪

for (Instruction *I : ListOfInstructions) {
  if (isa<ReturnInst>(I)) {
    if ( I->getOperand(0)->getType() != Type::getVoidTy(TempContext)) {
      RetTy = I->getOperand(0)->getType();
      break
    }
  }
}                                            

请注意,删除for循环一起工作并继续执行,因为函数FunctionType::get(...)处理Type * RetTy = Type::getVoidTy(TempContext)的初始化RetTy“void”值就好了。但是当llvm函数返回非void值时,我无法捕获。

我如何知道指令I何时是返回指令并且它在LLVM IR中返回Void?

1 个答案:

答案 0 :(得分:4)

您当前代码的问题是ret void没有操作数,因此调用getOperand(0)会访问无效数据。

将if替换为:

if (ReturnInst *ri = dyn_cast<ReturnInst>(I))
{
  if (ri->getNumOperands() == 0)
  {
    errs() << "VOID: " << *ri << "\n";
  }
  else
  {
    errs() << "NON-VOID: " << *ri << "\n";
  }
}

现在,此代码将输出VOID: ret void,并已正确检测到指令。

作为替代方案,您可以依靠函数I->getFunction()->getReturnType()包含的指令,使用任何指令检索函数的返回类型;但是,这将假设函数格式正确并且其ReturnInst与其类型匹配,并且指令是函数的一部分。