class PostStmt : public StmtPoint {
protected:
- PostStmt(const Stmt* S, Kind k, const LocationContext *L, const void *tag = 0)
- : StmtPoint(S, NULL, k, L, tag) {}
-
PostStmt(const Stmt* S, const void* data, Kind k, const LocationContext *L,
const void *tag =0)
: StmtPoint(S, data, k, L, tag) {}
public:
+ explicit PostStmt(const Stmt* S, Kind k,
+ const LocationContext *L, const void *tag = 0)
+ : StmtPoint(S, NULL, k, L, tag) {}
+
explicit PostStmt(const Stmt* S, const LocationContext *L,const void *tag = 0)
: StmtPoint(S, NULL, PostStmtKind, L, tag) {}
ExprEngine &Eng;
ExplodedNode *Pred;
SaveAndRestore<bool> OldSink;
- SaveAndRestore<const void*> OldTag;
+ const void *checkerTag;
SaveAndRestore<ProgramPoint::Kind> OldPointKind;
SaveOr OldHasGen;
const GRState *ST;
const Stmt *stmt = 0, const GRState *st = 0)
: Dst(dst), B(builder), Eng(eng), Pred(pred),
OldSink(B.BuildSinks),
- OldTag(B.Tag, tag),
+ checkerTag(tag),
OldPointKind(B.PointKind, K),
OldHasGen(B.HasGeneratedNode),
ST(st), statement(stmt), size(Dst.size()),
ExplodedNode *generateNode(bool autoTransition = true) {
assert(statement && "Only transitions with statements currently supported");
- ExplodedNode *N = generateNodeImpl(statement, getState(), false);
+ ExplodedNode *N = generateNodeImpl(statement, getState(), false,
+ checkerTag);
if (N && autoTransition)
Dst.Add(N);
return N;
}
ExplodedNode *generateNode(const Stmt *stmt, const GRState *state,
- bool autoTransition = true) {
+ bool autoTransition = true, const void *tag = 0) {
assert(state);
- ExplodedNode *N = generateNodeImpl(stmt, state, false);
+ ExplodedNode *N = generateNodeImpl(stmt, state, false,
+ tag ? tag : checkerTag);
if (N && autoTransition)
addTransition(N);
return N;
return N;
}
- ExplodedNode *generateNode(const GRState *state, bool autoTransition = true) {
+ ExplodedNode *generateNode(const GRState *state, bool autoTransition = true,
+ const void *tag = 0) {
assert(statement && "Only transitions with statements currently supported");
- ExplodedNode *N = generateNodeImpl(statement, state, false);
+ ExplodedNode *N = generateNodeImpl(statement, state, false,
+ tag ? tag : checkerTag);
if (N && autoTransition)
addTransition(N);
return N;
}
ExplodedNode *generateSink(const Stmt *stmt, const GRState *state = 0) {
- return generateNodeImpl(stmt, state ? state : getState(), true);
+ return generateNodeImpl(stmt, state ? state : getState(), true,
+ checkerTag);
}
ExplodedNode *generateSink(const GRState *state = 0) {
assert(statement && "Only transitions with statements currently supported");
- return generateNodeImpl(statement, state ? state : getState(), true);
+ return generateNodeImpl(statement, state ? state : getState(), true,
+ checkerTag);
}
void addTransition(ExplodedNode *node) {
Dst.Add(node);
}
- void addTransition(const GRState *state) {
+ void addTransition(const GRState *state, const void *tag = 0) {
assert(state);
// If the 'state' is not new, we need to check if the cached state 'ST'
// is new.
if (state != getState() || (ST && ST != B.GetState(Pred)))
// state is new or equals to ST.
- generateNode(state, true);
+ generateNode(state, true, tag);
else
Dst.Add(Pred);
}
- // Generate a node with a new program point different from the one that will
- // be created by the StmtNodeBuilder.
- void addTransition(const GRState *state, ProgramPoint Loc) {
- ExplodedNode *N = B.generateNode(Loc, state, Pred);
- if (N)
- addTransition(N);
- }
-
void EmitReport(BugReport *R) {
Eng.getBugReporter().EmitReport(R);
}
private:
ExplodedNode *generateNodeImpl(const Stmt* stmt, const GRState *state,
- bool markAsSink) {
- ExplodedNode *node = B.generateNode(stmt, state, Pred);
+ bool markAsSink, const void *tag) {
+ ExplodedNode *node = B.generateNode(stmt, state, Pred, tag);
if (markAsSink && node)
node->markAsSink();
return node;
ExplodedNode *generateNodeImpl(const Stmt* stmt, const GRState *state,
ExplodedNode *pred, bool markAsSink) {
- ExplodedNode *node = B.generateNode(stmt, state, pred);
+ ExplodedNode *node = B.generateNode(stmt, state, pred, checkerTag);
if (markAsSink && node)
node->markAsSink();
return node;
}
ExplodedNode* generateNode(const Stmt *S, const GRState *St,
- ExplodedNode *Pred, ProgramPoint::Kind K) {
+ ExplodedNode *Pred, ProgramPoint::Kind K,
+ const void *tag = 0) {
HasGeneratedNode = true;
if (PurgingDeadSymbols)
K = ProgramPoint::PostPurgeDeadSymbolsKind;
- return generateNodeInternal(S, St, Pred, K, Tag);
+ return generateNodeInternal(S, St, Pred, K, tag ? tag : Tag);
}
ExplodedNode* generateNode(const Stmt *S, const GRState *St,
- ExplodedNode *Pred) {
- return generateNode(S, St, Pred, PointKind);
+ ExplodedNode *Pred, const void *tag = 0) {
+ return generateNode(S, St, Pred, PointKind, tag);
}
ExplodedNode *generateNode(const ProgramPoint &PP, const GRState* State,