[cfe-dev] How to know which edge the path is traversing?
Ted Kremenek
kremenek at apple.com
Fri May 16 09:10:40 PDT 2008
On May 16, 2008, at 7:32 AM, Zhongxing Xu wrote:
> I use GRCoreEngine to do a path sensitive analysis. For example, I
> can get two paths for the program below:
>
> int f(int n) {
> if (n > 0)
> ...
> else
> ...
> }
>
> I can use the nodes in EndNodes to get these two paths (by
> backtracking from endnodes).
> There are two BlockEdgeDst nodes after the block containing the
> IfStmt "if (n>0)".
> How can I know which path is led by the condition n > 0 or n <= 0?
> That is, how can I know which is the "true"/"false" branch edge?
Hi Zhongxing,
You will want to inspect the successors CFBBlocks of the "source" in
the BlockEdge, and compare it against the destination. For CFGBlock's
whose terminator is a branch (if statements, loops, etc), the first
successor block is the true branch, the and second successor block is
the false branch. For example:
ProgramPoint P = N->getLocation(); // N is an ExplodedNode<...>
if (BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
CFGBlock* Src = BE->getSrc();
CFGBlock* Dst = BE->getDst();
// Test if we are at a (binary) branch.
if (Src.hasBinaryBranchTerminator()) {
if (*Src.succ_begin() == Dst) {
// We took the true branch.
}
else {
assert (*(Src.succ_begin()+1) == Dst);
// We took the false branch.
}
}
}
Note that "hasBinaryBranchTerminator" only returns true for
terminators that are "ForStmt", "WhileStmt", "DoStmt", "IfStmt",
"ChooseExpr", "ConditionalOperator", and "BinaryOperator" (for '&&'
and '||'). IndirectGotoStmt and SwitchStmt work differently.
IndirectGotoStmt always branches to a special block where the actual
indirect goto takes place (do a CFG dump of code with a labeled goto
to see what I mean). Blocks that have a SwitchStmt terminator have as
their successor blocks the targets of the switch. In that case, each
successor block should have "getLabel()" return a SwitchStmt, with the
exception of the last successor. The last successor is always the
"default" branch, which may be explicit (with a "default:" label) or
implicit (in the case of fall-through to the code after the switch
block).
BTW, "hasBinaryBranchTerminator" was a recently added predicate
method. Most code that inspects terminators actually uses a switch
statement on the statement class of the terminator to handle both
binary branches and other terminator types.
Ted
More information about the cfe-dev
mailing list