本文整理汇总了C++中CallInst::doesNotReturn方法的典型用法代码示例。如果您正苦于以下问题:C++ CallInst::doesNotReturn方法的具体用法?C++ CallInst::doesNotReturn怎么用?C++ CallInst::doesNotReturn使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CallInst
的用法示例。
在下文中一共展示了CallInst::doesNotReturn方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: isValidCallInst
bool ScopDetection::isValidCallInst(CallInst &CI) {
if (CI.mayHaveSideEffects() || CI.doesNotReturn())
return false;
if (CI.doesNotAccessMemory())
return true;
Function *CalledFunction = CI.getCalledFunction();
// Indirect calls are not supported.
if (CalledFunction == 0)
return false;
// TODO: Intrinsics.
return false;
}
示例2: isValidCallInst
bool ScopDetection::isValidCallInst(CallInst &CI) {
if (CI.doesNotReturn())
return false;
if (CI.doesNotAccessMemory())
return true;
Function *CalledFunction = CI.getCalledFunction();
// Indirect calls are not supported.
if (CalledFunction == 0)
return false;
// Check if we can handle the intrinsic call.
if (auto *IT = dyn_cast<IntrinsicInst>(&CI)) {
switch (IT->getIntrinsicID()) {
// Lifetime markers are supported/ignored.
case llvm::Intrinsic::lifetime_start:
case llvm::Intrinsic::lifetime_end:
// Invariant markers are supported/ignored.
case llvm::Intrinsic::invariant_start:
case llvm::Intrinsic::invariant_end:
// Some misc annotations are supported/ignored.
case llvm::Intrinsic::var_annotation:
case llvm::Intrinsic::ptr_annotation:
case llvm::Intrinsic::annotation:
case llvm::Intrinsic::donothing:
case llvm::Intrinsic::assume:
case llvm::Intrinsic::expect:
return true;
default:
// Other intrinsics which may access the memory are not yet supported.
break;
}
}
return false;
}
示例3: runOnModule
//.........这里部分代码省略.........
Function *F = I->first;
Phis& P = I->second;
CallInst::Create(PrepSetjmp, "", F->begin()->begin());
// Update each call that can longjmp so it can return to a setjmp where relevant
for (Function::iterator BBI = F->begin(), E = F->end(); BBI != E; ) {
BasicBlock *BB = BBI++;
for (BasicBlock::iterator Iter = BB->begin(), E = BB->end(); Iter != E; ) {
Instruction *I = Iter++;
CallInst *CI;
if ((CI = dyn_cast<CallInst>(I))) {
Value *V = CI->getCalledValue();
if (V == PrepSetjmp || V == EmSetjmp || V == CheckLongjmp || V == GetLongjmpResult || V == PreInvoke || V == PostInvoke) continue;
if (Function *CF = dyn_cast<Function>(V)) if (CF->isIntrinsic()) continue;
// TODO: proper analysis of what can actually longjmp. Currently we assume anything but setjmp can.
// This may longjmp, so we need to check if it did. Split at that point, and
// envelop the call in pre/post invoke, if we need to
CallInst *After;
Instruction *Check = NULL;
if (Iter != E && (After = dyn_cast<CallInst>(Iter)) && After->getCalledValue() == PostInvoke) {
// use the pre|postinvoke that exceptions lowering already made
Check = Iter++;
}
BasicBlock *Tail = SplitBlock(BB, Iter); // Iter already points to the next instruction, as we need
TerminatorInst *TI = BB->getTerminator();
if (!Check) {
// no existing pre|postinvoke, create our own
CallInst::Create(PreInvoke, "", CI);
Check = CallInst::Create(PostInvoke, "", TI); // CI is at the end of the block
// If we are calling a function that is noreturn, we must remove that attribute. The code we
// insert here does expect it to return, after we catch the exception.
if (CI->doesNotReturn()) {
if (Function *F = dyn_cast<Function>(CI->getCalledValue())) {
F->removeFnAttr(Attribute::NoReturn);
}
CI->setAttributes(CI->getAttributes().removeAttribute(TheModule->getContext(), AttributeSet::FunctionIndex, Attribute::NoReturn));
assert(!CI->doesNotReturn());
}
}
// We need to replace the terminator in Tail - SplitBlock makes BB go straight to Tail, we need to check if a longjmp occurred, and
// go to the right setjmp-tail if so
SmallVector<Value *, 1> Args;
Args.push_back(Check);
Instruction *LongjmpCheck = CallInst::Create(CheckLongjmp, Args, "", BB);
Instruction *LongjmpResult = CallInst::Create(GetLongjmpResult, Args, "", BB);
SwitchInst *SI = SwitchInst::Create(LongjmpCheck, Tail, 2, BB);
// -1 means no longjmp happened, continue normally (will hit the default switch case). 0 means a longjmp that is not ours to handle, needs a rethrow. Otherwise
// the index mean is the same as the index in P+1 (to avoid 0).
for (unsigned i = 0; i < P.size(); i++) {
SI->addCase(cast<ConstantInt>(ConstantInt::get(i32, i+1)), P[i]->getParent());
P[i]->addIncoming(LongjmpResult, BB);
}
ToErase.push_back(TI); // new terminator is now the switch
// we are splitting the block here, and must continue to find other calls in the block - which is now split. so continue
// to traverse in the Tail
BB = Tail;
Iter = BB->begin();
E = BB->end();
} else if (InvokeInst *CI = dyn_cast<InvokeInst>(I)) { // XXX check if target is setjmp
(void)CI;
report_fatal_error("TODO: invoke inside setjmping functions");
}
}
}
// add a cleanup before each return
for (Function::iterator BBI = F->begin(), E = F->end(); BBI != E; ) {
BasicBlock *BB = BBI++;
TerminatorInst *TI = BB->getTerminator();
if (isa<ReturnInst>(TI)) {
CallInst::Create(CleanupSetjmp, "", TI);
}
}
}
for (unsigned i = 0; i < ToErase.size(); i++) {
ToErase[i]->eraseFromParent();
}
// Finally, our modifications to the cfg can break dominance of SSA variables. For example,
// if (x()) { .. setjmp() .. }
// if (y()) { .. longjmp() .. }
// We must split the longjmp block, and it can jump into the setjmp one. But that means that when
// we split the setjmp block, it's first part no longer dominates its second part - there is
// a theoretically possible control flow path where x() is false, then y() is true and we
// reach the second part of the setjmp block, without ever reaching the first part. So,
// we recalculate regs vs. mem
for (FunctionPhisMap::iterator I = SetjmpOutputPhis.begin(); I != SetjmpOutputPhis.end(); I++) {
Function *F = I->first;
doRegToMem(*F);
doMemToReg(*F);
}
return true;
}