зеркало из https://github.com/microsoft/clang-1.git
[analyzer] Rename generateNode -> addTransition in CheckerContext
Also document addTransition methods. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143059 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
1d08123ae7
Коммит
0bd6b110e9
|
@ -87,36 +87,50 @@ public:
|
|||
return Eng.getStateManager();
|
||||
}
|
||||
|
||||
|
||||
AnalysisDeclContext *getCurrentAnalysisDeclContext() const {
|
||||
return Pred->getLocationContext()->getAnalysisDeclContext();
|
||||
}
|
||||
|
||||
/// \brief Generate a default checker node (containing checker tag but no
|
||||
/// checker state changes).
|
||||
ExplodedNode *generateNode() {
|
||||
return generateNode(getState());
|
||||
}
|
||||
|
||||
/// \brief Generate a new checker node.
|
||||
ExplodedNode *generateNode(const ProgramState *state,
|
||||
const ProgramPointTag *tag = 0) {
|
||||
return generateNodeImpl(state, false, 0, tag);
|
||||
/// \brief Generates a new transition in the program state graph
|
||||
/// (ExplodedGraph). Uses the default CheckerContext predecessor node.
|
||||
///
|
||||
/// @param State The state of the generated node.
|
||||
/// @param Tag The tag is used to uniquely identify the creation site. If no
|
||||
/// tag is specified, a default tag, unique to the given checker,
|
||||
/// will be used. Tags are used to prevent states generated at
|
||||
/// different sites from caching out.
|
||||
ExplodedNode *addTransition(const ProgramState *State,
|
||||
const ProgramPointTag *Tag = 0) {
|
||||
return addTransitionImpl(State, false, 0, Tag);
|
||||
}
|
||||
|
||||
/// \brief Generate a new checker node with the given predecessor.
|
||||
/// \brief Generates a default transition (containing checker tag but no
|
||||
/// checker state changes).
|
||||
// TODO: Can we remove this one? We always generate autotransitions.
|
||||
ExplodedNode *addTransition() {
|
||||
return addTransition(getState());
|
||||
}
|
||||
|
||||
/// \brief Generates a new transition with the given predecessor.
|
||||
/// Allows checkers to generate a chain of nodes.
|
||||
ExplodedNode *generateNode(const ProgramState *state,
|
||||
ExplodedNode *pred,
|
||||
const ProgramPointTag *tag = 0,
|
||||
bool isSink = false) {
|
||||
return generateNodeImpl(state, isSink, pred, tag);
|
||||
///
|
||||
/// @param State The state of the generated node.
|
||||
/// @param Pred The transition will be generated from the specified Pred node
|
||||
/// to the newly generated node.
|
||||
/// @param Tag The tag to uniquely identify the creation site.
|
||||
/// @param IsSink Mark the new node as sink, which will stop exploration of
|
||||
/// the given path.
|
||||
ExplodedNode *addTransition(const ProgramState *State,
|
||||
ExplodedNode *Pred,
|
||||
const ProgramPointTag *Tag = 0,
|
||||
bool IsSink = false) {
|
||||
return addTransitionImpl(State, IsSink, Pred, Tag);
|
||||
}
|
||||
|
||||
/// \brief Generate a sink node. Generating sink stops exploration of the
|
||||
/// given path.
|
||||
ExplodedNode *generateSink(const ProgramState *state = 0) {
|
||||
return generateNodeImpl(state ? state : getState(), true);
|
||||
return addTransitionImpl(state ? state : getState(), true);
|
||||
}
|
||||
|
||||
/// \brief Emit the diagnostics report.
|
||||
|
@ -124,6 +138,9 @@ public:
|
|||
Eng.getBugReporter().EmitReport(R);
|
||||
}
|
||||
|
||||
/// \brief Emit a very simple diagnostic report. Should only be used for
|
||||
/// non-path sensitive checkers.
|
||||
// TODO: We should not need it here!
|
||||
void EmitBasicReport(StringRef Name,
|
||||
StringRef Category,
|
||||
StringRef Str, PathDiagnosticLocation Loc,
|
||||
|
@ -133,7 +150,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
ExplodedNode *generateNodeImpl(const ProgramState *state,
|
||||
ExplodedNode *addTransitionImpl(const ProgramState *state,
|
||||
bool markAsSink,
|
||||
ExplodedNode *pred = 0,
|
||||
const ProgramPointTag *tag = 0) {
|
||||
|
|
|
@ -46,7 +46,7 @@ void AdjustedReturnValueChecker::checkPostStmt(const CallExpr *CE,
|
|||
|
||||
// Casting to void? Discard the value.
|
||||
if (expectedResultTy->isVoidType()) {
|
||||
C.generateNode(state->BindExpr(CE, UnknownVal()));
|
||||
C.addTransition(state->BindExpr(CE, UnknownVal()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ void AdjustedReturnValueChecker::checkPostStmt(const CallExpr *CE,
|
|||
// the cast avoids some assertion failures elsewhere.
|
||||
SValBuilder &svalBuilder = C.getSValBuilder();
|
||||
V = svalBuilder.evalCast(V, expectedResultTy, actualResultTy);
|
||||
C.generateNode(state->BindExpr(CE, V));
|
||||
C.addTransition(state->BindExpr(CE, V));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
|
|||
|
||||
// Array bound check succeeded. From this point forward the array bound
|
||||
// should always succeed.
|
||||
C.generateNode(StInBound);
|
||||
C.addTransition(StInBound);
|
||||
}
|
||||
|
||||
void ento::registerArrayBoundChecker(CheckerManager &mgr) {
|
||||
|
|
|
@ -166,7 +166,7 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
|
|||
while (false);
|
||||
|
||||
if (state != originalState)
|
||||
checkerContext.generateNode(state);
|
||||
checkerContext.addTransition(state);
|
||||
}
|
||||
|
||||
void ArrayBoundCheckerV2::reportOOB(CheckerContext &checkerContext,
|
||||
|
|
|
@ -125,7 +125,7 @@ void AttrNonNullChecker::checkPreStmt(const CallExpr *CE,
|
|||
|
||||
// If we reach here all of the arguments passed the nonnull check.
|
||||
// If 'state' has been updated generated a new node.
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void ento::registerAttrNonNullChecker(CheckerManager &mgr) {
|
||||
|
|
|
@ -316,7 +316,7 @@ void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
|
|||
// the bits initialized to the provided values.
|
||||
//
|
||||
if (ExplodedNode *N = SourceSize < TargetSize ? C.generateSink()
|
||||
: C.generateNode()) {
|
||||
: C.addTransition()) {
|
||||
llvm::SmallString<128> sbuf;
|
||||
llvm::raw_svector_ostream os(sbuf);
|
||||
|
||||
|
@ -421,7 +421,7 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
|
|||
}
|
||||
|
||||
// From here on, we know the argument is non-null.
|
||||
C.generateNode(stateFalse);
|
||||
C.addTransition(stateFalse);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -464,7 +464,7 @@ void ClassReleaseChecker::checkPreObjCMessage(ObjCMessage msg,
|
|||
if (!(S == releaseS || S == retainS || S == autoreleaseS || S == drainS))
|
||||
return;
|
||||
|
||||
if (ExplodedNode *N = C.generateNode()) {
|
||||
if (ExplodedNode *N = C.addTransition()) {
|
||||
llvm::SmallString<200> buf;
|
||||
llvm::raw_svector_ostream os(buf);
|
||||
|
||||
|
@ -612,7 +612,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
|
|||
|
||||
// Generate only one error node to use for all bug reports.
|
||||
if (!errorNode.hasValue()) {
|
||||
errorNode = C.generateNode();
|
||||
errorNode = C.addTransition();
|
||||
}
|
||||
|
||||
if (!errorNode.getValue())
|
||||
|
|
|
@ -49,7 +49,7 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
|
|||
// For __builtin_expect, just return the value of the subexpression.
|
||||
assert (CE->arg_begin() != CE->arg_end());
|
||||
SVal X = state->getSVal(*(CE->arg_begin()));
|
||||
C.generateNode(state->BindExpr(CE, X));
|
||||
C.addTransition(state->BindExpr(CE, X));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
|
|||
svalBuilder.evalEQ(state, Extent, Size);
|
||||
state = state->assume(extentMatchesSizeArg, true);
|
||||
|
||||
C.generateNode(state->BindExpr(CE, loc::MemRegionVal(R)));
|
||||
C.addTransition(state->BindExpr(CE, loc::MemRegionVal(R)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -659,7 +659,7 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, const ProgramState *&st
|
|||
// C string. In the context of locations, the only time we can issue such
|
||||
// a warning is for labels.
|
||||
if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&Buf)) {
|
||||
if (ExplodedNode *N = C.generateNode(state)) {
|
||||
if (ExplodedNode *N = C.addTransition(state)) {
|
||||
if (!BT_NotCString)
|
||||
BT_NotCString.reset(new BuiltinBug("API",
|
||||
"Argument is not a null-terminated string."));
|
||||
|
@ -716,7 +716,7 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, const ProgramState *&st
|
|||
// Other regions (mostly non-data) can't have a reliable C string length.
|
||||
// In this case, an error is emitted and UndefinedVal is returned.
|
||||
// The caller should always be prepared to handle this case.
|
||||
if (ExplodedNode *N = C.generateNode(state)) {
|
||||
if (ExplodedNode *N = C.addTransition(state)) {
|
||||
if (!BT_NotCString)
|
||||
BT_NotCString.reset(new BuiltinBug("API",
|
||||
"Argument is not a null-terminated string."));
|
||||
|
@ -859,7 +859,7 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
|
|||
// just bind the return value to the destination buffer and return.
|
||||
if (stateZeroSize) {
|
||||
stateZeroSize = stateZeroSize->BindExpr(CE, destVal);
|
||||
C.generateNode(stateZeroSize);
|
||||
C.addTransition(stateZeroSize);
|
||||
}
|
||||
|
||||
// If the size can be nonzero, we have to check the other arguments.
|
||||
|
@ -931,7 +931,7 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
|
|||
// This would probably remove any existing bindings past the end of the
|
||||
// copied region, but that's still an improvement over blank invalidation.
|
||||
state = InvalidateBuffer(C, state, Dest, state->getSVal(Dest));
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -993,7 +993,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
|
|||
if (stateZeroSize) {
|
||||
state = stateZeroSize;
|
||||
state = state->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
// If the size can be nonzero, we have to check the other arguments.
|
||||
|
@ -1017,7 +1017,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
|
|||
state = CheckBufferAccess(C, state, Size, Left);
|
||||
if (state) {
|
||||
state = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1031,7 +1031,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
|
|||
unsigned Count = C.getCurrentBlockCount();
|
||||
SVal CmpV = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
|
||||
state = state->BindExpr(CE, CmpV);
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1067,7 +1067,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
|
|||
if (stateZeroSize) {
|
||||
SVal zero = C.getSValBuilder().makeZeroVal(CE->getType());
|
||||
stateZeroSize = stateZeroSize->BindExpr(CE, zero);
|
||||
C.generateNode(stateZeroSize);
|
||||
C.addTransition(stateZeroSize);
|
||||
}
|
||||
|
||||
// If the size is GUARANTEED to be zero, we're done!
|
||||
|
@ -1170,7 +1170,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
|
|||
// Bind the return value.
|
||||
assert(!result.isUnknown() && "Should have conjured a value by now");
|
||||
state = state->BindExpr(CE, result);
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const {
|
||||
|
@ -1512,7 +1512,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
|
|||
|
||||
// Set the return value.
|
||||
state = state->BindExpr(CE, Result);
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void CStringChecker::evalStrcmp(CheckerContext &C, const CallExpr *CE) const {
|
||||
|
@ -1582,7 +1582,7 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
|
|||
// and we only need to check one size.
|
||||
if (StSameBuf) {
|
||||
StSameBuf = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
|
||||
C.generateNode(StSameBuf);
|
||||
C.addTransition(StSameBuf);
|
||||
|
||||
// If the two arguments are GUARANTEED to be the same, we're done!
|
||||
if (!StNotSameBuf)
|
||||
|
@ -1656,7 +1656,7 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
|
|||
}
|
||||
|
||||
// Record this as a possible path.
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1746,7 +1746,7 @@ void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
|
|||
state = state->set<CStringLength>(MR, strLength);
|
||||
}
|
||||
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
bool CStringChecker::wantsRegionChangeUpdate(const ProgramState *state) const {
|
||||
|
@ -1842,7 +1842,7 @@ void CStringChecker::checkDeadSymbols(SymbolReaper &SR,
|
|||
}
|
||||
|
||||
state = state->set<CStringLength>(Entries);
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void ento::registerCStringChecker(CheckerManager &mgr) {
|
||||
|
|
|
@ -312,7 +312,7 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
|
|||
|
||||
// The result is not consumed by a surrounding expression. Just propagate
|
||||
// the current state.
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -349,11 +349,11 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
|
|||
// of this case unless we have *a lot* more knowledge.
|
||||
//
|
||||
SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx));
|
||||
C.generateNode(state->BindExpr(msg.getOriginExpr(), V));
|
||||
C.addTransition(state->BindExpr(msg.getOriginExpr(), V));
|
||||
return;
|
||||
}
|
||||
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void ento::registerCallAndMessageChecker(CheckerManager &mgr) {
|
||||
|
|
|
@ -56,7 +56,7 @@ void CastToStructChecker::checkPreStmt(const CastExpr *CE,
|
|||
|
||||
// Now the cast-to-type is struct pointer, the original type is not void*.
|
||||
if (!OrigPointeeTy->isRecordType()) {
|
||||
if (ExplodedNode *N = C.generateNode()) {
|
||||
if (ExplodedNode *N = C.addTransition()) {
|
||||
if (!BT)
|
||||
BT.reset(new BuiltinBug("Cast from non-struct type to struct type",
|
||||
"Casting a non-structure type to a structure type "
|
||||
|
|
|
@ -94,7 +94,7 @@ void ChrootChecker::Chroot(CheckerContext &C, const CallExpr *CE) const {
|
|||
// Once encouter a chroot(), set the enum value ROOT_CHANGED directly in
|
||||
// the GDM.
|
||||
state = Mgr.addGDM(state, ChrootChecker::getTag(), (void*) ROOT_CHANGED);
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void ChrootChecker::Chdir(CheckerContext &C, const CallExpr *CE) const {
|
||||
|
@ -120,7 +120,7 @@ void ChrootChecker::Chdir(CheckerContext &C, const CallExpr *CE) const {
|
|||
}
|
||||
}
|
||||
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
// Check the jail state before any function call except chroot and chdir().
|
||||
|
@ -146,7 +146,7 @@ void ChrootChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
|
|||
void *const* k = state->FindGDM(ChrootChecker::getTag());
|
||||
if (k)
|
||||
if (isRootChanged((intptr_t) *k))
|
||||
if (ExplodedNode *N = C.generateNode()) {
|
||||
if (ExplodedNode *N = C.addTransition()) {
|
||||
if (!BT_BreakJail)
|
||||
BT_BreakJail.reset(new BuiltinBug("Break out of jail",
|
||||
"No call of chdir(\"/\") immediately "
|
||||
|
|
|
@ -184,7 +184,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
|
|||
}
|
||||
|
||||
// From this point forward, we know that the location is not null.
|
||||
C.generateNode(notNullState);
|
||||
C.addTransition(notNullState);
|
||||
}
|
||||
|
||||
void ento::registerDereferenceChecker(CheckerManager &mgr) {
|
||||
|
|
|
@ -73,7 +73,7 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
|
|||
|
||||
// If we get here, then the denom should not be zero. We abandon the implicit
|
||||
// zero denom case for now.
|
||||
C.generateNode(stateNotZero);
|
||||
C.addTransition(stateNotZero);
|
||||
}
|
||||
|
||||
void ento::registerDivZeroChecker(CheckerManager &mgr) {
|
||||
|
|
|
@ -51,7 +51,7 @@ void FixedAddressChecker::checkPreStmt(const BinaryOperator *B,
|
|||
if (!RV.isConstant() || RV.isZeroConstant())
|
||||
return;
|
||||
|
||||
if (ExplodedNode *N = C.generateNode()) {
|
||||
if (ExplodedNode *N = C.addTransition()) {
|
||||
if (!BT)
|
||||
BT.reset(new BuiltinBug("Use fixed address",
|
||||
"Using a fixed address is not portable because that "
|
||||
|
|
|
@ -405,7 +405,7 @@ void IteratorsChecker::checkExpr(CheckerContext &C, const Expr *E) const {
|
|||
if (!RS)
|
||||
return;
|
||||
if (RS->isInvalid()) {
|
||||
if (ExplodedNode *N = C.generateNode()) {
|
||||
if (ExplodedNode *N = C.addTransition()) {
|
||||
if (!BT_Invalid)
|
||||
// FIXME: We are eluding constness here.
|
||||
const_cast<IteratorsChecker*>(this)->BT_Invalid = new BuiltinBug("");
|
||||
|
@ -428,7 +428,7 @@ void IteratorsChecker::checkExpr(CheckerContext &C, const Expr *E) const {
|
|||
}
|
||||
}
|
||||
else if (RS->isUndefined()) {
|
||||
if (ExplodedNode *N = C.generateNode()) {
|
||||
if (ExplodedNode *N = C.addTransition()) {
|
||||
if (!BT_Undefined)
|
||||
// FIXME: We are eluding constness here.
|
||||
const_cast<IteratorsChecker*>(this)->BT_Undefined =
|
||||
|
@ -472,7 +472,7 @@ void IteratorsChecker::checkPreStmt(const CXXOperatorCallExpr *OCE,
|
|||
if (Kind == OO_Equal) {
|
||||
checkExpr(C, OCE->getArg(1));
|
||||
state = handleAssign(state, OCE->getArg(0), OCE->getArg(1), LC);
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
@ -497,7 +497,7 @@ void IteratorsChecker::checkPreStmt(const CXXOperatorCallExpr *OCE,
|
|||
if (!RS1)
|
||||
return;
|
||||
if (RS0->getMemRegion() != RS1->getMemRegion()) {
|
||||
if (ExplodedNode *N = C.generateNode()) {
|
||||
if (ExplodedNode *N = C.addTransition()) {
|
||||
if (!BT_Incompatible)
|
||||
const_cast<IteratorsChecker*>(this)->BT_Incompatible =
|
||||
new BuiltinBug(
|
||||
|
@ -550,7 +550,7 @@ void IteratorsChecker::checkPreStmt(const DeclStmt *DS,
|
|||
}
|
||||
}
|
||||
}
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
|
||||
|
@ -600,6 +600,6 @@ void IteratorsChecker::checkPreStmt(const CXXMemberCallExpr *MCE,
|
|||
state = state->add<CalledReserved>(MR);
|
||||
|
||||
if (state != C.getState())
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ void MacOSKeychainAPIChecker::
|
|||
CheckerContext &C) const {
|
||||
const ProgramState *State = C.getState();
|
||||
State = State->remove<AllocatedData>(AP.first);
|
||||
ExplodedNode *N = C.generateNode(State);
|
||||
ExplodedNode *N = C.addTransition(State);
|
||||
|
||||
if (!N)
|
||||
return;
|
||||
|
@ -304,7 +304,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
|
|||
// Remove the value from the state. The new symbol will be added for
|
||||
// tracking when the second allocator is processed in checkPostStmt().
|
||||
State = State->remove<AllocatedData>(V);
|
||||
ExplodedNode *N = C.generateNode(State);
|
||||
ExplodedNode *N = C.addTransition(State);
|
||||
if (!N)
|
||||
return;
|
||||
initBugType();
|
||||
|
@ -362,7 +362,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
|
|||
if (isEnclosingFunctionParam(ArgExpr))
|
||||
return;
|
||||
|
||||
ExplodedNode *N = C.generateNode(State);
|
||||
ExplodedNode *N = C.addTransition(State);
|
||||
if (!N)
|
||||
return;
|
||||
initBugType();
|
||||
|
@ -400,7 +400,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
|
|||
// custom deallocator which does the right thing.
|
||||
if (DE->getFoundDecl()->getName() != "kCFAllocatorNull") {
|
||||
State = State->remove<AllocatedData>(ArgSM);
|
||||
C.generateNode(State);
|
||||
C.addTransition(State);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -422,7 +422,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
|
|||
|
||||
// If the return status is undefined or is error, report a bad call to free.
|
||||
if (!definitelyDidnotReturnError(AS->Region, State, C.getSValBuilder())) {
|
||||
ExplodedNode *N = C.generateNode(State);
|
||||
ExplodedNode *N = C.addTransition(State);
|
||||
if (!N)
|
||||
return;
|
||||
initBugType();
|
||||
|
@ -434,7 +434,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
|
|||
return;
|
||||
}
|
||||
|
||||
C.generateNode(State);
|
||||
C.addTransition(State);
|
||||
}
|
||||
|
||||
void MacOSKeychainAPIChecker::checkPostStmt(const CallExpr *CE,
|
||||
|
@ -482,7 +482,7 @@ void MacOSKeychainAPIChecker::checkPostStmt(const CallExpr *CE,
|
|||
State = State->set<AllocatedData>(V, AllocationState(ArgExpr, idx,
|
||||
RetStatusSymbol));
|
||||
assert(State);
|
||||
C.generateNode(State);
|
||||
C.addTransition(State);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -500,7 +500,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const ReturnStmt *S,
|
|||
state = state->remove<AllocatedData>(getSymbolForRegion(C, V));
|
||||
|
||||
// Proceed from the new state.
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
BugReport *MacOSKeychainAPIChecker::
|
||||
|
@ -545,7 +545,7 @@ void MacOSKeychainAPIChecker::checkDeadSymbols(SymbolReaper &SR,
|
|||
return;
|
||||
|
||||
// Generate the new, cleaned up state.
|
||||
ExplodedNode *N = C.generateNode(State);
|
||||
ExplodedNode *N = C.addTransition(State);
|
||||
if (!N)
|
||||
return;
|
||||
|
||||
|
@ -584,7 +584,7 @@ void MacOSKeychainAPIChecker::checkEndPath(CheckerContext &Ctx) const {
|
|||
if (!Changed)
|
||||
return;
|
||||
|
||||
ExplodedNode *N = Ctx.generateNode(state);
|
||||
ExplodedNode *N = Ctx.addTransition(state);
|
||||
if (!N)
|
||||
return;
|
||||
|
||||
|
|
|
@ -197,7 +197,7 @@ bool MallocChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
|
|||
void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
|
||||
const ProgramState *state = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(),
|
||||
C.getState());
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
|
||||
|
@ -209,12 +209,12 @@ void MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
|
|||
if (I != E) {
|
||||
const ProgramState *state =
|
||||
MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
return;
|
||||
}
|
||||
const ProgramState *state = MallocMemAux(C, CE, UnknownVal(), UndefinedVal(),
|
||||
C.getState());
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
const ProgramState *MallocChecker::MallocMemAux(CheckerContext &C,
|
||||
|
@ -252,7 +252,7 @@ void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) const {
|
|||
const ProgramState *state = FreeMemAux(C, CE, C.getState(), 0, false);
|
||||
|
||||
if (state)
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE,
|
||||
|
@ -265,7 +265,7 @@ void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE,
|
|||
const ProgramState *state = FreeMemAux(C, CE, C.getState(), *I,
|
||||
Att->getOwnKind() == OwnershipAttr::Holds);
|
||||
if (state)
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,7 +531,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
|
|||
|
||||
const ProgramState *stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
|
||||
UndefinedVal(), stateEqual);
|
||||
C.generateNode(stateMalloc);
|
||||
C.addTransition(stateMalloc);
|
||||
}
|
||||
|
||||
if (const ProgramState *stateNotEqual = state->assume(PtrEQ, false)) {
|
||||
|
@ -541,7 +541,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
|
|||
FreeMemAux(C, CE, stateSizeZero, 0, false)) {
|
||||
|
||||
// Bind the return value to NULL because it is now free.
|
||||
C.generateNode(stateFree->BindExpr(CE, svalBuilder.makeNull(), true));
|
||||
C.addTransition(stateFree->BindExpr(CE, svalBuilder.makeNull(), true));
|
||||
}
|
||||
if (const ProgramState *stateSizeNotZero = stateNotEqual->assume(SizeZero,false))
|
||||
if (const ProgramState *stateFree = FreeMemAux(C, CE, stateSizeNotZero,
|
||||
|
@ -549,7 +549,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
|
|||
// FIXME: We should copy the content of the original buffer.
|
||||
const ProgramState *stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
|
||||
UnknownVal(), stateFree);
|
||||
C.generateNode(stateRealloc);
|
||||
C.addTransition(stateRealloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -564,7 +564,7 @@ void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
|
|||
svalBuilder.getContext().getSizeType());
|
||||
SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
|
||||
|
||||
C.generateNode(MallocMemAux(C, CE, TotalSize, zeroVal, state));
|
||||
C.addTransition(MallocMemAux(C, CE, TotalSize, zeroVal, state));
|
||||
}
|
||||
|
||||
void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
||||
|
@ -590,7 +590,7 @@ void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
|||
}
|
||||
}
|
||||
|
||||
ExplodedNode *N = C.generateNode(state->set<RegionState>(RS));
|
||||
ExplodedNode *N = C.addTransition(state->set<RegionState>(RS));
|
||||
|
||||
// FIXME: This does not handle when we have multiple leaks at a single
|
||||
// place.
|
||||
|
@ -611,7 +611,7 @@ void MallocChecker::checkEndPath(CheckerContext &Ctx) const {
|
|||
for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) {
|
||||
RefState RS = I->second;
|
||||
if (RS.isAllocated()) {
|
||||
ExplodedNode *N = Ctx.generateNode(state);
|
||||
ExplodedNode *N = Ctx.addTransition(state);
|
||||
if (N) {
|
||||
if (!BT_Leak)
|
||||
BT_Leak.reset(new BuiltinBug("Memory leak",
|
||||
|
@ -642,7 +642,7 @@ void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
|
|||
if (RS->isAllocated())
|
||||
state = state->set<RegionState>(Sym, RefState::getEscaped(S));
|
||||
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
const ProgramState *MallocChecker::evalAssume(const ProgramState *state, SVal Cond,
|
||||
|
@ -668,7 +668,7 @@ void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
|
|||
if (Sym) {
|
||||
const RefState *RS = C.getState()->get<RegionState>(Sym);
|
||||
if (RS && RS->isReleased()) {
|
||||
if (ExplodedNode *N = C.generateNode()) {
|
||||
if (ExplodedNode *N = C.addTransition()) {
|
||||
if (!BT_UseFree)
|
||||
BT_UseFree.reset(new BuiltinBug("Use dynamically allocated memory "
|
||||
"after it is freed."));
|
||||
|
@ -707,7 +707,7 @@ void MallocChecker::checkBind(SVal location, SVal val,
|
|||
// Generate a transition for 'nullState' to record the assumption
|
||||
// that the state was null.
|
||||
if (nullState)
|
||||
C.generateNode(nullState);
|
||||
C.addTransition(nullState);
|
||||
|
||||
if (!notNullState)
|
||||
return;
|
||||
|
@ -735,7 +735,7 @@ void MallocChecker::checkBind(SVal location, SVal val,
|
|||
}
|
||||
while (false);
|
||||
}
|
||||
C.generateNode(notNullState);
|
||||
C.addTransition(notNullState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ template <typename T>
|
|||
static void setFlag(const ProgramState *state, SVal val, CheckerContext &C) {
|
||||
// We tag the symbol that the SVal wraps.
|
||||
if (SymbolRef sym = val.getAsSymbol())
|
||||
C.generateNode(state->set<T>(sym, true));
|
||||
C.addTransition(state->set<T>(sym, true));
|
||||
}
|
||||
|
||||
static QualType parameterTypeFromSVal(SVal val, CheckerContext &C) {
|
||||
|
|
|
@ -66,7 +66,7 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
|
|||
if (!notNullState) {
|
||||
// Generate an error node. This isn't a sink since
|
||||
// a null mutex just means no synchronization occurs.
|
||||
if (ExplodedNode *N = C.generateNode(nullState)) {
|
||||
if (ExplodedNode *N = C.addTransition(nullState)) {
|
||||
if (!BT_null)
|
||||
BT_null.reset(new BuiltinBug("Nil value used as mutex for @synchronized() "
|
||||
"(no synchronization will occur)"));
|
||||
|
@ -84,7 +84,7 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
|
|||
}
|
||||
|
||||
if (notNullState)
|
||||
C.generateNode(notNullState);
|
||||
C.addTransition(notNullState);
|
||||
}
|
||||
|
||||
void ento::registerObjCAtSyncChecker(CheckerManager &mgr) {
|
||||
|
|
|
@ -145,7 +145,7 @@ static void addSelfFlag(const ProgramState *state, SVal val,
|
|||
SelfFlagEnum flag, CheckerContext &C) {
|
||||
// We tag the symbol that the SVal wraps.
|
||||
if (SymbolRef sym = val.getAsSymbol())
|
||||
C.generateNode(state->set<SelfFlag>(sym, getSelfFlags(val, C) | flag));
|
||||
C.addTransition(state->set<SelfFlag>(sym, getSelfFlags(val, C) | flag));
|
||||
}
|
||||
|
||||
static bool hasSelfFlag(SVal val, SelfFlagEnum flag, CheckerContext &C) {
|
||||
|
@ -265,11 +265,11 @@ void ObjCSelfInitChecker::checkPreStmt(const CallExpr *CE,
|
|||
SVal argV = state->getSVal(*I);
|
||||
if (isSelfVar(argV, C)) {
|
||||
unsigned selfFlags = getSelfFlags(state->getSVal(cast<Loc>(argV)), C);
|
||||
C.generateNode(state->set<PreCallSelfFlags>(selfFlags));
|
||||
C.addTransition(state->set<PreCallSelfFlags>(selfFlags));
|
||||
return;
|
||||
} else if (hasSelfFlag(argV, SelfFlag_Self, C)) {
|
||||
unsigned selfFlags = getSelfFlags(argV, C);
|
||||
C.generateNode(state->set<PreCallSelfFlags>(selfFlags));
|
||||
C.addTransition(state->set<PreCallSelfFlags>(selfFlags));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ void PointerArithChecker::checkPreStmt(const BinaryOperator *B,
|
|||
if (isa<VarRegion>(LR) || isa<CodeTextRegion>(LR) ||
|
||||
isa<CompoundLiteralRegion>(LR)) {
|
||||
|
||||
if (ExplodedNode *N = C.generateNode()) {
|
||||
if (ExplodedNode *N = C.addTransition()) {
|
||||
if (!BT)
|
||||
BT.reset(new BuiltinBug("Dangerous pointer arithmetic",
|
||||
"Pointer arithmetic done on non-array variables "
|
||||
|
|
|
@ -59,7 +59,7 @@ void PointerSubChecker::checkPreStmt(const BinaryOperator *B,
|
|||
if (isa<SymbolicRegion>(BaseLR) || isa<SymbolicRegion>(BaseRR))
|
||||
return;
|
||||
|
||||
if (ExplodedNode *N = C.generateNode()) {
|
||||
if (ExplodedNode *N = C.addTransition()) {
|
||||
if (!BT)
|
||||
BT.reset(new BuiltinBug("Pointer subtraction",
|
||||
"Subtraction of two pointers that do not point to "
|
||||
|
|
|
@ -141,7 +141,7 @@ void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
|
|||
break;
|
||||
}
|
||||
assert(lockFail && lockSucc);
|
||||
C.generateNode(lockFail);
|
||||
C.addTransition(lockFail);
|
||||
|
||||
} else if (semantics == PthreadSemantics) {
|
||||
// Assume that the return value was 0.
|
||||
|
@ -156,7 +156,7 @@ void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
|
|||
|
||||
// Record that the lock was acquired.
|
||||
lockSucc = lockSucc->add<LockSet>(lockR);
|
||||
C.generateNode(lockSucc);
|
||||
C.addTransition(lockSucc);
|
||||
}
|
||||
|
||||
void PthreadLockChecker::ReleaseLock(CheckerContext &C, const CallExpr *CE,
|
||||
|
@ -193,7 +193,7 @@ void PthreadLockChecker::ReleaseLock(CheckerContext &C, const CallExpr *CE,
|
|||
|
||||
// Record that the lock was released.
|
||||
state = state->set<LockSet>(LS.getTail());
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
ExplodedNode *MakeNode(const ProgramState *state, ExplodedNode *Pred,
|
||||
bool MarkAsSink = false) {
|
||||
return C->generateNode(state, Pred, tag, MarkAsSink);
|
||||
return C->addTransition(state, Pred, tag, MarkAsSink);
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
@ -2515,7 +2515,7 @@ void RetainCountChecker::checkPostStmt(const BlockExpr *BE,
|
|||
state =
|
||||
state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
|
||||
Regions.data() + Regions.size()).getState();
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void RetainCountChecker::checkPostStmt(const CastExpr *CE,
|
||||
|
@ -2555,7 +2555,7 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE,
|
|||
return;
|
||||
}
|
||||
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void RetainCountChecker::checkPostStmt(const CallExpr *CE,
|
||||
|
@ -2768,7 +2768,7 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
|
|||
if (state == C.getState()) {
|
||||
NewNode = C.getPredecessor();
|
||||
} else {
|
||||
NewNode = C.generateNode(state);
|
||||
NewNode = C.addTransition(state);
|
||||
}
|
||||
|
||||
// Annotate the node with summary we used.
|
||||
|
@ -3045,7 +3045,7 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
|
|||
state = state->set<RefBindings>(Sym, *Binding);
|
||||
}
|
||||
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3099,7 +3099,7 @@ void RetainCountChecker::checkPreStmt(const ReturnStmt *S,
|
|||
|
||||
// Update the binding.
|
||||
state = state->set<RefBindings>(Sym, X);
|
||||
ExplodedNode *Pred = C.generateNode(state);
|
||||
ExplodedNode *Pred = C.addTransition(state);
|
||||
|
||||
// At this point we have updated the state properly.
|
||||
// Everything after this is merely checking to see if the return value has
|
||||
|
@ -3177,7 +3177,7 @@ void RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
|
|||
|
||||
static SimpleProgramPointTag
|
||||
ReturnOwnLeakTag("RetainCountChecker : ReturnsOwnLeak");
|
||||
ExplodedNode *N = C.generateNode(state, Pred, &ReturnOwnLeakTag);
|
||||
ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
|
||||
if (N) {
|
||||
const LangOptions &LOpts = C.getASTContext().getLangOptions();
|
||||
bool GCEnabled = C.isObjCGCEnabled();
|
||||
|
@ -3197,7 +3197,7 @@ void RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
|
|||
|
||||
static SimpleProgramPointTag
|
||||
ReturnNotOwnedTag("RetainCountChecker : ReturnNotOwnedForOwned");
|
||||
ExplodedNode *N = C.generateNode(state, Pred, &ReturnNotOwnedTag);
|
||||
ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
|
||||
if (N) {
|
||||
if (!returnNotOwnedForOwned)
|
||||
returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned());
|
||||
|
@ -3249,7 +3249,7 @@ void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
|
|||
// Otherwise, find all symbols referenced by 'val' that we are tracking
|
||||
// and stop tracking them.
|
||||
state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
const ProgramState *RetainCountChecker::evalAssume(const ProgramState *state,
|
||||
|
@ -3509,7 +3509,7 @@ void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
|||
B = F.remove(B, *I);
|
||||
|
||||
state = state->set<RefBindings>(B);
|
||||
C.generateNode(state, Pred);
|
||||
C.addTransition(state, Pred);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -188,7 +188,7 @@ void StackAddrEscapeChecker::checkEndPath(CheckerContext &Ctx) const {
|
|||
return;
|
||||
|
||||
// Generate an error node.
|
||||
ExplodedNode *N = Ctx.generateNode(state);
|
||||
ExplodedNode *N = Ctx.addTransition(state);
|
||||
if (!N)
|
||||
return;
|
||||
|
||||
|
|
|
@ -241,15 +241,15 @@ void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const {
|
|||
stateNull =
|
||||
stateNull->set<StreamState>(Sym, StreamState::getOpenFailed(CE));
|
||||
|
||||
C.generateNode(stateNotNull);
|
||||
C.generateNode(stateNull);
|
||||
C.addTransition(stateNotNull);
|
||||
C.addTransition(stateNull);
|
||||
}
|
||||
}
|
||||
|
||||
void StreamChecker::Fclose(CheckerContext &C, const CallExpr *CE) const {
|
||||
const ProgramState *state = CheckDoubleClose(CE, C.getState(), C);
|
||||
if (state)
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void StreamChecker::Fread(CheckerContext &C, const CallExpr *CE) const {
|
||||
|
@ -279,7 +279,7 @@ void StreamChecker::Fseek(CheckerContext &C, const CallExpr *CE) const {
|
|||
if (x >= 0 && x <= 2)
|
||||
return;
|
||||
|
||||
if (ExplodedNode *N = C.generateNode(state)) {
|
||||
if (ExplodedNode *N = C.addTransition(state)) {
|
||||
if (!BT_illegalwhence)
|
||||
BT_illegalwhence.reset(new BuiltinBug("Illegal whence argument",
|
||||
"The whence argument to fseek() should be "
|
||||
|
@ -426,7 +426,7 @@ void StreamChecker::checkEndPath(CheckerContext &Ctx) const {
|
|||
for (SymMap::iterator I = M.begin(), E = M.end(); I != E; ++I) {
|
||||
StreamState SS = I->second;
|
||||
if (SS.isOpened()) {
|
||||
ExplodedNode *N = Ctx.generateNode(state);
|
||||
ExplodedNode *N = Ctx.addTransition(state);
|
||||
if (N) {
|
||||
if (!BT_ResourceLeak)
|
||||
BT_ResourceLeak.reset(new BuiltinBug("Resource Leak",
|
||||
|
@ -457,7 +457,7 @@ void StreamChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
|
|||
if (SS->isOpened())
|
||||
state = state->set<StreamState>(Sym, StreamState::getEscaped(S));
|
||||
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void ento::registerStreamChecker(CheckerManager &mgr) {
|
||||
|
|
|
@ -215,7 +215,7 @@ void UnixAPIChecker::CheckMallocZero(CheckerContext &C,
|
|||
// Assume the the value is non-zero going forward.
|
||||
assert(trueState);
|
||||
if (trueState != state) {
|
||||
C.generateNode(trueState);
|
||||
C.addTransition(trueState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
|
|||
assert(state);
|
||||
|
||||
// Remember our assumptions!
|
||||
C.generateNode(state);
|
||||
C.addTransition(state);
|
||||
}
|
||||
|
||||
void ento::registerVLASizeChecker(CheckerManager &mgr) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче