本文整理汇总了C++中CheckerContext::getConstraintManager方法的典型用法代码示例。如果您正苦于以下问题:C++ CheckerContext::getConstraintManager方法的具体用法?C++ CheckerContext::getConstraintManager怎么用?C++ CheckerContext::getConstraintManager使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CheckerContext
的用法示例。
在下文中一共展示了CheckerContext::getConstraintManager方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: PreVisitBinaryOperator
void DivZeroChecker::PreVisitBinaryOperator(CheckerContext &C,
const BinaryOperator *B) {
BinaryOperator::Opcode Op = B->getOpcode();
if (Op != BO_Div &&
Op != BO_Rem &&
Op != BO_DivAssign &&
Op != BO_RemAssign)
return;
if (!B->getRHS()->getType()->isIntegerType() ||
!B->getRHS()->getType()->isScalarType())
return;
SVal Denom = C.getState()->getSVal(B->getRHS());
const DefinedSVal *DV = dyn_cast<DefinedSVal>(&Denom);
// Divide-by-undefined handled in the generic checking for uses of
// undefined values.
if (!DV)
return;
// Check for divide by zero.
ConstraintManager &CM = C.getConstraintManager();
const GRState *stateNotZero, *stateZero;
llvm::tie(stateNotZero, stateZero) = CM.AssumeDual(C.getState(), *DV);
if (stateZero && !stateNotZero) {
if (ExplodedNode *N = C.GenerateSink(stateZero)) {
if (!BT)
BT = new BuiltinBug("Division by zero");
EnhancedBugReport *R =
new EnhancedBugReport(*BT, BT->getDescription(), N);
R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
bugreporter::GetDenomExpr(N));
C.EmitReport(R);
}
return;
}
// If we get here, then the denom should not be zero. We abandon the implicit
// zero denom case for now.
C.addTransition(stateNotZero);
}
示例2: assumeValuesEqual
/// Constrain the passed-in state to assume two values are equal.
ProgramStateRef GTestChecker::assumeValuesEqual(SVal Val1, SVal Val2,
ProgramStateRef State,
CheckerContext &C) {
if (!Val1.getAs<DefinedOrUnknownSVal>() ||
!Val2.getAs<DefinedOrUnknownSVal>())
return State;
auto ValuesEqual =
C.getSValBuilder().evalEQ(State, Val1.castAs<DefinedOrUnknownSVal>(),
Val2.castAs<DefinedOrUnknownSVal>());
if (!ValuesEqual.getAs<DefinedSVal>())
return State;
State = C.getConstraintManager().assume(
State, ValuesEqual.castAs<DefinedSVal>(), true);
return State;
}
示例3: checkPreStmt
void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
CheckerContext &C) const {
BinaryOperator::Opcode Op = B->getOpcode();
if (Op != BO_Div &&
Op != BO_Rem &&
Op != BO_DivAssign &&
Op != BO_RemAssign)
return;
if (!B->getRHS()->getType()->isScalarType())
return;
SVal Denom = C.getSVal(B->getRHS());
Optional<DefinedSVal> DV = Denom.getAs<DefinedSVal>();
// Divide-by-undefined handled in the generic checking for uses of
// undefined values.
if (!DV)
return;
// Check for divide by zero.
ConstraintManager &CM = C.getConstraintManager();
ProgramStateRef stateNotZero, stateZero;
std::tie(stateNotZero, stateZero) = CM.assumeDual(C.getState(), *DV);
if (!stateNotZero) {
assert(stateZero);
reportBug("Division by zero", stateZero, C);
return;
}
bool TaintedD = C.getState()->isTainted(*DV);
if ((stateNotZero && stateZero && TaintedD)) {
reportBug("Division by a tainted value, possibly zero", stateZero, C,
llvm::make_unique<TaintBugVisitor>(*DV));
return;
}
// If we get here, then the denom should not be zero. We abandon the implicit
// zero denom case for now.
C.addTransition(stateNotZero);
}
示例4: CheckNullStream
ProgramStateRef StreamChecker::CheckNullStream(SVal SV, ProgramStateRef state,
CheckerContext &C) const {
Optional<DefinedSVal> DV = SV.getAs<DefinedSVal>();
if (!DV)
return nullptr;
ConstraintManager &CM = C.getConstraintManager();
ProgramStateRef stateNotNull, stateNull;
std::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
if (!stateNotNull && stateNull) {
if (ExplodedNode *N = C.generateErrorNode(stateNull)) {
if (!BT_nullfp)
BT_nullfp.reset(new BuiltinBug(this, "NULL stream pointer",
"Stream pointer might be NULL."));
C.emitReport(llvm::make_unique<BugReport>(
*BT_nullfp, BT_nullfp->getDescription(), N));
}
return nullptr;
}
return stateNotNull;
}
示例5: CheckNullStream
ProgramStateRef StreamChecker::CheckNullStream(SVal SV, ProgramStateRef state,
CheckerContext &C) const {
const DefinedSVal *DV = dyn_cast<DefinedSVal>(&SV);
if (!DV)
return 0;
ConstraintManager &CM = C.getConstraintManager();
ProgramStateRef stateNotNull, stateNull;
llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
if (!stateNotNull && stateNull) {
if (ExplodedNode *N = C.generateSink(stateNull)) {
if (!BT_nullfp)
BT_nullfp.reset(new BuiltinBug("NULL stream pointer",
"Stream pointer might be NULL."));
BugReport *R =new BugReport(*BT_nullfp, BT_nullfp->getDescription(), N);
C.emitReport(R);
}
return 0;
}
return stateNotNull;
}
示例6: checkPreCall
void NonNullParamChecker::checkPreCall(const CallEvent &Call,
CheckerContext &C) const {
const Decl *FD = Call.getDecl();
if (!FD)
return;
const NonNullAttr *Att = FD->getAttr<NonNullAttr>();
ProgramStateRef state = C.getState();
CallEvent::param_type_iterator TyI = Call.param_type_begin(),
TyE = Call.param_type_end();
for (unsigned idx = 0, count = Call.getNumArgs(); idx != count; ++idx){
// Check if the parameter is a reference. We want to report when reference
// to a null pointer is passed as a paramter.
bool haveRefTypeParam = false;
if (TyI != TyE) {
haveRefTypeParam = (*TyI)->isReferenceType();
TyI++;
}
bool haveAttrNonNull = Att && Att->isNonNull(idx);
if (!haveAttrNonNull) {
// Check if the parameter is also marked 'nonnull'.
ArrayRef<ParmVarDecl*> parms = Call.parameters();
if (idx < parms.size())
haveAttrNonNull = parms[idx]->hasAttr<NonNullAttr>();
}
if (!haveRefTypeParam && !haveAttrNonNull)
continue;
// If the value is unknown or undefined, we can't perform this check.
const Expr *ArgE = Call.getArgExpr(idx);
SVal V = Call.getArgSVal(idx);
Optional<DefinedSVal> DV = V.getAs<DefinedSVal>();
if (!DV)
continue;
// Process the case when the argument is not a location.
assert(!haveRefTypeParam || DV->getAs<Loc>());
if (haveAttrNonNull && !DV->getAs<Loc>()) {
// If the argument is a union type, we want to handle a potential
// transparent_union GCC extension.
if (!ArgE)
continue;
QualType T = ArgE->getType();
const RecordType *UT = T->getAsUnionType();
if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
continue;
if (Optional<nonloc::CompoundVal> CSV =
DV->getAs<nonloc::CompoundVal>()) {
nonloc::CompoundVal::iterator CSV_I = CSV->begin();
assert(CSV_I != CSV->end());
V = *CSV_I;
DV = V.getAs<DefinedSVal>();
assert(++CSV_I == CSV->end());
// FIXME: Handle (some_union){ some_other_union_val }, which turns into
// a LazyCompoundVal inside a CompoundVal.
if (!V.getAs<Loc>())
continue;
// Retrieve the corresponding expression.
if (const CompoundLiteralExpr *CE = dyn_cast<CompoundLiteralExpr>(ArgE))
if (const InitListExpr *IE =
dyn_cast<InitListExpr>(CE->getInitializer()))
ArgE = dyn_cast<Expr>(*(IE->begin()));
} else {
// FIXME: Handle LazyCompoundVals?
continue;
}
}
ConstraintManager &CM = C.getConstraintManager();
ProgramStateRef stateNotNull, stateNull;
std::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
if (stateNull && !stateNotNull) {
// Generate an error node. Check for a null node in case
// we cache out.
if (ExplodedNode *errorNode = C.generateSink(stateNull)) {
BugReport *R = 0;
if (haveAttrNonNull)
R = genReportNullAttrNonNull(errorNode, ArgE);
else if (haveRefTypeParam)
R = genReportReferenceToNullPointer(errorNode, ArgE);
// Highlight the range of the argument that was null.
R->addRange(Call.getArgSourceRange(idx));
// Emit the bug report.
C.emitReport(R);
}
//.........这里部分代码省略.........
示例7: checkPreCall
void AttrNonNullChecker::checkPreCall(const CallEvent &Call,
CheckerContext &C) const {
const Decl *FD = Call.getDecl();
if (!FD)
return;
const NonNullAttr *Att = FD->getAttr<NonNullAttr>();
if (!Att)
return;
ProgramStateRef state = C.getState();
// Iterate through the arguments of CE and check them for null.
for (unsigned idx = 0, count = Call.getNumArgs(); idx != count; ++idx) {
if (!Att->isNonNull(idx))
continue;
SVal V = Call.getArgSVal(idx);
DefinedSVal *DV = dyn_cast<DefinedSVal>(&V);
// If the value is unknown or undefined, we can't perform this check.
if (!DV)
continue;
if (!isa<Loc>(*DV)) {
// If the argument is a union type, we want to handle a potential
// transparent_union GCC extension.
const Expr *ArgE = Call.getArgExpr(idx);
if (!ArgE)
continue;
QualType T = ArgE->getType();
const RecordType *UT = T->getAsUnionType();
if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
continue;
if (nonloc::CompoundVal *CSV = dyn_cast<nonloc::CompoundVal>(DV)) {
nonloc::CompoundVal::iterator CSV_I = CSV->begin();
assert(CSV_I != CSV->end());
V = *CSV_I;
DV = dyn_cast<DefinedSVal>(&V);
assert(++CSV_I == CSV->end());
if (!DV)
continue;
} else {
// FIXME: Handle LazyCompoundVals?
continue;
}
}
ConstraintManager &CM = C.getConstraintManager();
ProgramStateRef stateNotNull, stateNull;
llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
if (stateNull && !stateNotNull) {
// Generate an error node. Check for a null node in case
// we cache out.
if (ExplodedNode *errorNode = C.generateSink(stateNull)) {
// Lazily allocate the BugType object if it hasn't already been
// created. Ownership is transferred to the BugReporter object once
// the BugReport is passed to 'EmitWarning'.
if (!BT)
BT.reset(new BugType("Argument with 'nonnull' attribute passed null",
"API"));
BugReport *R =
new BugReport(*BT, "Null pointer passed as an argument to a "
"'nonnull' parameter", errorNode);
// Highlight the range of the argument that was null.
R->addRange(Call.getArgSourceRange(idx));
if (const Expr *ArgE = Call.getArgExpr(idx))
bugreporter::addTrackNullOrUndefValueVisitor(errorNode, ArgE, R);
// Emit the bug report.
C.EmitReport(R);
}
// Always return. Either we cached out or we just emitted an error.
return;
}
// If a pointer value passed the check we should assume that it is
// indeed not null from this point forward.
assert(stateNotNull);
state = stateNotNull;
}
// If we reach here all of the arguments passed the nonnull check.
// If 'state' has been updated generated a new node.
C.addTransition(state);
}
示例8: checkBind
void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
CheckerContext &C) const {
// We are only interested in stores into Booleans.
const TypedValueRegion *TR =
dyn_cast_or_null<TypedValueRegion>(loc.getAsRegion());
if (!TR)
return;
QualType valTy = TR->getValueType();
if (!isBooleanType(valTy))
return;
// Get the value of the right-hand side. We only care about values
// that are defined (UnknownVals and UndefinedVals are handled by other
// checkers).
Optional<DefinedSVal> DV = val.getAs<DefinedSVal>();
if (!DV)
return;
// Check if the assigned value meets our criteria for correctness. It must
// be a value that is either 0 or 1. One way to check this is to see if
// the value is possibly < 0 (for a negative value) or greater than 1.
ProgramStateRef state = C.getState();
SValBuilder &svalBuilder = C.getSValBuilder();
ConstraintManager &CM = C.getConstraintManager();
// First, ensure that the value is >= 0.
DefinedSVal zeroVal = svalBuilder.makeIntVal(0, valTy);
SVal greaterThanOrEqualToZeroVal =
svalBuilder.evalBinOp(state, BO_GE, *DV, zeroVal,
svalBuilder.getConditionType());
Optional<DefinedSVal> greaterThanEqualToZero =
greaterThanOrEqualToZeroVal.getAs<DefinedSVal>();
if (!greaterThanEqualToZero) {
// The SValBuilder cannot construct a valid SVal for this condition.
// This means we cannot properly reason about it.
return;
}
ProgramStateRef stateLT, stateGE;
std::tie(stateGE, stateLT) = CM.assumeDual(state, *greaterThanEqualToZero);
// Is it possible for the value to be less than zero?
if (stateLT) {
// It is possible for the value to be less than zero. We only
// want to emit a warning, however, if that value is fully constrained.
// If it it possible for the value to be >= 0, then essentially the
// value is underconstrained and there is nothing left to be done.
if (!stateGE)
emitReport(stateLT, C);
// In either case, we are done.
return;
}
// If we reach here, it must be the case that the value is constrained
// to only be >= 0.
assert(stateGE == state);
// At this point we know that the value is >= 0.
// Now check to ensure that the value is <= 1.
DefinedSVal OneVal = svalBuilder.makeIntVal(1, valTy);
SVal lessThanEqToOneVal =
svalBuilder.evalBinOp(state, BO_LE, *DV, OneVal,
svalBuilder.getConditionType());
Optional<DefinedSVal> lessThanEqToOne =
lessThanEqToOneVal.getAs<DefinedSVal>();
if (!lessThanEqToOne) {
// The SValBuilder cannot construct a valid SVal for this condition.
// This means we cannot properly reason about it.
return;
}
ProgramStateRef stateGT, stateLE;
std::tie(stateLE, stateGT) = CM.assumeDual(state, *lessThanEqToOne);
// Is it possible for the value to be greater than one?
if (stateGT) {
// It is possible for the value to be greater than one. We only
// want to emit a warning, however, if that value is fully constrained.
// If it is possible for the value to be <= 1, then essentially the
// value is underconstrained and there is nothing left to be done.
if (!stateLE)
emitReport(stateGT, C);
// In either case, we are done.
return;
}
// If we reach here, it must be the case that the value is constrained
// to only be <= 1.
assert(stateLE == state);
}
示例9: PreVisitCallExpr
void AttrNonNullChecker::PreVisitCallExpr(CheckerContext &C,
const CallExpr *CE) {
const GRState *state = C.getState();
const GRState *originalState = state;
// Check if the callee has a 'nonnull' attribute.
SVal X = state->getSVal(CE->getCallee());
const FunctionDecl* FD = X.getAsFunctionDecl();
if (!FD)
return;
const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
if (!Att)
return;
// Iterate through the arguments of CE and check them for null.
unsigned idx = 0;
for (CallExpr::const_arg_iterator I=CE->arg_begin(), E=CE->arg_end(); I!=E;
++I, ++idx) {
if (!Att->isNonNull(idx))
continue;
const SVal &V = state->getSVal(*I);
const DefinedSVal *DV = dyn_cast<DefinedSVal>(&V);
if (!DV)
continue;
ConstraintManager &CM = C.getConstraintManager();
const GRState *stateNotNull, *stateNull;
llvm::tie(stateNotNull, stateNull) = CM.AssumeDual(state, *DV);
if (stateNull && !stateNotNull) {
// Generate an error node. Check for a null node in case
// we cache out.
if (ExplodedNode *errorNode = C.GenerateNode(CE, stateNull, true)) {
// Lazily allocate the BugType object if it hasn't already been
// created. Ownership is transferred to the BugReporter object once
// the BugReport is passed to 'EmitWarning'.
if (!BT)
BT = new BugType("Argument with 'nonnull' attribute passed null",
"API");
EnhancedBugReport *R =
new EnhancedBugReport(*BT,
"Null pointer passed as an argument to a "
"'nonnull' parameter", errorNode);
// Highlight the range of the argument that was null.
const Expr *arg = *I;
R->addRange(arg->getSourceRange());
R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, arg);
// Emit the bug report.
C.EmitReport(R);
}
// Always return. Either we cached out or we just emitted an error.
return;
}
// If a pointer value passed the check we should assume that it is
// indeed not null from this point forward.
assert(stateNotNull);
state = stateNotNull;
}
// If we reach here all of the arguments passed the nonnull check.
// If 'state' has been updated generated a new node.
if (state != originalState)
C.addTransition(C.GenerateNode(CE, state));
}
示例10: checkPreStmt
void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
if (!DS->isSingleDecl())
return;
const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
if (!VD)
return;
ASTContext &Ctx = C.getASTContext();
const VariableArrayType *VLA = Ctx.getAsVariableArrayType(VD->getType());
if (!VLA)
return;
// FIXME: Handle multi-dimensional VLAs.
const Expr *SE = VLA->getSizeExpr();
ProgramStateRef state = C.getState();
SVal sizeV = state->getSVal(SE, C.getLocationContext());
if (sizeV.isUndef()) {
reportBug(VLA_Garbage, SE, state, C);
return;
}
// See if the size value is known. It can't be undefined because we would have
// warned about that already.
if (sizeV.isUnknown())
return;
// Check if the size is tainted.
if (state->isTainted(sizeV)) {
reportBug(VLA_Tainted, SE, nullptr, C);
return;
}
// Check if the size is zero.
DefinedSVal sizeD = sizeV.castAs<DefinedSVal>();
ProgramStateRef stateNotZero, stateZero;
std::tie(stateNotZero, stateZero) = state->assume(sizeD);
if (stateZero && !stateNotZero) {
reportBug(VLA_Zero, SE, stateZero, C);
return;
}
// From this point on, assume that the size is not zero.
state = stateNotZero;
// VLASizeChecker is responsible for defining the extent of the array being
// declared. We do this by multiplying the array length by the element size,
// then matching that with the array region's extent symbol.
// Check if the size is negative.
SValBuilder &svalBuilder = C.getSValBuilder();
QualType Ty = SE->getType();
DefinedOrUnknownSVal Zero = svalBuilder.makeZeroVal(Ty);
SVal LessThanZeroVal = svalBuilder.evalBinOp(state, BO_LT, sizeD, Zero, Ty);
if (Optional<DefinedSVal> LessThanZeroDVal =
LessThanZeroVal.getAs<DefinedSVal>()) {
ConstraintManager &CM = C.getConstraintManager();
ProgramStateRef StatePos, StateNeg;
std::tie(StateNeg, StatePos) = CM.assumeDual(state, *LessThanZeroDVal);
if (StateNeg && !StatePos) {
reportBug(VLA_Negative, SE, state, C);
return;
}
state = StatePos;
}
// Convert the array length to size_t.
QualType SizeTy = Ctx.getSizeType();
NonLoc ArrayLength =
svalBuilder.evalCast(sizeD, SizeTy, SE->getType()).castAs<NonLoc>();
// Get the element size.
CharUnits EleSize = Ctx.getTypeSizeInChars(VLA->getElementType());
SVal EleSizeVal = svalBuilder.makeIntVal(EleSize.getQuantity(), SizeTy);
// Multiply the array length by the element size.
SVal ArraySizeVal = svalBuilder.evalBinOpNN(
state, BO_Mul, ArrayLength, EleSizeVal.castAs<NonLoc>(), SizeTy);
// Finally, assume that the array's extent matches the given size.
const LocationContext *LC = C.getLocationContext();
DefinedOrUnknownSVal Extent =
state->getRegion(VD, LC)->getExtent(svalBuilder);
DefinedOrUnknownSVal ArraySize = ArraySizeVal.castAs<DefinedOrUnknownSVal>();
DefinedOrUnknownSVal sizeIsKnown =
svalBuilder.evalEQ(state, Extent, ArraySize);
state = state->assume(sizeIsKnown, true);
// Assume should not fail at this point.
assert(state);
// Remember our assumptions!
C.addTransition(state);
}
示例11: checkPreCall
void NonNullParamChecker::checkPreCall(const CallEvent &Call,
CheckerContext &C) const {
if (!Call.getDecl())
return;
llvm::SmallBitVector AttrNonNull = getNonNullAttrs(Call);
unsigned NumArgs = Call.getNumArgs();
ProgramStateRef state = C.getState();
ArrayRef<ParmVarDecl*> parms = Call.parameters();
for (unsigned idx = 0; idx < NumArgs; ++idx) {
// For vararg functions, a corresponding parameter decl may not exist.
bool HasParam = idx < parms.size();
// Check if the parameter is a reference. We want to report when reference
// to a null pointer is passed as a parameter.
bool haveRefTypeParam =
HasParam ? parms[idx]->getType()->isReferenceType() : false;
bool haveAttrNonNull = AttrNonNull[idx];
// Check if the parameter is also marked 'nonnull'.
if (!haveAttrNonNull && HasParam)
haveAttrNonNull = parms[idx]->hasAttr<NonNullAttr>();
if (!haveAttrNonNull && !haveRefTypeParam)
continue;
// If the value is unknown or undefined, we can't perform this check.
const Expr *ArgE = Call.getArgExpr(idx);
SVal V = Call.getArgSVal(idx);
auto DV = V.getAs<DefinedSVal>();
if (!DV)
continue;
assert(!haveRefTypeParam || DV->getAs<Loc>());
// Process the case when the argument is not a location.
if (haveAttrNonNull && !DV->getAs<Loc>()) {
// If the argument is a union type, we want to handle a potential
// transparent_union GCC extension.
if (!ArgE)
continue;
QualType T = ArgE->getType();
const RecordType *UT = T->getAsUnionType();
if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
continue;
auto CSV = DV->getAs<nonloc::CompoundVal>();
// FIXME: Handle LazyCompoundVals?
if (!CSV)
continue;
V = *(CSV->begin());
DV = V.getAs<DefinedSVal>();
assert(++CSV->begin() == CSV->end());
// FIXME: Handle (some_union){ some_other_union_val }, which turns into
// a LazyCompoundVal inside a CompoundVal.
if (!V.getAs<Loc>())
continue;
// Retrieve the corresponding expression.
if (const auto *CE = dyn_cast<CompoundLiteralExpr>(ArgE))
if (const auto *IE = dyn_cast<InitListExpr>(CE->getInitializer()))
ArgE = dyn_cast<Expr>(*(IE->begin()));
}
ConstraintManager &CM = C.getConstraintManager();
ProgramStateRef stateNotNull, stateNull;
std::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
// Generate an error node. Check for a null node in case
// we cache out.
if (stateNull && !stateNotNull) {
if (ExplodedNode *errorNode = C.generateErrorNode(stateNull)) {
std::unique_ptr<BugReport> R;
if (haveAttrNonNull)
R = genReportNullAttrNonNull(errorNode, ArgE);
else if (haveRefTypeParam)
R = genReportReferenceToNullPointer(errorNode, ArgE);
// Highlight the range of the argument that was null.
R->addRange(Call.getArgSourceRange(idx));
// Emit the bug report.
C.emitReport(std::move(R));
}
// Always return. Either we cached out or we just emitted an error.
return;
}
if (stateNull) {
if (ExplodedNode *N = C.generateSink(stateNull, C.getPredecessor())) {
ImplicitNullDerefEvent event = {
V, false, N, &C.getBugReporter(),
/*IsDirectDereference=*/haveRefTypeParam};
//.........这里部分代码省略.........