本文整理汇总了C++中PEdge::IfCall方法的典型用法代码示例。如果您正苦于以下问题:C++ PEdge::IfCall方法的具体用法?C++ PEdge::IfCall怎么用?C++ PEdge::IfCall使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类PEdge
的用法示例。
在下文中一共展示了PEdge::IfCall方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: InferSummaries
//.........这里部分代码省略.........
}
}
for (size_t eind = 0; eind < cfg->GetEdgeCount(); eind++) {
PEdge *edge = cfg->GetEdge(eind);
PPoint point = edge->GetSource();
if (PEdgeAnnotation *nedge = edge->IfAnnotation()) {
// add an assertion for this annotation if it not an assume.
BlockCFG *annot_cfg = GetAnnotationCFG(nedge->GetAnnotationId());
if (!annot_cfg) continue;
if (annot_cfg->GetAnnotationKind() != AK_Assert &&
annot_cfg->GetAnnotationKind() != AK_AssertRuntime) {
continue;
}
if (Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg)) {
AssertInfo info;
info.kind = (annot_cfg->GetAnnotationKind() == AK_Assert)
? ASK_Annotation : ASK_AnnotationRuntime;
info.cls = ASC_Check;
info.point = point;
info.bit = bit;
asserts.PushBack(info);
}
}
// add assertions for any invariants affected by a write.
Exp *left = NULL;
if (PEdgeAssign *nedge = edge->IfAssign())
left = nedge->GetLeftSide();
if (PEdgeCall *nedge = edge->IfCall())
left = nedge->GetReturnValue();
// for now our detection of affected invariants is pretty crude;
// writes to fields can affect type invariants on the field's type
// which use that field, and writes to global variables can affect
// invariants on that global. TODO: pin this down once we draw a
// precise line between which invariants can and can't be checked.
if (left && left->IsFld()) {
ExpFld *nleft = left->AsFld();
String *csu_name = nleft->GetField()->GetCSUType()->GetCSUName();
Vector<BlockCFG*> *comp_annot_list = CompAnnotCache.Lookup(csu_name);
for (size_t aind = 0; comp_annot_list &&
aind < comp_annot_list->Size(); aind++) {
BlockCFG *annot_cfg = comp_annot_list->At(aind);
if (annot_cfg->GetAnnotationKind() != AK_Invariant)
continue;
Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg);
if (!bit) continue;
Vector<Exp*> lval_list;
LvalListVisitor visitor(&lval_list);
bit->DoVisit(&visitor);
bool uses_field = false;
for (size_t ind = 0; ind < lval_list.Size(); ind++) {
if (ExpFld *lval = lval_list[ind]->IfFld()) {
if (lval->GetField() == nleft->GetField())
uses_field = true;
}
示例2: GetMatchingHeapWrites
void GetMatchingHeapWrites(const EscapeAccess &heap_write,
Vector<HeapWriteInfo> *writes)
{
BlockId *id = heap_write.where.id;
BlockMemory *mcfg = GetBlockMemory(id);
if (mcfg == NULL) {
logout << "WARNING: Missing memory: '" << id << "'" << endl;
return;
}
BlockCFG *cfg = mcfg->GetCFG();
// for incremental analysis, make sure the write CFG uses the right version.
// as for checking callers, if the CFG has changed but the new one still
// has a matching write, we will see an escape access for the new CFG.
if (cfg->GetVersion() != heap_write.where.version) {
if (checker_verbose.IsSpecified())
logout << "CHECK: Write is an older version: "
<< heap_write.where.id << ": "
<< heap_write.where.version << endl;
mcfg->DecRef();
return;
}
PPoint point = heap_write.where.point;
PPoint exit_point = mcfg->GetCFG()->GetExitPoint();
// find a point-relative lvalue written at the write point with
// the sanitized representation from the heap_write trace.
// TODO: we only match against direct assignments in the CFG for now,
// ignoring structural copies (which are simple recursive writes).
PEdge *edge = cfg->GetSingleOutgoingEdge(point);
Exp *point_lval = NULL;
if (PEdgeAssign *nedge = edge->IfAssign())
point_lval = nedge->GetLeftSide();
else if (PEdgeCall *nedge = edge->IfCall())
point_lval = nedge->GetReturnValue();
bool lval_matches = false;
if (point_lval) {
if (Exp *new_point_lval = Trace::SanitizeExp(point_lval)) {
lval_matches = (new_point_lval == heap_write.target->GetValue());
new_point_lval->DecRef();
}
}
if (!lval_matches) {
mcfg->DecRef();
return;
}
// it would be nice to remove Val() expressions from this list, but we can't
// do that as lvalues in memory assignments can contain Val and we want to
// see the effects of those assignments. TODO: fix.
GuardExpVector lval_res;
mcfg->TranslateExp(TRK_Point, point, point_lval, &lval_res);
for (size_t ind = 0; ind < lval_res.Size(); ind++) {
const GuardExp &lv = lval_res[ind];
HeapWriteInfo info;
info.mcfg = mcfg;
info.lval = lv.exp;
info.base_lval = point_lval;
// look for a condition where the lvalue is not written.
GuardExpVector exit_vals;
info.mcfg->GetValComplete(info.lval, NULL, exit_point, &exit_vals);
for (size_t ind = 0; ind < exit_vals.Size(); ind++) {
const GuardExp &val = exit_vals[ind];
// exclude cases where the lvalue refers to its value at block entry.
if (ExpDrf *nval = val.exp->IfDrf()) {
if (nval->GetTarget() == info.lval)
info.exclude.PushBack(val.guard);
}
}
if (!writes->Contains(info)) {
info.mcfg->IncRef(writes);
info.lval->IncRef(writes);
info.base_lval->IncRef(writes);
IncRefVector<Bit>(info.exclude, writes);
writes->PushBack(info);
}
}
mcfg->DecRef();
}
示例3: TryPropagate
Where* CheckerPropagate::TryPropagate(Bit *bit, Exp *lval)
{
BlockMemory *mcfg = m_frame->Memory();
TypeCSU *csu = NULL;
Exp *csu_lval = NULL;
if (UseHeapExp(lval, &csu, &csu_lval)) {
// do the heap propagation unless we are trying to push heap data
// up into the caller.
if (!m_prefer_precondition ||
!UseCallerExp(lval, m_frame->Kind() == B_Function) ||
(m_frame->Kind() == B_Loop && !mcfg->IsExpPreserved(lval))) {
Where *res = WhereInvariant::Make(csu, csu_lval, bit);
if (res)
return res;
// fall through, we might still be able to treat this as a precondition.
}
}
if (UseCallerExp(lval, m_frame->Kind() == B_Function))
return WherePrecondition::Make(m_frame->Memory(), bit);
if (PPoint point = UseCalleeExp(lval)) {
// fail propagation if this is from a later callee than the point
// this propagation occurs at. this can come up when generating
// sufficient conditions.
if (point > m_point || (point == m_point && !m_allow_point))
return NULL;
// cutoff propagation if the buffer came from a primitive memory
// allocator. if we find a sufficient condition that does not
// mention the allocator we could continue propagation.
PEdge *edge = mcfg->GetCFG()->GetSingleOutgoingEdge(point);
PEdgeCall *edge_call = edge->IfCall();
Variable *callee = edge_call ? edge_call->GetDirectFunction() : NULL;
Exp *callee_base;
Exp *callee_size;
if (callee && GetAllocationFunction(callee, &callee_base, &callee_size)) {
callee_base->DecRef();
callee_size->DecRef();
if (lval->IsBound())
lval = lval->GetLvalTarget();
// ignore this if it refers to fields or other structures
// in the result of the allocation. this data is either
// uninitialized or zeroed, either way we don't care.
if (ExpClobber *nlval = lval->IfClobber()) {
Exp *callee_lval = nlval->GetCallee();
Exp *callee_target = NULL;
if (nlval->GetValueKind() == NULL) {
callee_target = callee_lval;
}
else {
// skip the first dereference. for terminators we still depend on
// the initial contents of the allocated buffer.
if (ExpExit *ncallee = callee_lval->IfExit())
callee_target = ncallee->GetTarget();
}
if (callee_target) {
while (callee_target->IsFld())
callee_target = callee_target->GetLvalTarget();
if (callee_target->IsExit())
return new WhereNone(RK_None);
}
}
// watch for accessing indexes of a buffer returned via the allocator,
// which currently aren't mapped back into the callee correctly.
// TODO: fix hack.
if (lval->IsDrf() && lval->GetLvalTarget()->IsIndex())
return new WhereNone(RK_None);
return new WhereNone(RK_Finished);
}
if (callee && IsCutoffFunction(callee))
return new WhereNone(RK_Finished);
return WherePostcondition::Make(m_frame, point, bit);
}
return NULL;
}