Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 6 additions & 26 deletions clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,47 +429,27 @@ class BranchNodeBuilder: public NodeBuilder {
const CFGBlock *DstT;
const CFGBlock *DstF;

bool InFeasibleTrue;
bool InFeasibleFalse;

void anchor() override;

public:
BranchNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
const NodeBuilderContext &C,
const CFGBlock *dstT, const CFGBlock *dstF)
: NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF),
InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
const NodeBuilderContext &C, const CFGBlock *DT,
const CFGBlock *DF)
: NodeBuilder(SrcNode, DstSet, C), DstT(DT), DstF(DF) {
// The branch node builder does not generate autotransitions.
// If there are no successors it means that both branches are infeasible.
takeNodes(SrcNode);
}

BranchNodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
const NodeBuilderContext &C,
const CFGBlock *dstT, const CFGBlock *dstF)
: NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF),
InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
const NodeBuilderContext &C, const CFGBlock *DT,
const CFGBlock *DF)
: NodeBuilder(SrcSet, DstSet, C), DstT(DT), DstF(DF) {
takeNodes(SrcSet);
}

ExplodedNode *generateNode(ProgramStateRef State, bool branch,
ExplodedNode *Pred);

const CFGBlock *getTargetBlock(bool branch) const {
return branch ? DstT : DstF;
}

void markInfeasible(bool branch) {
if (branch)
InFeasibleTrue = true;
else
InFeasibleFalse = true;
}

bool isFeasible(bool branch) {
return branch ? !InFeasibleTrue : !InFeasibleFalse;
}
};

class IndirectGotoNodeBuilder {
Expand Down
11 changes: 6 additions & 5 deletions clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -649,14 +649,15 @@ StmtNodeBuilder::~StmtNodeBuilder() {
void BranchNodeBuilder::anchor() {}

ExplodedNode *BranchNodeBuilder::generateNode(ProgramStateRef State,
bool branch,
bool Branch,
ExplodedNode *NodePred) {
// If the branch has been marked infeasible we should not generate a node.
if (!isFeasible(branch))
const CFGBlock *Dst = Branch ? DstT : DstF;

if (!Dst)
return nullptr;

ProgramPoint Loc = BlockEdge(C.getBlock(), branch ? DstT : DstF,
NodePred->getLocationContext());
ProgramPoint Loc =
BlockEdge(C.getBlock(), Dst, NodePred->getLocationContext());
ExplodedNode *Succ = generateNodeImpl(Loc, State, NodePred);
return Succ;
}
Expand Down
37 changes: 9 additions & 28 deletions clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1655,10 +1655,8 @@ void ExprEngine::processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE,
ProgramStateRef State = Pred->getState();
const LocationContext *LC = Pred->getLocationContext();
if (getObjectUnderConstruction(State, BTE, LC)) {
TempDtorBuilder.markInfeasible(false);
TempDtorBuilder.generateNode(State, true, Pred);
} else {
TempDtorBuilder.markInfeasible(true);
TempDtorBuilder.generateNode(State, false, Pred);
}
}
Expand Down Expand Up @@ -2778,7 +2776,6 @@ void ExprEngine::processBranch(const Stmt *Condition,
// Check for NULL conditions; e.g. "for(;;)"
if (!Condition) {
BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF);
NullCondBldr.markInfeasible(false);
NullCondBldr.generateNode(Pred->getState(), true, Pred);
return;
}
Expand All @@ -2798,40 +2795,25 @@ void ExprEngine::processBranch(const Stmt *Condition,
if (CheckersOutSet.empty())
return;

BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF);
BranchNodeBuilder Builder(CheckersOutSet, Dst, BldCtx, DstT, DstF);
for (ExplodedNode *PredN : CheckersOutSet) {
if (PredN->isSink())
continue;

ProgramStateRef PrevState = PredN->getState();

ProgramStateRef StTrue, StFalse;
ProgramStateRef StTrue = PrevState, StFalse = PrevState;
if (const auto KnownCondValueAssumption = assumeCondition(Condition, PredN))
std::tie(StTrue, StFalse) = *KnownCondValueAssumption;
else {
assert(!isa<ObjCForCollectionStmt>(Condition));
builder.generateNode(PrevState, true, PredN);
builder.generateNode(PrevState, false, PredN);
continue;
}

if (StTrue && StFalse)
assert(!isa<ObjCForCollectionStmt>(Condition));

// Process the true branch.
if (builder.isFeasible(true)) {
if (StTrue)
builder.generateNode(StTrue, true, PredN);
else
builder.markInfeasible(true);
}
if (StTrue)
Builder.generateNode(StTrue, true, PredN);

// Process the false branch.
if (builder.isFeasible(false)) {
if (StFalse)
builder.generateNode(StFalse, false, PredN);
else
builder.markInfeasible(false);
}
if (StFalse)
Builder.generateNode(StFalse, false, PredN);
}
currBldrCtx = nullptr;
}
Expand All @@ -2853,14 +2835,13 @@ void ExprEngine::processStaticInitializer(const DeclStmt *DS,
const auto *VD = cast<VarDecl>(DS->getSingleDecl());
ProgramStateRef state = Pred->getState();
bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
BranchNodeBuilder builder(Pred, Dst, BuilderCtx, DstT, DstF);
BranchNodeBuilder Builder(Pred, Dst, BuilderCtx, DstT, DstF);

if (!initHasRun) {
state = state->add<InitializedGlobalsSet>(VD);
}

builder.generateNode(state, initHasRun, Pred);
builder.markInfeasible(!initHasRun);
Builder.generateNode(state, initHasRun, Pred);

currBldrCtx = nullptr;
}
Expand Down