[analyzer] Apply whitespace cleanups by Honggyu Kim.

llvm-svn: 246978
This commit is contained in:
Ted Kremenek 2015-09-08 03:50:52 +00:00
parent 21dfbfb426
commit 3a0678e33c
85 changed files with 983 additions and 985 deletions

View File

@ -101,7 +101,7 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
else if (isa<BlockDecl>(D)) {
output << "block(line:" << Loc.getLine() << ":col:" << Loc.getColumn();
}
NumBlocksUnreachable += unreachable;
NumBlocks += total;
std::string NameOfRootFunction = output.str();

View File

@ -23,7 +23,7 @@ using namespace clang;
using namespace ento;
namespace {
class ArrayBoundChecker :
class ArrayBoundChecker :
public Checker<check::Location> {
mutable std::unique_ptr<BuiltinBug> BT;
@ -55,8 +55,8 @@ void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
ProgramStateRef state = C.getState();
// Get the size of the array.
DefinedOrUnknownSVal NumElements
= C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(),
DefinedOrUnknownSVal NumElements
= C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(),
ER->getValueType());
ProgramStateRef StInBound = state->assumeInBound(Idx, NumElements, true);
@ -65,7 +65,7 @@ void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
ExplodedNode *N = C.generateSink(StOutBound);
if (!N)
return;
if (!BT)
BT.reset(new BuiltinBug(
this, "Out-of-bound array access",
@ -82,7 +82,7 @@ void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
C.emitReport(std::move(report));
return;
}
// Array bound check succeeded. From this point forward the array bound
// should always succeed.
C.addTransition(StInBound);

View File

@ -26,15 +26,15 @@ using namespace clang;
using namespace ento;
namespace {
class ArrayBoundCheckerV2 :
class ArrayBoundCheckerV2 :
public Checker<check::Location> {
mutable std::unique_ptr<BuiltinBug> BT;
enum OOB_Kind { OOB_Precedes, OOB_Excedes, OOB_Tainted };
void reportOOB(CheckerContext &C, ProgramStateRef errorState,
OOB_Kind kind) const;
public:
void checkLocation(SVal l, bool isLoad, const Stmt*S,
CheckerContext &C) const;
@ -55,7 +55,7 @@ public:
NonLoc getByteOffset() const { return byteOffset.castAs<NonLoc>(); }
const SubRegion *getRegion() const { return baseRegion; }
static RegionRawOffsetV2 computeOffset(ProgramStateRef state,
SValBuilder &svalBuilder,
SVal location);
@ -65,12 +65,12 @@ public:
};
}
static SVal computeExtentBegin(SValBuilder &svalBuilder,
static SVal computeExtentBegin(SValBuilder &svalBuilder,
const MemRegion *region) {
while (true)
switch (region->getKind()) {
default:
return svalBuilder.makeZeroArrayIndex();
return svalBuilder.makeZeroArrayIndex();
case MemRegion::SymbolicRegionKind:
// FIXME: improve this later by tracking symbolic lower bounds
// for symbolic regions.
@ -94,22 +94,22 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
// memory access is within the extent of the base region. Since we
// have some flexibility in defining the base region, we can achieve
// various levels of conservatism in our buffer overflow checking.
ProgramStateRef state = checkerContext.getState();
ProgramStateRef state = checkerContext.getState();
ProgramStateRef originalState = state;
SValBuilder &svalBuilder = checkerContext.getSValBuilder();
const RegionRawOffsetV2 &rawOffset =
const RegionRawOffsetV2 &rawOffset =
RegionRawOffsetV2::computeOffset(state, svalBuilder, location);
if (!rawOffset.getRegion())
return;
// CHECK LOWER BOUND: Is byteOffset < extent begin?
// CHECK LOWER BOUND: Is byteOffset < extent begin?
// If so, we are doing a load/store
// before the first valid offset in the memory region.
SVal extentBegin = computeExtentBegin(svalBuilder, rawOffset.getRegion());
if (Optional<NonLoc> NV = extentBegin.getAs<NonLoc>()) {
SVal lowerBound =
svalBuilder.evalBinOpNN(state, BO_LT, rawOffset.getByteOffset(), *NV,
@ -118,7 +118,7 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
Optional<NonLoc> lowerBoundToCheck = lowerBound.getAs<NonLoc>();
if (!lowerBoundToCheck)
return;
ProgramStateRef state_precedesLowerBound, state_withinLowerBound;
std::tie(state_precedesLowerBound, state_withinLowerBound) =
state->assume(*lowerBoundToCheck);
@ -128,12 +128,12 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
reportOOB(checkerContext, state_precedesLowerBound, OOB_Precedes);
return;
}
// Otherwise, assume the constraint of the lower bound.
assert(state_withinLowerBound);
state = state_withinLowerBound;
}
do {
// CHECK UPPER BOUND: Is byteOffset >= extent(baseRegion)? If so,
// we are doing a load/store after the last valid offset.
@ -146,11 +146,11 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
= svalBuilder.evalBinOpNN(state, BO_GE, rawOffset.getByteOffset(),
extentVal.castAs<NonLoc>(),
svalBuilder.getConditionType());
Optional<NonLoc> upperboundToCheck = upperbound.getAs<NonLoc>();
if (!upperboundToCheck)
break;
ProgramStateRef state_exceedsUpperBound, state_withinUpperBound;
std::tie(state_exceedsUpperBound, state_withinUpperBound) =
state->assume(*upperboundToCheck);
@ -161,19 +161,19 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
reportOOB(checkerContext, state_exceedsUpperBound, OOB_Tainted);
return;
}
// If we are constrained enough to definitely exceed the upper bound, report.
if (state_exceedsUpperBound) {
assert(!state_withinUpperBound);
reportOOB(checkerContext, state_exceedsUpperBound, OOB_Excedes);
return;
}
assert(state_withinUpperBound);
state = state_withinUpperBound;
}
while (false);
if (state != originalState)
checkerContext.addTransition(state);
}
@ -181,7 +181,7 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
void ArrayBoundCheckerV2::reportOOB(CheckerContext &checkerContext,
ProgramStateRef errorState,
OOB_Kind kind) const {
ExplodedNode *errorNode = checkerContext.generateSink(errorState);
if (!errorNode)
return;
@ -259,7 +259,7 @@ RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(ProgramStateRef state,
{
const MemRegion *region = location.getAsRegion();
SVal offset = UndefinedVal();
while (region) {
switch (region->getKind()) {
default: {
@ -280,7 +280,7 @@ RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(ProgramStateRef state,
ASTContext &astContext = svalBuilder.getContext();
if (elemType->isIncompleteType())
return RegionRawOffsetV2();
// Update the offset.
offset = addValue(state,
getValue(offset, svalBuilder),

View File

@ -143,7 +143,7 @@ void NilArgChecker::warnIfNilExpr(const Expr *E,
if (ExplodedNode *N = C.generateSink()) {
generateBugReport(N, Msg, E->getSourceRange(), E, C);
}
}
}
@ -156,7 +156,7 @@ void NilArgChecker::warnIfNilArg(CheckerContext &C,
ProgramStateRef State = C.getState();
if (!State->isNull(msg.getArgSVal(Arg)).isConstrainedTrue())
return;
if (ExplodedNode *N = C.generateSink()) {
SmallString<128> sbuf;
llvm::raw_svector_ostream os(sbuf);
@ -193,7 +193,7 @@ void NilArgChecker::warnIfNilArg(CheckerContext &C,
os << "' cannot be nil";
}
}
generateBugReport(N, os.str(), msg.getArgSourceRange(Arg),
msg.getArgExpr(Arg), C);
}
@ -224,7 +224,7 @@ void NilArgChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
static const unsigned InvalidArgIndex = UINT_MAX;
unsigned Arg = InvalidArgIndex;
bool CanBeSubscript = false;
if (Class == FC_NSString) {
Selector S = msg.getSelector();
@ -433,7 +433,7 @@ void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
const FunctionDecl *FD = C.getCalleeDecl(CE);
if (!FD)
return;
ASTContext &Ctx = C.getASTContext();
if (!II)
II = &Ctx.Idents.get("CFNumberCreate");
@ -495,17 +495,17 @@ void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
// FIXME: We can actually create an abstract "CFNumber" object that has
// the bits initialized to the provided values.
//
if (ExplodedNode *N = SourceSize < TargetSize ? C.generateSink()
if (ExplodedNode *N = SourceSize < TargetSize ? C.generateSink()
: C.addTransition()) {
SmallString<128> sbuf;
llvm::raw_svector_ostream os(sbuf);
os << (SourceSize == 8 ? "An " : "A ")
<< SourceSize << " bit integer is used to initialize a CFNumber "
"object that represents "
<< (TargetSize == 8 ? "an " : "a ")
<< TargetSize << " bit integer. ";
if (SourceSize < TargetSize)
os << (TargetSize - SourceSize)
<< " bits of the CFNumber value will be garbage." ;
@ -549,7 +549,7 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
const FunctionDecl *FD = C.getCalleeDecl(CE);
if (!FD)
return;
if (!BT) {
ASTContext &Ctx = C.getASTContext();
Retain = &Ctx.Idents.get("CFRetain");
@ -635,7 +635,7 @@ public:
void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
CheckerContext &C) const {
if (!BT) {
BT.reset(new APIMisuse(
this, "message incorrectly sent to class instead of class instance"));
@ -646,7 +646,7 @@ void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
autoreleaseS = GetNullarySelector("autorelease", Ctx);
drainS = GetNullarySelector("drain", Ctx);
}
if (msg.isInstanceMessage())
return;
const ObjCInterfaceDecl *Class = msg.getReceiverInterface();
@ -655,7 +655,7 @@ void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
Selector S = msg.getSelector();
if (!(S == releaseS || S == retainS || S == autoreleaseS || S == drainS))
return;
if (ExplodedNode *N = C.addTransition()) {
SmallString<200> buf;
llvm::raw_svector_ostream os(buf);
@ -665,7 +665,7 @@ void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
os << "' message should be sent to instances "
"of class '" << Class->getName()
<< "' and not the class directly";
auto report = llvm::make_unique<BugReport>(*BT, os.str(), N);
report->addRange(msg.getSourceRange());
C.emitReport(std::move(report));
@ -699,12 +699,12 @@ public:
bool
VariadicMethodTypeChecker::isVariadicMessage(const ObjCMethodCall &msg) const {
const ObjCMethodDecl *MD = msg.getDecl();
if (!MD || !MD->isVariadic() || isa<ObjCProtocolDecl>(MD->getDeclContext()))
return false;
Selector S = msg.getSelector();
if (msg.isInstanceMessage()) {
// FIXME: Ideally we'd look at the receiver interface here, but that's not
// useful for init, because alloc returns 'id'. In theory, this could lead
@ -751,7 +751,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
ASTContext &Ctx = C.getASTContext();
arrayWithObjectsS = GetUnarySelector("arrayWithObjects", Ctx);
dictionaryWithObjectsAndKeysS =
dictionaryWithObjectsAndKeysS =
GetUnarySelector("dictionaryWithObjectsAndKeys", Ctx);
setWithObjectsS = GetUnarySelector("setWithObjects", Ctx);
orderedSetWithObjectsS = GetUnarySelector("orderedSetWithObjects", Ctx);
@ -789,11 +789,11 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
// Ignore pointer constants.
if (msg.getArgSVal(I).getAs<loc::ConcreteInt>())
continue;
// Ignore pointer types annotated with 'NSObject' attribute.
if (C.getASTContext().isObjCNSObjectType(ArgTy))
continue;
// Ignore CF references, which can be toll-free bridged.
if (coreFoundation::isCFObjectRef(ArgTy))
continue;
@ -861,7 +861,7 @@ static bool isKnownNonNilCollectionType(QualType T) {
const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
if (!PT)
return false;
const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
if (!ID)
return false;
@ -1023,7 +1023,7 @@ void ObjCLoopChecker::checkPostStmt(const ObjCForCollectionStmt *FCS,
State = checkElementNonNil(C, State, FCS);
State = assumeCollectionNonEmpty(C, State, FCS, /*Assumption*/true);
}
if (!State)
C.generateSink();
else if (State != C.getState())
@ -1041,7 +1041,7 @@ bool ObjCLoopChecker::isCollectionCountMethod(const ObjCMethodCall &M,
if (S.isUnarySelector() &&
(S.getIdentifierInfoForSlot(0) == CountSelectorII))
return true;
return false;
}
@ -1069,7 +1069,7 @@ void ObjCLoopChecker::checkPostObjCMessage(const ObjCMethodCall &M,
// a call to "count" and add it to the map.
if (!isCollectionCountMethod(M, C))
return;
const Expr *MsgExpr = M.getOriginExpr();
SymbolRef CountS = C.getSVal(MsgExpr).getAsSymbol();
if (CountS) {

View File

@ -42,45 +42,45 @@ void BoolAssignmentChecker::emitReport(ProgramStateRef state,
static bool isBooleanType(QualType Ty) {
if (Ty->isBooleanType()) // C++ or C99
return true;
if (const TypedefType *TT = Ty->getAs<TypedefType>())
return TT->getDecl()->getName() == "BOOL" || // Objective-C
TT->getDecl()->getName() == "_Bool" || // stdbool.h < C99
TT->getDecl()->getName() == "Boolean"; // MacTypes.h
return false;
}
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();
ProgramStateRef state = C.getState();
SValBuilder &svalBuilder = C.getSValBuilder();
ConstraintManager &CM = C.getConstraintManager();
// First, ensure that the value is >= 0.
// First, ensure that the value is >= 0.
DefinedSVal zeroVal = svalBuilder.makeIntVal(0, valTy);
SVal greaterThanOrEqualToZeroVal =
svalBuilder.evalBinOp(state, BO_GE, *DV, zeroVal,
@ -91,13 +91,13 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
if (!greaterThanEqualToZero) {
// The SValBuilder cannot construct a valid SVal for this condition.
// This means we cannot properly reason about it.
// 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
@ -106,15 +106,15 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
// 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);
@ -127,13 +127,13 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
if (!lessThanEqToOne) {
// The SValBuilder cannot construct a valid SVal for this condition.
// This means we cannot properly reason about it.
// 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
@ -142,11 +142,11 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
// 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);

View File

@ -65,7 +65,7 @@ public:
void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
bool wantsRegionChangeUpdate(ProgramStateRef state) const;
ProgramStateRef
ProgramStateRef
checkRegionChanges(ProgramStateRef state,
const InvalidatedSymbols *,
ArrayRef<const MemRegion *> ExplicitRegions,
@ -92,7 +92,7 @@ public:
void evalstrLength(CheckerContext &C, const CallExpr *CE) const;
void evalstrnLength(CheckerContext &C, const CallExpr *CE) const;
void evalstrLengthCommon(CheckerContext &C,
const CallExpr *CE,
const CallExpr *CE,
bool IsStrnlen = false) const;
void evalStrcpy(CheckerContext &C, const CallExpr *CE) const;
@ -137,9 +137,9 @@ public:
SVal Buf,
bool hypothetical = false) const;
const StringLiteral *getCStringLiteral(CheckerContext &C,
const StringLiteral *getCStringLiteral(CheckerContext &C,
ProgramStateRef &state,
const Expr *expr,
const Expr *expr,
SVal val) const;
static ProgramStateRef InvalidateBuffer(CheckerContext &C,
@ -282,7 +282,7 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
// Get the size of the array.
const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion());
SValBuilder &svalBuilder = C.getSValBuilder();
SVal Extent =
SVal Extent =
svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder));
DefinedOrUnknownSVal Size = Extent.castAs<DefinedOrUnknownSVal>();
@ -327,7 +327,7 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
C.emitReport(std::move(report));
return nullptr;
}
// Array bound check succeeded. From this point forward the array bound
// should always succeed.
return StInBound;
@ -442,7 +442,7 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
return state;
// Are the two values the same?
SValBuilder &svalBuilder = C.getSValBuilder();
SValBuilder &svalBuilder = C.getSValBuilder();
std::tie(stateTrue, stateFalse) =
state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc));
@ -489,7 +489,7 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
// Bail out if the cast fails.
ASTContext &Ctx = svalBuilder.getContext();
QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
SVal FirstStart = svalBuilder.evalCast(*firstLoc, CharPtrTy,
SVal FirstStart = svalBuilder.evalCast(*firstLoc, CharPtrTy,
First->getType());
Optional<Loc> FirstStartLoc = FirstStart.getAs<Loc>();
if (!FirstStartLoc)
@ -568,7 +568,7 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
} else {
// Try switching the operands. (The order of these two assignments is
// important!)
maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, left,
maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, left,
sizeTy);
left = right;
}
@ -723,7 +723,7 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
auto report = llvm::make_unique<BugReport>(*BT_NotCString, os.str(), N);
report->addRange(Ex->getSourceRange());
C.emitReport(std::move(report));
C.emitReport(std::move(report));
}
return UndefinedVal();
@ -787,7 +787,7 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
auto report = llvm::make_unique<BugReport>(*BT_NotCString, os.str(), N);
report->addRange(Ex->getSourceRange());
C.emitReport(std::move(report));
C.emitReport(std::move(report));
}
return UndefinedVal();
@ -843,13 +843,13 @@ ProgramStateRef CStringChecker::InvalidateBuffer(CheckerContext &C,
// Invalidate and escape only indirect regions accessible through the source
// buffer.
if (IsSourceBuffer) {
ITraits.setTrait(R,
ITraits.setTrait(R,
RegionAndSymbolInvalidationTraits::TK_PreserveContents);
ITraits.setTrait(R, RegionAndSymbolInvalidationTraits::TK_SuppressEscape);
CausesPointerEscape = true;
}
return state->invalidateRegions(R, E, C.blockCount(), LCtx,
return state->invalidateRegions(R, E, C.blockCount(), LCtx,
CausesPointerEscape, nullptr, nullptr,
&ITraits);
}
@ -901,7 +901,7 @@ bool CStringChecker::SummarizeRegion(raw_ostream &os, ASTContext &Ctx,
// evaluation of individual function calls.
//===----------------------------------------------------------------------===//
void CStringChecker::evalCopyCommon(CheckerContext &C,
void CStringChecker::evalCopyCommon(CheckerContext &C,
const CallExpr *CE,
ProgramStateRef state,
const Expr *Size, const Expr *Dest,
@ -941,7 +941,7 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
// Get the value of the Src.
SVal srcVal = state->getSVal(Source, LCtx);
// Ensure the source is not null. If it is NULL there will be a
// NULL pointer dereference.
state = checkNonNull(C, state, Source, srcVal);
@ -959,11 +959,11 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
if (!state)
return;
// If this is mempcpy, get the byte after the last byte copied and
// If this is mempcpy, get the byte after the last byte copied and
// bind the expr.
if (IsMempcpy) {
loc::MemRegionVal destRegVal = destVal.castAs<loc::MemRegionVal>();
// Get the length to copy.
if (Optional<NonLoc> lenValNonLoc = sizeVal.getAs<NonLoc>()) {
// Get the byte after the last byte copied.
@ -972,11 +972,11 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
loc::MemRegionVal DestRegCharVal = SvalBuilder.evalCast(destRegVal,
CharPtrTy, Dest->getType()).castAs<loc::MemRegionVal>();
SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add,
SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add,
DestRegCharVal,
*lenValNonLoc,
*lenValNonLoc,
Dest->getType());
// The byte after the last byte copied is the return value.
state = state->BindExpr(CE, LCtx, lastElement);
} else {
@ -999,12 +999,12 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
// can use LazyCompoundVals to copy the source values into the destination.
// 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, C.getSVal(Dest),
state = InvalidateBuffer(C, state, Dest, C.getSVal(Dest),
/*IsSourceBuffer*/false);
// Invalidate the source (const-invalidation without const-pointer-escaping
// the address of the top-level region).
state = InvalidateBuffer(C, state, Source, C.getSVal(Source),
state = InvalidateBuffer(C, state, Source, C.getSVal(Source),
/*IsSourceBuffer*/true);
C.addTransition(state);
@ -1032,7 +1032,7 @@ void CStringChecker::evalMempcpy(CheckerContext &C, const CallExpr *CE) const {
// The return value is a pointer to the byte following the last written byte.
const Expr *Dest = CE->getArg(0);
ProgramStateRef state = C.getState();
evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true, true);
}
@ -1053,7 +1053,7 @@ void CStringChecker::evalBcopy(CheckerContext &C, const CallExpr *CE) const {
return;
// void bcopy(const void *src, void *dst, size_t n);
evalCopyCommon(C, CE, C.getState(),
evalCopyCommon(C, CE, C.getState(),
CE->getArg(2), CE->getArg(1), CE->getArg(0));
}
@ -1244,7 +1244,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
state, BO_LE, resultNL, *strLengthNL, cmpTy)
.castAs<DefinedOrUnknownSVal>(), true);
}
if (maxlenValNL) {
state = state->assume(C.getSValBuilder().evalBinOpNN(
state, BO_LE, resultNL, *maxlenValNL, cmpTy)
@ -1275,8 +1275,8 @@ void CStringChecker::evalStrcpy(CheckerContext &C, const CallExpr *CE) const {
return;
// char *strcpy(char *restrict dst, const char *restrict src);
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
/* isBounded = */ false,
/* isAppending = */ false);
}
@ -1286,8 +1286,8 @@ void CStringChecker::evalStrncpy(CheckerContext &C, const CallExpr *CE) const {
return;
// char *strncpy(char *restrict dst, const char *restrict src, size_t n);
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
/* isBounded = */ true,
/* isAppending = */ false);
}
@ -1297,8 +1297,8 @@ void CStringChecker::evalStpcpy(CheckerContext &C, const CallExpr *CE) const {
return;
// char *stpcpy(char *restrict dst, const char *restrict src);
evalStrcpyCommon(C, CE,
/* returnEnd = */ true,
evalStrcpyCommon(C, CE,
/* returnEnd = */ true,
/* isBounded = */ false,
/* isAppending = */ false);
}
@ -1308,8 +1308,8 @@ void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const {
return;
//char *strcat(char *restrict s1, const char *restrict s2);
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
/* isBounded = */ false,
/* isAppending = */ true);
}
@ -1319,8 +1319,8 @@ void CStringChecker::evalStrncat(CheckerContext &C, const CallExpr *CE) const {
return;
//char *strncat(char *restrict s1, const char *restrict s2, size_t n);
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
/* isBounded = */ true,
/* isAppending = */ true);
}
@ -1515,7 +1515,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
Optional<NonLoc> srcStrLengthNL = amountCopied.getAs<NonLoc>();
Optional<NonLoc> dstStrLengthNL = dstStrLength.getAs<NonLoc>();
// If we know both string lengths, we might know the final string length.
if (srcStrLengthNL && dstStrLengthNL) {
// Make sure the two lengths together don't overflow a size_t.
@ -1523,7 +1523,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
if (!state)
return;
finalStrLength = svalBuilder.evalBinOpNN(state, BO_Add, *srcStrLengthNL,
finalStrLength = svalBuilder.evalBinOpNN(state, BO_Add, *srcStrLengthNL,
*dstStrLengthNL, sizeTy);
}
@ -1586,7 +1586,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
if (Optional<NonLoc> maxLastNL = maxLastElementIndex.getAs<NonLoc>()) {
SVal maxLastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal,
*maxLastNL, ptrTy);
state = CheckLocation(C, state, CE->getArg(2), maxLastElement,
state = CheckLocation(C, state, CE->getArg(2), maxLastElement,
boundWarning);
if (!state)
return;
@ -1667,7 +1667,7 @@ void CStringChecker::evalStrncmp(CheckerContext &C, const CallExpr *CE) const {
evalStrcmpCommon(C, CE, /* isBounded = */ true, /* ignoreCase = */ false);
}
void CStringChecker::evalStrcasecmp(CheckerContext &C,
void CStringChecker::evalStrcasecmp(CheckerContext &C,
const CallExpr *CE) const {
if (CE->getNumArgs() < 2)
return;
@ -1676,7 +1676,7 @@ void CStringChecker::evalStrcasecmp(CheckerContext &C,
evalStrcmpCommon(C, CE, /* isBounded = */ false, /* ignoreCase = */ true);
}
void CStringChecker::evalStrncasecmp(CheckerContext &C,
void CStringChecker::evalStrncasecmp(CheckerContext &C,
const CallExpr *CE) const {
if (CE->getNumArgs() < 3)
return;
@ -1915,7 +1915,7 @@ bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
evalFunction = &CStringChecker::evalBcopy;
else if (C.isCLibraryFunction(FDecl, "bcmp"))
evalFunction = &CStringChecker::evalMemcmp;
// If the callee isn't a string function, let another checker handle it.
if (!evalFunction)
return false;
@ -1975,7 +1975,7 @@ bool CStringChecker::wantsRegionChangeUpdate(ProgramStateRef state) const {
return !Entries.isEmpty();
}
ProgramStateRef
ProgramStateRef
CStringChecker::checkRegionChanges(ProgramStateRef state,
const InvalidatedSymbols *,
ArrayRef<const MemRegion *> ExplicitRegions,

View File

@ -51,7 +51,7 @@ static bool scan_ivar_release(Stmt *S, ObjCIvarDecl *ID,
if (E->getDecl()->getIdentifier() == SelfII)
if (ME->getMethodDecl() == PD->getSetterMethodDecl() &&
ME->getNumArgs() == 1 &&
ME->getArg(0)->isNullPointerConstant(Ctx,
ME->getArg(0)->isNullPointerConstant(Ctx,
Expr::NPC_ValueDependentIsNull))
return true;
@ -61,7 +61,7 @@ static bool scan_ivar_release(Stmt *S, ObjCIvarDecl *ID,
if (ObjCPropertyRefExpr *PRE =
dyn_cast<ObjCPropertyRefExpr>(BO->getLHS()->IgnoreParenCasts()))
if (PRE->isExplicitProperty() && PRE->getExplicitProperty() == PD)
if (BO->getRHS()->isNullPointerConstant(Ctx,
if (BO->getRHS()->isNullPointerConstant(Ctx,
Expr::NPC_ValueDependentIsNull)) {
// This is only a 'release' if the property kind is not
// 'assign'.

View File

@ -115,7 +115,7 @@ void WalkAST::VisitChildren(Stmt *S) {
}
void WalkAST::VisitCallExpr(CallExpr *CE) {
// Get the callee.
// Get the callee.
const FunctionDecl *FD = CE->getDirectCallee();
if (!FD)
@ -307,7 +307,7 @@ void WalkAST::checkLoopConditionForFloat(const ForStmt *FS) {
void WalkAST::checkCall_gets(const CallExpr *CE, const FunctionDecl *FD) {
if (!filter.check_gets)
return;
const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>();
if (!FPT)
return;
@ -434,18 +434,18 @@ void WalkAST::checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD) {
.Case("mkdtemp", std::make_pair(0,-1))
.Case("mkstemps", std::make_pair(0,1))
.Default(std::make_pair(-1, -1));
assert(ArgSuffix.first >= 0 && "Unsupported function");
// Check if the number of arguments is consistent with out expectations.
unsigned numArgs = CE->getNumArgs();
if ((signed) numArgs <= ArgSuffix.first)
return;
const StringLiteral *strArg =
dyn_cast<StringLiteral>(CE->getArg((unsigned)ArgSuffix.first)
->IgnoreParenImpCasts());
// Currently we only handle string literals. It is possible to do better,
// either by looking at references to const variables, or by doing real
// flow analysis.
@ -470,13 +470,13 @@ void WalkAST::checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD) {
suffix = (unsigned) Result.getZExtValue();
n = (n > suffix) ? n - suffix : 0;
}
for (unsigned i = 0; i < n; ++i)
if (str[i] == 'X') ++numX;
if (numX >= 6)
return;
// Issue a warning.
PathDiagnosticLocation CELoc =
PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
@ -502,13 +502,13 @@ void WalkAST::checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD) {
//===----------------------------------------------------------------------===//
// Check: Any use of 'strcpy' is insecure.
//
// CWE-119: Improper Restriction of Operations within
// the Bounds of a Memory Buffer
// CWE-119: Improper Restriction of Operations within
// the Bounds of a Memory Buffer
//===----------------------------------------------------------------------===//
void WalkAST::checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD) {
if (!filter.check_strcpy)
return;
if (!checkCall_strCommon(CE, FD))
return;
@ -529,8 +529,8 @@ void WalkAST::checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD) {
//===----------------------------------------------------------------------===//
// Check: Any use of 'strcat' is insecure.
//
// CWE-119: Improper Restriction of Operations within
// the Bounds of a Memory Buffer
// CWE-119: Improper Restriction of Operations within
// the Bounds of a Memory Buffer
//===----------------------------------------------------------------------===//
void WalkAST::checkCall_strcat(const CallExpr *CE, const FunctionDecl *FD) {
if (!filter.check_strcpy)
@ -684,7 +684,7 @@ void WalkAST::checkCall_vfork(const CallExpr *CE, const FunctionDecl *FD) {
void WalkAST::checkUncheckedReturnValue(CallExpr *CE) {
if (!filter.check_UncheckedReturn)
return;
const FunctionDecl *FD = CE->getDirectCallee();
if (!FD)
return;
@ -749,7 +749,7 @@ namespace {
class SecuritySyntaxChecker : public Checker<check::ASTCodeBody> {
public:
ChecksFilter filter;
void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
BugReporter &BR) const {
WalkAST walker(BR, mgr.getAnalysisDeclContext(D), filter);

View File

@ -55,8 +55,8 @@ void WalkAST::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
QualType T = E->getTypeOfArgument();
if (T->isPointerType()) {
// Many false positives have the form 'sizeof *p'. This is reasonable
// because people know what they are doing when they intentionally
// Many false positives have the form 'sizeof *p'. This is reasonable
// because people know what they are doing when they intentionally
// dereference the pointer.
Expr *ArgEx = E->getArgumentExpr();
if (!isa<DeclRefExpr>(ArgEx->IgnoreParens()))

View File

@ -222,7 +222,7 @@ public:
/// changed, this allows the analyzer core to skip the more expensive
/// #checkRegionChanges when no checkers are tracking any state.
bool wantsRegionChangeUpdate(ProgramStateRef St) const { return true; }
/// \brief Called when the contents of one or more regions change.
///
/// This can occur in many different ways: an explicit bind, a blanket
@ -246,7 +246,7 @@ public:
/// #wantsRegionChangeUpdate returns \c true.
///
/// check::RegionChanges
ProgramStateRef
ProgramStateRef
checkRegionChanges(ProgramStateRef State,
const InvalidatedSymbols *Invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
@ -259,12 +259,12 @@ public:
///
/// This notifies the checkers about pointer escape, which occurs whenever
/// the analyzer cannot track the symbol any more. For example, as a
/// result of assigning a pointer into a global or when it's passed to a
/// result of assigning a pointer into a global or when it's passed to a
/// function call the analyzer cannot model.
///
///
/// \param State The state at the point of escape.
/// \param Escaped The list of escaped symbols.
/// \param Call The corresponding CallEvent, if the symbols escape as
/// \param Call The corresponding CallEvent, if the symbols escape as
/// parameters to the given call.
/// \param Kind How the symbols have escaped.
/// \returns Checkers can modify the state by returning a new state.
@ -285,7 +285,7 @@ public:
PointerEscapeKind Kind) const {
return State;
}
/// check::Event<ImplicitNullDerefEvent>
void checkEvent(ImplicitNullDerefEvent Event) const {}

View File

@ -30,7 +30,7 @@ def DeadCodeAlpha : Package<"deadcode">, InPackage<Alpha>, Hidden;
def Security : Package <"security">;
def InsecureAPI : Package<"insecureAPI">, InPackage<Security>;
def SecurityAlpha : Package<"security">, InPackage<Alpha>, Hidden;
def Taint : Package<"taint">, InPackage<SecurityAlpha>, Hidden;
def Taint : Package<"taint">, InPackage<SecurityAlpha>, Hidden;
def Unix : Package<"unix">;
def UnixAlpha : Package<"unix">, InPackage<Alpha>, Hidden;
@ -192,7 +192,7 @@ def UndefBranchChecker : Checker<"Branch">,
def UndefCapturedBlockVarChecker : Checker<"CapturedBlockVariable">,
HelpText<"Check for blocks that capture uninitialized values">,
DescFile<"UndefCapturedBlockVarChecker.cpp">;
def ReturnUndefChecker : Checker<"UndefReturn">,
HelpText<"Check for uninitialized values being returned to the caller">,
DescFile<"ReturnUndefChecker.cpp">;
@ -206,11 +206,11 @@ def ReturnUndefChecker : Checker<"UndefReturn">,
let ParentPackage = Cplusplus in {
def NewDeleteChecker : Checker<"NewDelete">,
HelpText<"Check for double-free and use-after-free problems. Traces memory managed by new/delete.">,
HelpText<"Check for double-free and use-after-free problems. Traces memory managed by new/delete.">,
DescFile<"MallocChecker.cpp">;
def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">,
HelpText<"Check for memory leaks. Traces memory managed by new/delete.">,
HelpText<"Check for memory leaks. Traces memory managed by new/delete.">,
DescFile<"MallocChecker.cpp">;
} // end: "cplusplus"
@ -218,7 +218,7 @@ def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">,
let ParentPackage = CplusplusAlpha in {
def VirtualCallChecker : Checker<"VirtualCall">,
HelpText<"Check virtual function calls during construction or destruction">,
HelpText<"Check virtual function calls during construction or destruction">,
DescFile<"VirtualCallChecker.cpp">;
} // end: "alpha.cplusplus"
@ -282,7 +282,7 @@ let ParentPackage = SecurityAlpha in {
def ArrayBoundChecker : Checker<"ArrayBound">,
HelpText<"Warn about buffer overflows (older checker)">,
DescFile<"ArrayBoundChecker.cpp">;
DescFile<"ArrayBoundChecker.cpp">;
def ArrayBoundCheckerV2 : Checker<"ArrayBoundV2">,
HelpText<"Warn about buffer overflows (newer checker)">,
@ -323,7 +323,7 @@ def UnixAPIChecker : Checker<"API">,
def MallocChecker: Checker<"Malloc">,
HelpText<"Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().">,
DescFile<"MallocChecker.cpp">;
def MallocSizeofChecker : Checker<"MallocSizeof">,
HelpText<"Check for dubious malloc arguments involving sizeof">,
DescFile<"MallocSizeofChecker.cpp">;
@ -331,7 +331,7 @@ def MallocSizeofChecker : Checker<"MallocSizeof">,
def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">,
HelpText<"Check for mismatched deallocators.">,
DescFile<"MallocChecker.cpp">;
} // end "unix"
let ParentPackage = UnixAlpha in {
@ -362,7 +362,7 @@ def CStringNullArg : Checker<"NullArg">,
def CStringSyntaxChecker : Checker<"BadSizeArg">,
HelpText<"Check the size argument passed into C string functions for common erroneous patterns">,
DescFile<"CStringSyntaxChecker.cpp">;
DescFile<"CStringSyntaxChecker.cpp">;
}
let ParentPackage = CStringAlpha in {
@ -514,7 +514,7 @@ def ObjCContainersASTChecker : Checker<"PointerSizedValues">,
def ObjCContainersChecker : Checker<"OutOfBounds">,
HelpText<"Checks for index out-of-bounds when using 'CFArray' API">,
DescFile<"ObjCContainersChecker.cpp">;
}
//===----------------------------------------------------------------------===//
// Checkers for LLVM development.

View File

@ -27,7 +27,7 @@ namespace {
// enum value that represent the jail state
enum Kind { NO_CHROOT, ROOT_CHANGED, JAIL_ENTERED };
bool isRootChanged(intptr_t k) { return k == ROOT_CHANGED; }
//bool isJailEntered(intptr_t k) { return k == JAIL_ENTERED; }
@ -50,7 +50,7 @@ public:
static int x;
return &x;
}
bool evalCall(const CallExpr *CE, CheckerContext &C) const;
void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
@ -87,8 +87,8 @@ bool ChrootChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
void ChrootChecker::Chroot(CheckerContext &C, const CallExpr *CE) const {
ProgramStateRef state = C.getState();
ProgramStateManager &Mgr = state->getStateManager();
// Once encouter a chroot(), set the enum value ROOT_CHANGED directly in
// Once encouter a chroot(), set the enum value ROOT_CHANGED directly in
// the GDM.
state = Mgr.addGDM(state, ChrootChecker::getTag(), (void*) ROOT_CHANGED);
C.addTransition(state);
@ -106,7 +106,7 @@ void ChrootChecker::Chdir(CheckerContext &C, const CallExpr *CE) const {
// After chdir("/"), enter the jail, set the enum value JAIL_ENTERED.
const Expr *ArgExpr = CE->getArg(0);
SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext());
if (const MemRegion *R = ArgVal.getAsRegion()) {
R = R->StripCasts();
if (const StringRegion* StrRegion= dyn_cast<StringRegion>(R)) {
@ -135,7 +135,7 @@ void ChrootChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
// Ingnore chroot and chdir.
if (FD->getIdentifier() == II_chroot || FD->getIdentifier() == II_chdir)
return;
// If jail state is ROOT_CHANGED, generate BugReport.
void *const* k = C.getState()->FindGDM(ChrootChecker::getTag());
if (k)

View File

@ -28,36 +28,36 @@
using namespace clang;
using namespace ento;
namespace {
namespace {
/// A simple visitor to record what VarDecls occur in EH-handling code.
class EHCodeVisitor : public RecursiveASTVisitor<EHCodeVisitor> {
public:
bool inEH;
llvm::DenseSet<const VarDecl *> &S;
bool TraverseObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
SaveAndRestore<bool> inFinally(inEH, true);
return ::RecursiveASTVisitor<EHCodeVisitor>::TraverseObjCAtFinallyStmt(S);
}
bool TraverseObjCAtCatchStmt(ObjCAtCatchStmt *S) {
SaveAndRestore<bool> inCatch(inEH, true);
return ::RecursiveASTVisitor<EHCodeVisitor>::TraverseObjCAtCatchStmt(S);
}
bool TraverseCXXCatchStmt(CXXCatchStmt *S) {
SaveAndRestore<bool> inCatch(inEH, true);
return TraverseStmt(S->getHandlerBlock());
}
bool VisitDeclRefExpr(DeclRefExpr *DR) {
if (inEH)
if (const VarDecl *D = dyn_cast<VarDecl>(DR->getDecl()))
S.insert(D);
return true;
}
EHCodeVisitor(llvm::DenseSet<const VarDecl *> &S) :
inEH(false), S(S) {}
};
@ -70,9 +70,9 @@ class ReachableCode {
public:
ReachableCode(const CFG &cfg)
: cfg(cfg), reachable(cfg.getNumBlockIDs(), false) {}
void computeReachableBlocks();
bool isReachable(const CFGBlock *block) const {
return reachable[block->getBlockID()];
}
@ -82,7 +82,7 @@ public:
void ReachableCode::computeReachableBlocks() {
if (!cfg.getNumBlockIDs())
return;
SmallVector<const CFGBlock*, 10> worklist;
worklist.push_back(&cfg.getEntry());
@ -160,19 +160,19 @@ public:
// to analyze that yet.
return InEH->count(D);
}
void Report(const VarDecl *V, DeadStoreKind dsk,
PathDiagnosticLocation L, SourceRange R) {
if (Escaped.count(V))
return;
// Compute reachable blocks within the CFG for trivial cases
// where a bogus dead store can be reported because itself is unreachable.
if (!reachableCode.get()) {
reachableCode.reset(new ReachableCode(cfg));
reachableCode->computeReachableBlocks();
}
if (!reachableCode->isReachable(currentBlock))
return;
@ -196,7 +196,7 @@ public:
case Enclosing:
// Don't report issues in this case, e.g.: "if (x = foo())",
// where 'x' is unused later. We have yet to see a case where
// where 'x' is unused later. We have yet to see a case where
// this is a real bug.
return;
}
@ -259,7 +259,7 @@ public:
const LiveVariables::LivenessValues &Live) override {
currentBlock = block;
// Skip statements in macros.
if (S->getLocStart().isMacroID())
return;
@ -276,7 +276,7 @@ public:
const Expr *RHS =
LookThroughTransitiveAssignmentsAndCommaOperators(B->getRHS());
RHS = RHS->IgnoreParenCasts();
QualType T = VD->getType();
if (T->isPointerType() || T->isObjCObjectPointerType()) {
if (RHS->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNull))
@ -318,27 +318,27 @@ public:
if (!V)
continue;
if (V->hasLocalStorage()) {
if (V->hasLocalStorage()) {
// Reference types confuse the dead stores checker. Skip them
// for now.
if (V->getType()->getAs<ReferenceType>())
return;
if (const Expr *E = V->getInit()) {
while (const ExprWithCleanups *exprClean =
dyn_cast<ExprWithCleanups>(E))
E = exprClean->getSubExpr();
// Look through transitive assignments, e.g.:
// int x = y = 0;
E = LookThroughTransitiveAssignmentsAndCommaOperators(E);
// Don't warn on C++ objects (yet) until we can show that their
// constructors/destructors don't have side effects.
if (isa<CXXConstructExpr>(E))
return;
// A dead initialization is a variable that is dead after it
// is initialized. We don't flag warnings for those variables
// marked 'unused' or 'objc_precise_lifetime'.

View File

@ -84,7 +84,7 @@ DereferenceChecker::AddDerefSource(raw_ostream &os,
SourceLocation L = IV->getLocation();
Ranges.push_back(SourceRange(L, L));
break;
}
}
}
}

View File

@ -29,7 +29,7 @@ class DivZeroChecker : public Checker< check::PreStmt<BinaryOperator> > {
CheckerContext &C) const ;
public:
void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
};
};
} // end anonymous namespace
void DivZeroChecker::reportBug(const char *Msg,

View File

@ -113,7 +113,7 @@ void DynamicTypePropagation::checkPostCall(const CallEvent &Call,
ProgramStateRef State = C.getState();
const ObjCMethodDecl *D = Msg->getDecl();
if (D && D->hasRelatedResultType()) {
switch (Msg->getMethodFamily()) {
default:
@ -201,7 +201,7 @@ void DynamicTypePropagation::checkPostStmt(const CXXNewExpr *NewE,
const MemRegion *MR = C.getSVal(NewE).getAsRegion();
if (!MR)
return;
C.addTransition(C.getState()->setDynamicTypeInfo(MR, NewE->getType(),
/*CanBeSubclass=*/false));
}

View File

@ -23,7 +23,7 @@ using namespace clang;
using namespace ento;
namespace {
class FixedAddressChecker
class FixedAddressChecker
: public Checker< check::PreStmt<BinaryOperator> > {
mutable std::unique_ptr<BuiltinBug> BT;

View File

@ -100,8 +100,8 @@ private:
/// Generate a report if the expression is tainted or points to tainted data.
bool generateReportIfTainted(const Expr *E, const char Msg[],
CheckerContext &C) const;
typedef SmallVector<unsigned, 2> ArgVector;
/// \brief A struct used to specify taint propagation rules for a function.
@ -441,7 +441,7 @@ SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C,
return Val.getAsSymbol();
}
ProgramStateRef
ProgramStateRef
GenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
@ -667,8 +667,8 @@ bool GenericTaintChecker::checkUncontrolledFormatString(const CallExpr *CE,
bool GenericTaintChecker::checkSystemCall(const CallExpr *CE,
StringRef Name,
CheckerContext &C) const {
// TODO: It might make sense to run this check on demand. In some cases,
// we should check if the environment has been cleansed here. We also might
// TODO: It might make sense to run this check on demand. In some cases,
// we should check if the environment has been cleansed here. We also might
// need to know if the user was reset before these calls(seteuid).
unsigned ArgNum = llvm::StringSwitch<unsigned>(Name)
.Case("system", 0)

View File

@ -96,7 +96,7 @@ void FindIdenticalExprVisitor::checkBitwiseOrLogicalOp(const BinaryOperator *B,
}
LHS = B2->getLHS();
}
if (isIdenticalStmt(AC->getASTContext(), RHS, LHS)) {
Sr[0] = RHS->getSourceRange();
Sr[1] = LHS->getSourceRange();

View File

@ -20,8 +20,8 @@
// been called on them. An invalidation method should either invalidate all
// the ivars or call another invalidation method (on self).
//
// Partial invalidor annotation allows to addess cases when ivars are
// invalidated by other methods, which might or might not be called from
// Partial invalidor annotation allows to addess cases when ivars are
// invalidated by other methods, which might or might not be called from
// the invalidation method. The checker checks that each invalidation
// method and all the partial methods cumulatively invalidate all ivars.
// __attribute__((annotate("objc_instance_variable_invalidator_partial")));
@ -310,7 +310,7 @@ const ObjCIvarDecl *IvarInvalidationCheckerImpl::findPropertyBackingIvar(
// Lookup for the synthesized case.
IvarD = Prop->getPropertyIvarDecl();
// We only track the ivars/properties that are defined in the current
// We only track the ivars/properties that are defined in the current
// class (not the parent).
if (IvarD && IvarD->getContainingInterface() == InterfaceD) {
if (TrackedIvars.count(IvarD)) {

View File

@ -118,7 +118,7 @@ private:
SValBuilder &Builder) const {
return definitelyReturnedError(RetSym, State, Builder, true);
}
/// Mark an AllocationPair interesting for diagnostic reporting.
void markInteresting(BugReport *R, const AllocationPair &AP) const {
R->markInteresting(AP.first);
@ -282,7 +282,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
const FunctionDecl *FD = C.getCalleeDecl(CE);
if (!FD || FD->getKind() != Decl::Function)
return;
StringRef funName = C.getCalleeName(FD);
if (funName.empty())
return;

View File

@ -79,7 +79,7 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
if (TrimmedFName != FName)
FName = TrimmedFName;
}
SmallString<256> S;
llvm::raw_svector_ostream os(S);
os << "Call to '" << FName << "' uses";

View File

@ -1,13 +1,13 @@
##===- clang/lib/Checker/Makefile --------------------------*- Makefile -*-===##
#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#
##===----------------------------------------------------------------------===##
#
# This implements analyses built on top of source-level CFGs.
# This implements analyses built on top of source-level CFGs.
#
##===----------------------------------------------------------------------===##

View File

@ -65,10 +65,10 @@ class RefState {
const Stmt *S;
unsigned K : 3; // Kind enum, but stored as a bitfield.
unsigned Family : 29; // Rest of 32-bit word, currently just an allocation
unsigned Family : 29; // Rest of 32-bit word, currently just an allocation
// family.
RefState(Kind k, const Stmt *s, unsigned family)
RefState(Kind k, const Stmt *s, unsigned family)
: S(s), K(k), Family(family) {
assert(family != AF_None);
}
@ -94,7 +94,7 @@ public:
return RefState(AllocatedOfSizeZero, RS->getStmt(),
RS->getAllocationFamily());
}
static RefState getReleased(unsigned family, const Stmt *s) {
static RefState getReleased(unsigned family, const Stmt *s) {
return RefState(Released, s, family);
}
static RefState getRelinquished(unsigned family, const Stmt *s) {
@ -169,9 +169,9 @@ class MallocChecker : public Checker<check::DeadSymbols,
{
public:
MallocChecker()
: II_alloca(nullptr), II_malloc(nullptr), II_free(nullptr),
: II_alloca(nullptr), II_malloc(nullptr), II_free(nullptr),
II_realloc(nullptr), II_calloc(nullptr), II_valloc(nullptr),
II_reallocf(nullptr), II_strndup(nullptr), II_strdup(nullptr),
II_reallocf(nullptr), II_strndup(nullptr), II_strdup(nullptr),
II_kmalloc(nullptr), II_if_nameindex(nullptr),
II_if_freenameindex(nullptr) {}
@ -185,7 +185,7 @@ public:
CK_NumCheckKinds
};
enum class MemoryOperationKind {
enum class MemoryOperationKind {
MOK_Allocate,
MOK_Free,
MOK_Any
@ -245,19 +245,19 @@ private:
/// \brief Print names of allocators and deallocators.
///
/// \returns true on success.
bool printAllocDeallocName(raw_ostream &os, CheckerContext &C,
bool printAllocDeallocName(raw_ostream &os, CheckerContext &C,
const Expr *E) const;
/// \brief Print expected name of an allocator based on the deallocator's
/// family derived from the DeallocExpr.
void printExpectedAllocName(raw_ostream &os, CheckerContext &C,
void printExpectedAllocName(raw_ostream &os, CheckerContext &C,
const Expr *DeallocExpr) const;
/// \brief Print expected name of a deallocator based on the allocator's
/// \brief Print expected name of a deallocator based on the allocator's
/// family.
void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) const;
///@{
/// Check if this is one of the functions which can allocate/reallocate memory
/// Check if this is one of the functions which can allocate/reallocate memory
/// pointed to by one of its arguments.
bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const;
bool isCMemFunction(const FunctionDecl *FD,
@ -292,7 +292,7 @@ private:
const ProgramStateRef &State) const;
/// Update the RefState to reflect the new memory allocation.
static ProgramStateRef
static ProgramStateRef
MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State,
AllocationFamily Family = AF_Malloc);
@ -312,17 +312,17 @@ private:
bool ReturnsNullOnFailure = false) const;
ProgramStateRef ReallocMem(CheckerContext &C, const CallExpr *CE,
bool FreesMemOnFailure,
bool FreesMemOnFailure,
ProgramStateRef State) const;
static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE,
ProgramStateRef State);
///\brief Check if the memory associated with this symbol was released.
bool isReleased(SymbolRef Sym, CheckerContext &C) const;
bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const;
void checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
void checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
const Stmt *S) const;
bool checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const;
@ -330,7 +330,7 @@ private:
/// Check if the function is known free memory, or if it is
/// "interesting" and should be modeled explicitly.
///
/// \param [out] EscapingSymbol A function might not free memory in general,
/// \param [out] EscapingSymbol A function might not free memory in general,
/// but could be known to free a particular symbol. In this case, false is
/// returned and the single escaping symbol is returned through the out
/// parameter.
@ -357,20 +357,20 @@ private:
Optional<CheckKind> getCheckIfTracked(CheckerContext &C,
const Stmt *AllocDeallocStmt,
bool IsALeakCheck = false) const;
Optional<CheckKind> getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
Optional<CheckKind> getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
bool IsALeakCheck = false) const;
///@}
static bool SummarizeValue(raw_ostream &os, SVal V);
static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
const Expr *DeallocExpr) const;
void ReportFreeAlloca(CheckerContext &C, SVal ArgVal,
SourceRange Range) const;
void ReportMismatchedDealloc(CheckerContext &C, SourceRange Range,
const Expr *DeallocExpr, const RefState *RS,
SymbolRef Sym, bool OwnershipTransferred) const;
void ReportOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
const Expr *DeallocExpr,
void ReportOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
const Expr *DeallocExpr,
const Expr *AllocExpr = nullptr) const;
void ReportUseAfterFree(CheckerContext &C, SourceRange Range,
SymbolRef Sym) const;
@ -425,8 +425,8 @@ private:
const Stmt *Stmt) {
// Did not track -> allocated. Other state (released) -> allocated.
return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXNewExpr>(Stmt)) &&
(S && (S->isAllocated() || S->isAllocatedOfSizeZero())) &&
(!SPrev || !(SPrev->isAllocated() ||
(S && (S->isAllocated() || S->isAllocatedOfSizeZero())) &&
(!SPrev || !(SPrev->isAllocated() ||
SPrev->isAllocatedOfSizeZero())));
}
@ -509,7 +509,7 @@ private:
REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState)
REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair)
// A map from the freed symbol to the symbol representing the return value of
// A map from the freed symbol to the symbol representing the return value of
// the free function.
REGISTER_MAP_WITH_PROGRAMSTATE(FreeReturnValue, SymbolRef, SymbolRef)
@ -633,7 +633,7 @@ bool MallocChecker::isStandardNewDelete(const FunctionDecl *FD,
return false;
OverloadedOperatorKind Kind = FD->getOverloadedOperator();
if (Kind != OO_New && Kind != OO_Array_New &&
if (Kind != OO_New && Kind != OO_Array_New &&
Kind != OO_Delete && Kind != OO_Array_Delete)
return false;
@ -798,8 +798,8 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
State = ProcessZeroAllocation(C, CE, 0, State);
} else if (isStandardNewDelete(FD, C.getASTContext())) {
// Process direct calls to operator new/new[]/delete/delete[] functions
// as distinct from new/new[]/delete/delete[] expressions that are
// processed by the checkPostStmt callbacks for CXXNewExpr and
// as distinct from new/new[]/delete/delete[] expressions that are
// processed by the checkPostStmt callbacks for CXXNewExpr and
// CXXDeleteExpr.
OverloadedOperatorKind K = FD->getOverloadedOperator();
if (K == OO_New) {
@ -869,7 +869,7 @@ ProgramStateRef MallocChecker::ProcessZeroAllocation(CheckerContext &C,
assert(Arg);
Optional<DefinedSVal> DefArgVal =
Optional<DefinedSVal> DefArgVal =
State->getSVal(Arg, C.getLocationContext()).getAs<DefinedSVal>();
if (!DefArgVal)
@ -881,7 +881,7 @@ ProgramStateRef MallocChecker::ProcessZeroAllocation(CheckerContext &C,
DefinedSVal Zero =
SvalBuilder.makeZeroVal(Arg->getType()).castAs<DefinedSVal>();
std::tie(TrueState, FalseState) =
std::tie(TrueState, FalseState) =
State->assume(SvalBuilder.evalEQ(State, *DefArgVal, Zero));
if (TrueState && !FalseState) {
@ -892,7 +892,7 @@ ProgramStateRef MallocChecker::ProcessZeroAllocation(CheckerContext &C,
const RefState *RS = State->get<RegionState>(Sym);
if (!RS)
return State; // TODO: change to assert(RS); after realloc() will
return State; // TODO: change to assert(RS); after realloc() will
// guarantee have a RegionState attached.
if (!RS->isAllocated())
@ -943,7 +943,7 @@ static bool treatUnusedNewEscaped(const CXXNewExpr *NE) {
return false;
}
void MallocChecker::checkPostStmt(const CXXNewExpr *NE,
void MallocChecker::checkPostStmt(const CXXNewExpr *NE,
CheckerContext &C) const {
if (NE->getNumPlacementArgs())
@ -960,17 +960,17 @@ void MallocChecker::checkPostStmt(const CXXNewExpr *NE,
return;
ProgramStateRef State = C.getState();
// The return value from operator new is bound to a specified initialization
// value (if any) and we don't want to loose this value. So we call
// MallocUpdateRefState() instead of MallocMemAux() which breakes the
// The return value from operator new is bound to a specified initialization
// value (if any) and we don't want to loose this value. So we call
// MallocUpdateRefState() instead of MallocMemAux() which breakes the
// existing binding.
State = MallocUpdateRefState(C, NE, State, NE->isArray() ? AF_CXXNewArray
State = MallocUpdateRefState(C, NE, State, NE->isArray() ? AF_CXXNewArray
: AF_CXXNew);
State = ProcessZeroAllocation(C, NE, 0, State);
C.addTransition(State);
}
void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE,
void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE,
CheckerContext &C) const {
if (!ChecksEnabled[CK_NewDeleteChecker])
@ -1037,7 +1037,7 @@ void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call,
ProgramStateRef
MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
const OwnershipAttr *Att,
const OwnershipAttr *Att,
ProgramStateRef State) const {
if (!State)
return nullptr;
@ -1104,7 +1104,7 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
State = State->assume(extentMatchesSize, true);
assert(State);
}
return MallocUpdateRefState(C, CE, State, Family);
}
@ -1131,7 +1131,7 @@ ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C,
ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C,
const CallExpr *CE,
const OwnershipAttr *Att,
const OwnershipAttr *Att,
ProgramStateRef State) const {
if (!State)
return nullptr;
@ -1183,7 +1183,7 @@ static bool didPreviousFreeFail(ProgramStateRef State,
return false;
}
AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C,
AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C,
const Stmt *S) const {
if (!S)
return AF_None;
@ -1228,14 +1228,14 @@ AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C,
return AF_None;
}
bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C,
bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C,
const Expr *E) const {
if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
// FIXME: This doesn't handle indirect calls.
const FunctionDecl *FD = CE->getDirectCallee();
if (!FD)
return false;
os << *FD;
if (!FD->isOverloadedOperator())
os << "()";
@ -1252,14 +1252,14 @@ bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C,
}
if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
os << "'"
os << "'"
<< getOperatorSpelling(NE->getOperatorNew()->getOverloadedOperator())
<< "'";
return true;
}
if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(E)) {
os << "'"
os << "'"
<< getOperatorSpelling(DE->getOperatorDelete()->getOverloadedOperator())
<< "'";
return true;
@ -1282,7 +1282,7 @@ void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C,
}
}
void MallocChecker::printExpectedDeallocName(raw_ostream &os,
void MallocChecker::printExpectedDeallocName(raw_ostream &os,
AllocationFamily Family) const {
switch(Family) {
case AF_Malloc: os << "free()"; return;
@ -1326,25 +1326,25 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
return nullptr;
const MemRegion *R = ArgVal.getAsRegion();
// Nonlocs can't be freed, of course.
// Non-region locations (labels and fixed addresses) also shouldn't be freed.
if (!R) {
ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
return nullptr;
}
R = R->StripCasts();
// Blocks might show up as heap data, but should not be free()d
if (isa<BlockDataRegion>(R)) {
ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
return nullptr;
}
const MemSpaceRegion *MS = R->getMemorySpace();
// Parameters, locals, statics, globals, and memory returned by
// Parameters, locals, statics, globals, and memory returned by
// __builtin_alloca() shouldn't be freed.
if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
// FIXME: at the time this code was written, malloc() regions were
@ -1390,7 +1390,7 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
// If the pointer is allocated or escaped, but we are now trying to free it,
// check that the call to free is proper.
} else if (RsBase->isAllocated() || RsBase->isAllocatedOfSizeZero() ||
} else if (RsBase->isAllocated() || RsBase->isAllocatedOfSizeZero() ||
RsBase->isEscaped()) {
// Check if an expected deallocation function matches the real one.
@ -1409,20 +1409,20 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
!Offset.hasSymbolicOffset() &&
Offset.getOffset() != 0) {
const Expr *AllocExpr = cast<Expr>(RsBase->getStmt());
ReportOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
ReportOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
AllocExpr);
return nullptr;
}
}
}
ReleasedAllocated = (RsBase != nullptr) && (RsBase->isAllocated() ||
ReleasedAllocated = (RsBase != nullptr) && (RsBase->isAllocated() ||
RsBase->isAllocatedOfSizeZero());
// Clean out the info on previous call to free return info.
State = State->remove<FreeReturnValue>(SymBase);
// Keep track of the return value. If it is NULL, we will know that free
// Keep track of the return value. If it is NULL, we will know that free
// failed.
if (ReturnsNullOnFailure) {
SVal RetVal = C.getSVal(ParentExpr);
@ -1462,7 +1462,7 @@ MallocChecker::getCheckIfTracked(AllocationFamily Family,
if (IsALeakCheck) {
if (ChecksEnabled[CK_NewDeleteLeaksChecker])
return CK_NewDeleteLeaksChecker;
}
}
else {
if (ChecksEnabled[CK_NewDeleteChecker])
return CK_NewDeleteChecker;
@ -1501,7 +1501,7 @@ bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
os << "the address of the label '" << Label->getLabel()->getName() << "'";
else
return false;
return true;
}
@ -1525,7 +1525,7 @@ bool MallocChecker::SummarizeRegion(raw_ostream &os,
return true;
default: {
const MemSpaceRegion *MS = MR->getMemorySpace();
if (isa<StackLocalsSpaceRegion>(MS)) {
const VarRegion *VR = dyn_cast<VarRegion>(MR);
const VarDecl *VD;
@ -1579,8 +1579,8 @@ bool MallocChecker::SummarizeRegion(raw_ostream &os,
}
}
void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
SourceRange Range,
void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
SourceRange Range,
const Expr *DeallocExpr) const {
if (!ChecksEnabled[CK_MallocChecker] &&
@ -1609,7 +1609,7 @@ void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
os << "deallocator";
os << " is ";
bool Summarized = MR ? SummarizeRegion(os, MR)
bool Summarized = MR ? SummarizeRegion(os, MR)
: SummarizeValue(os, ArgVal);
if (Summarized)
os << ", which is not memory allocated by ";
@ -1625,7 +1625,7 @@ void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
}
}
void MallocChecker::ReportFreeAlloca(CheckerContext &C, SVal ArgVal,
void MallocChecker::ReportFreeAlloca(CheckerContext &C, SVal ArgVal,
SourceRange Range) const {
Optional<MallocChecker::CheckKind> CheckKind;
@ -1651,11 +1651,11 @@ void MallocChecker::ReportFreeAlloca(CheckerContext &C, SVal ArgVal,
}
}
void MallocChecker::ReportMismatchedDealloc(CheckerContext &C,
void MallocChecker::ReportMismatchedDealloc(CheckerContext &C,
SourceRange Range,
const Expr *DeallocExpr,
const Expr *DeallocExpr,
const RefState *RS,
SymbolRef Sym,
SymbolRef Sym,
bool OwnershipTransferred) const {
if (!ChecksEnabled[CK_MismatchedDeallocatorChecker])
@ -1679,7 +1679,7 @@ void MallocChecker::ReportMismatchedDealloc(CheckerContext &C,
if (OwnershipTransferred) {
if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
os << DeallocOs.str() << " cannot";
else
else
os << "Cannot";
os << " take ownership of memory";
@ -1790,7 +1790,7 @@ void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
}
void MallocChecker::ReportDoubleFree(CheckerContext &C, SourceRange Range,
bool Released, SymbolRef Sym,
bool Released, SymbolRef Sym,
SymbolRef PrevSym) const {
if (!ChecksEnabled[CK_MallocChecker] &&
@ -1920,7 +1920,7 @@ ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero;
// If the ptr is NULL and the size is not 0, the call is equivalent to
// If the ptr is NULL and the size is not 0, the call is equivalent to
// malloc(size).
if ( PrtIsNull && !SizeIsZero) {
ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
@ -1978,7 +1978,7 @@ ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
return nullptr;
}
ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE,
ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE,
ProgramStateRef State) {
if (!State)
return nullptr;
@ -1991,7 +1991,7 @@ ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE,
SVal count = State->getSVal(CE->getArg(0), LCtx);
SVal elementSize = State->getSVal(CE->getArg(1), LCtx);
SVal TotalSize = svalBuilder.evalBinOp(State, BO_Mul, count, elementSize,
svalBuilder.getContext().getSizeType());
svalBuilder.getContext().getSizeType());
SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
return MallocMemAux(C, CE, TotalSize, zeroVal, State);
@ -2078,7 +2078,7 @@ void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
const ExplodedNode *AllocNode = nullptr;
const MemRegion *Region = nullptr;
std::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
ProgramPoint P = AllocNode->getLocation();
const Stmt *AllocationStmt = nullptr;
if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
@ -2127,7 +2127,7 @@ void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
}
}
// Cleanup the Realloc Pairs Map.
ReallocPairsTy RP = state->get<ReallocPairs>();
for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
@ -2232,7 +2232,7 @@ void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
}
// TODO: Blocks should be either inlined or should call invalidate regions
// upon invocation. After that's in place, special casing here will not be
// upon invocation. After that's in place, special casing here will not be
// needed.
void MallocChecker::checkPostStmt(const BlockExpr *BE,
CheckerContext &C) const {
@ -2446,7 +2446,7 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
StringRef FName = II->getName();
// White list the 'XXXNoCopy' CoreFoundation functions.
// We specifically check these before
// We specifically check these before
if (FName.endswith("NoCopy")) {
// Look for the deallocator argument. We know that the memory ownership
// is not transferred only if the deallocator argument is
@ -2555,7 +2555,7 @@ ProgramStateRef MallocChecker::checkPointerEscapeAux(ProgramStateRef State,
if (EscapingSymbol && EscapingSymbol != sym)
continue;
if (const RefState *RS = State->get<RegionState>(sym)) {
if ((RS->isAllocated() || RS->isAllocatedOfSizeZero()) &&
CheckRefState(RS)) {
@ -2702,7 +2702,7 @@ void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true;
checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] =
mgr.getCurrentCheckName();
// We currently treat NewDeleteLeaks checker as a subchecker of NewDelete
// We currently treat NewDeleteLeaks checker as a subchecker of NewDelete
// checker.
if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker])
checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true;

View File

@ -33,7 +33,7 @@ struct MallocOverflowCheck {
const BinaryOperator *mulop;
const Expr *variable;
MallocOverflowCheck (const BinaryOperator *m, const Expr *v)
MallocOverflowCheck (const BinaryOperator *m, const Expr *v)
: mulop(m), variable (v)
{}
};

View File

@ -143,20 +143,20 @@ static bool typesCompatible(ASTContext &C, QualType A, QualType B) {
while (true) {
A = A.getCanonicalType();
B = B.getCanonicalType();
if (A.getTypePtr() == B.getTypePtr())
return true;
if (const PointerType *ptrA = A->getAs<PointerType>())
if (const PointerType *ptrB = B->getAs<PointerType>()) {
A = ptrA->getPointeeType();
B = ptrB->getPointeeType();
continue;
}
break;
}
return false;
}

View File

@ -11,7 +11,7 @@
// about subpar uses of NSAutoreleasePool. Note that while the check itself
// (in its current form) could be written as a flow-insensitive check, in
// can be potentially enhanced in the future with flow-sensitive information.
// It is also a good example of the CheckerVisitor interface.
// It is also a good example of the CheckerVisitor interface.
//
//===----------------------------------------------------------------------===//
@ -48,7 +48,7 @@ void NSAutoreleasePoolChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
const ObjCInterfaceDecl *OD = msg.getReceiverInterface();
if (!OD)
return;
return;
if (!OD->getIdentifier()->isStr("NSAutoreleasePool"))
return;

View File

@ -58,7 +58,7 @@ void NSErrorMethodChecker::checkASTDecl(const ObjCMethodDecl *D,
return;
if (!II)
II = &D->getASTContext().Idents.get("NSError");
II = &D->getASTContext().Idents.get("NSError");
bool hasNSError = false;
for (const auto *I : D->params()) {
@ -105,7 +105,7 @@ void CFErrorFunctionChecker::checkASTDecl(const FunctionDecl *D,
return;
if (!II)
II = &D->getASTContext().Idents.get("CFErrorRef");
II = &D->getASTContext().Idents.get("CFErrorRef");
bool hasCFError = false;
for (auto I : D->params()) {

View File

@ -133,7 +133,7 @@ void ObjCContainersChecker::checkPreStmt(const CallExpr *CE,
if (IdxVal.isUnknownOrUndef())
return;
DefinedSVal Idx = IdxVal.castAs<DefinedSVal>();
// Now, check if 'Idx in [0, Size-1]'.
const QualType T = IdxExpr->getType();
ProgramStateRef StInBound = State->assumeInBound(Idx, *Size, true, T);

View File

@ -49,7 +49,7 @@ public:
DoesCallSuper = true;
// Recurse if we didn't find the super call yet.
return !DoesCallSuper;
return !DoesCallSuper;
}
bool DoesCallSuper;
@ -59,7 +59,7 @@ private:
};
//===----------------------------------------------------------------------===//
// ObjCSuperCallChecker
// ObjCSuperCallChecker
//===----------------------------------------------------------------------===//
class ObjCSuperCallChecker : public Checker<
@ -202,7 +202,7 @@ void ObjCSuperCallChecker::checkASTDecl(const ObjCImplementationDecl *D,
SmallString<320> Buf;
llvm::raw_svector_ostream os(Buf);
os << "The '" << S.getAsString()
os << "The '" << S.getAsString()
<< "' instance method in " << SuperclassName.str() << " subclass '"
<< *D << "' is missing a [super " << S.getAsString() << "] call";

View File

@ -145,13 +145,13 @@ void ObjCSelfInitChecker::checkForInvalidSelf(const Expr *E, CheckerContext &C,
const char *errorStr) const {
if (!E)
return;
if (!C.getState()->get<CalledInit>())
return;
if (!isInvalidSelf(E, C))
return;
// Generate an error node.
ExplodedNode *N = C.generateSink();
if (!N)
@ -177,12 +177,12 @@ void ObjCSelfInitChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
if (isInitMessage(Msg)) {
// Tag the return value as the result of an initializer.
ProgramStateRef state = C.getState();
// FIXME this really should be context sensitive, where we record
// the current stack frame (for IPA). Also, we need to clean this
// value out when we return from this method.
state = state->set<CalledInit>(true);
SVal V = state->getSVal(Msg.getOriginExpr(), C.getLocationContext());
addSelfFlag(state, V, SelfFlag_InitRes, C);
return;
@ -318,7 +318,7 @@ void ObjCSelfInitChecker::checkBind(SVal loc, SVal val, const Stmt *S,
CheckerContext &C) const {
// Allow assignment of anything to self. Self is a local variable in the
// initializer, so it is legal to assign anything to it, like results of
// static functions/method calls. After self is assigned something we cannot
// static functions/method calls. After self is assigned something we cannot
// reason about, stop enforcing the rules.
// (Only continue checking if the assigned value should be treated as self.)
if ((isSelfVar(loc, C)) &&
@ -412,7 +412,7 @@ static bool shouldRunOnFunctionOrMethod(const NamedDecl *ND) {
/// \brief Returns true if the location is 'self'.
static bool isSelfVar(SVal location, CheckerContext &C) {
AnalysisDeclContext *analCtx = C.getCurrentAnalysisDeclContext();
AnalysisDeclContext *analCtx = C.getCurrentAnalysisDeclContext();
if (!analCtx->getSelfDecl())
return false;
if (!location.getAs<loc::MemRegionVal>())

View File

@ -22,7 +22,7 @@ using namespace clang;
using namespace ento;
namespace {
class PointerArithChecker
class PointerArithChecker
: public Checker< check::PreStmt<BinaryOperator> > {
mutable std::unique_ptr<BuiltinBug> BT;
@ -48,7 +48,7 @@ void PointerArithChecker::checkPreStmt(const BinaryOperator *B,
// If pointer arithmetic is done on variables of non-array type, this often
// means behavior rely on memory organization, which is dangerous.
if (isa<VarRegion>(LR) || isa<CodeTextRegion>(LR) ||
if (isa<VarRegion>(LR) || isa<CodeTextRegion>(LR) ||
isa<CompoundLiteralRegion>(LR)) {
if (ExplodedNode *N = C.addTransition()) {

View File

@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This files defines PointerSubChecker, a builtin checker that checks for
// pointer subtractions on two pointers pointing to different memory chunks.
// pointer subtractions on two pointers pointing to different memory chunks.
// This check corresponds to CWE-469.
//
//===----------------------------------------------------------------------===//
@ -23,7 +23,7 @@ using namespace clang;
using namespace ento;
namespace {
class PointerSubChecker
class PointerSubChecker
: public Checker< check::PreStmt<BinaryOperator> > {
mutable std::unique_ptr<BuiltinBug> BT;

View File

@ -62,10 +62,10 @@ class PthreadLockChecker : public Checker< check::PostStmt<CallExpr> > {
};
public:
void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
void AcquireLock(CheckerContext &C, const CallExpr *CE, SVal lock,
bool isTryLock, enum LockingSemantics semantics) const;
void ReleaseLock(CheckerContext &C, const CallExpr *CE, SVal lock) const;
void DestroyLock(CheckerContext &C, const CallExpr *CE, SVal Lock) const;
void InitLock(CheckerContext &C, const CallExpr *CE, SVal Lock) const;
@ -96,7 +96,7 @@ void PthreadLockChecker::checkPostStmt(const CallExpr *CE,
false, PthreadSemantics);
else if (FName == "lck_mtx_lock" ||
FName == "lck_rw_lock_exclusive" ||
FName == "lck_rw_lock_shared")
FName == "lck_rw_lock_shared")
AcquireLock(C, CE, state->getSVal(CE->getArg(0), LCtx),
false, XNUSemantics);
else if (FName == "pthread_mutex_trylock" ||
@ -124,17 +124,17 @@ void PthreadLockChecker::checkPostStmt(const CallExpr *CE,
void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
SVal lock, bool isTryLock,
enum LockingSemantics semantics) const {
const MemRegion *lockR = lock.getAsRegion();
if (!lockR)
return;
ProgramStateRef state = C.getState();
SVal X = state->getSVal(CE, C.getLocationContext());
if (X.isUnknownOrUndef())
return;
DefinedSVal retVal = X.castAs<DefinedSVal>();
if (const LockState *LState = state->get<LockMap>(lockR)) {
@ -183,8 +183,8 @@ void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
assert((semantics == XNUSemantics) && "Unknown locking semantics");
lockSucc = state;
}
// Record that the lock was acquired.
// Record that the lock was acquired.
lockSucc = lockSucc->add<LockSet>(lockR);
lockSucc = lockSucc->set<LockMap>(lockR, LockState::getLocked());
C.addTransition(lockSucc);
@ -196,7 +196,7 @@ void PthreadLockChecker::ReleaseLock(CheckerContext &C, const CallExpr *CE,
const MemRegion *lockR = lock.getAsRegion();
if (!lockR)
return;
ProgramStateRef state = C.getState();
if (const LockState *LState = state->get<LockMap>(lockR)) {

View File

@ -250,7 +250,7 @@ public:
bool operator==(const RefVal& X) const {
return T == X.T && hasSameState(X) && getObjKind() == X.getObjKind();
}
void Profile(llvm::FoldingSetNodeID& ID) const {
ID.Add(T);
ID.AddInteger(RawKind);
@ -426,16 +426,16 @@ public:
/// setRetEffect - Set the effect of the return value of the call.
void setRetEffect(RetEffect E) { Ret = E; }
/// Sets the effect on the receiver of the message.
void setReceiverEffect(ArgEffect e) { Receiver = e; }
/// getReceiverEffect - Returns the effect on the receiver of the call.
/// This is only meaningful if the summary applies to an ObjCMessageExpr*.
ArgEffect getReceiverEffect() const { return Receiver; }
/// Test if two retain summaries are identical. Note that merely equivalent
/// summaries are not necessarily identical (for example, if an explicit
/// summaries are not necessarily identical (for example, if an explicit
/// argument effect matches the default effect).
bool operator==(const RetainSummary &Other) const {
return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&
@ -621,7 +621,7 @@ class RetainSummaryManager {
ArgEffects::Factory AF;
/// ScratchArgs - A holding buffer for construct ArgEffects.
ArgEffects ScratchArgs;
ArgEffects ScratchArgs;
/// ObjCAllocRetE - Default return effect for methods returning Objective-C
/// objects.
@ -644,7 +644,7 @@ class RetainSummaryManager {
ArgEffects getArgEffects();
enum UnaryFuncKind { cfretain, cfrelease, cfautorelease, cfmakecollectable };
const RetainSummary *getUnarySummary(const FunctionType* FT,
UnaryFuncKind func);
@ -664,7 +664,7 @@ class RetainSummaryManager {
const RetainSummary *getDoNothingSummary() {
return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
}
const RetainSummary *getDefaultSummary() {
return getPersistentSummary(RetEffect::MakeNoRet(),
DoNothing, MayEscape);
@ -689,7 +689,7 @@ private:
void addClassMethSummary(const char* Cls, const char* name,
const RetainSummary *Summ, bool isNullary = true) {
IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
Selector S = isNullary ? GetNullarySelector(name, Ctx)
Selector S = isNullary ? GetNullarySelector(name, Ctx)
: GetUnarySelector(name, Ctx);
ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
}
@ -739,7 +739,7 @@ public:
? RetEffect::MakeGCNotOwned()
: (usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
: RetEffect::MakeOwned(RetEffect::ObjC, true))),
ObjCInitRetE(gcenabled
ObjCInitRetE(gcenabled
? RetEffect::MakeGCNotOwned()
: (usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
: RetEffect::MakeOwnedWhenTrackedReceiver())) {
@ -803,7 +803,7 @@ public:
bool isGCEnabled() const { return GCEnabled; }
bool isARCEnabled() const { return ARCEnabled; }
bool isARCorGCEnabled() const { return GCEnabled || ARCEnabled; }
RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
@ -966,7 +966,7 @@ void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,
// Additionally, our Self Init checker already warns about it. To avoid
// overwhelming the user with messages from both checkers, we model the case
// of '[super init]' in cases when it is not consumed by another expression
// as if the call preserves the value of 'self'; essentially, assuming it can
// as if the call preserves the value of 'self'; essentially, assuming it can
// never fail and return 'nil'.
// Note, we don't want to just stop tracking the value since we want the
// RetainCount checker to report leaks and use-after-free if SelfInit checker
@ -1150,7 +1150,7 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) {
if (S)
break;
if (RetTy->isPointerType()) {
if (RetTy->isPointerType()) {
// For CoreFoundation ('CF') types.
if (cocoa::isRefType(RetTy, "CF", FName)) {
if (isRetain(FD, FName)) {
@ -1278,14 +1278,14 @@ RetainSummaryManager::getUnarySummary(const FunctionType* FT,
return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
}
const RetainSummary *
const RetainSummary *
RetainSummaryManager::getCFSummaryCreateRule(const FunctionDecl *FD) {
assert (ScratchArgs.isEmpty());
return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
}
const RetainSummary *
const RetainSummary *
RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {
assert (ScratchArgs.isEmpty());
return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF),
@ -1331,7 +1331,7 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
// Effects on the parameters.
unsigned parm_idx = 0;
for (FunctionDecl::param_const_iterator pi = FD->param_begin(),
for (FunctionDecl::param_const_iterator pi = FD->param_begin(),
pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) {
const ParmVarDecl *pd = *pi;
if (pd->hasAttr<NSConsumedAttr>())
@ -1367,8 +1367,8 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
// Effects on the receiver.
if (MD->hasAttr<NSConsumesSelfAttr>())
Template->setReceiverEffect(DecRefMsg);
Template->setReceiverEffect(DecRefMsg);
// Effects on the parameters.
unsigned parm_idx = 0;
for (ObjCMethodDecl::param_const_iterator
@ -1376,9 +1376,9 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
pi != pe; ++pi, ++parm_idx) {
const ParmVarDecl *pd = *pi;
if (pd->hasAttr<NSConsumedAttr>())
Template->addArg(AF, parm_idx, DecRefMsg);
Template->addArg(AF, parm_idx, DecRefMsg);
else if (pd->hasAttr<CFConsumedAttr>()) {
Template->addArg(AF, parm_idx, DecRef);
Template->addArg(AF, parm_idx, DecRef);
} else if (pd->hasAttr<CFReturnsRetainedAttr>()) {
QualType PointeeTy = pd->getType()->getPointeeType();
if (!PointeeTy.isNull())
@ -1415,7 +1415,7 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
if (cocoa::isCocoaObjectRef(RetTy))
ResultEff = RetEffect::MakeNotOwned(RetEffect::ObjC);
else if (coreFoundation::isCFObjectRef(RetTy)) {
// ObjCMethodDecl currently doesn't consider CF objects as valid return
// ObjCMethodDecl currently doesn't consider CF objects as valid return
// values for alloc, new, copy, or mutableCopy, so we have to
// double-check with the selector. This is ugly, but there aren't that
// many Objective-C methods that return CF objects, right?
@ -1428,11 +1428,11 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
ResultEff = RetEffect::MakeOwned(RetEffect::CF, true);
break;
default:
ResultEff = RetEffect::MakeNotOwned(RetEffect::CF);
ResultEff = RetEffect::MakeNotOwned(RetEffect::CF);
break;
}
} else {
ResultEff = RetEffect::MakeNotOwned(RetEffect::CF);
ResultEff = RetEffect::MakeNotOwned(RetEffect::CF);
}
}
break;
@ -1749,7 +1749,7 @@ namespace {
SymbolRef Sym;
const SummaryLogTy &SummaryLog;
bool GCEnabled;
public:
CFRefReportVisitor(SymbolRef sym, bool gcEnabled, const SummaryLogTy &log)
: Sym(sym), SummaryLog(log), GCEnabled(gcEnabled) {}
@ -1869,7 +1869,7 @@ void CFRefReport::addGCModeDescription(const LangOptions &LOpts,
static bool isNumericLiteralExpression(const Expr *E) {
// FIXME: This set of cases was copied from SemaExprObjC.
return isa<IntegerLiteral>(E) ||
return isa<IntegerLiteral>(E) ||
isa<CharacterLiteral>(E) ||
isa<FloatingLiteral>(E) ||
isa<ObjCBoolLiteralExpr>(E) ||
@ -1948,7 +1948,7 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
else if (isa<ObjCIvarRefExpr>(S)) {
os << "Object loaded from instance variable";
}
else {
else {
if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
// Get the name of the callee (if it is available).
SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee(), LCtx);
@ -2228,7 +2228,7 @@ GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
StoreManager::FindUniqueBinding FB(Sym);
StateMgr.iterBindings(St, FB);
if (FB) {
const MemRegion *R = FB.getRegion();
const VarRegion *VR = R->getBaseRegion()->getAs<VarRegion>();
@ -2345,10 +2345,10 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
// objects. Only "copy", "alloc", "retain" and "new" transfer ownership
// to the caller for NS objects.
const Decl *D = &EndN->getCodeDecl();
os << (isa<ObjCMethodDecl>(D) ? " is returned from a method "
: " is returned from a function ");
if (D->hasAttr<CFReturnsNotRetainedAttr>())
os << "that is annotated as CF_RETURNS_NOT_RETAINED";
else if (D->hasAttr<NSReturnsNotRetainedAttr>())
@ -2385,7 +2385,7 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
}
CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
bool GCEnabled, const SummaryLogTy &Log,
bool GCEnabled, const SummaryLogTy &Log,
ExplodedNode *n, SymbolRef sym,
CheckerContext &Ctx,
bool IncludeAllocationLine)
@ -2492,7 +2492,7 @@ class RetainCountChecker
/// the allocation line.
mutable bool IncludeAllocationLine;
public:
public:
RetainCountChecker(AnalyzerOptions &AO)
: ShouldResetSummaryLog(false),
IncludeAllocationLine(shouldIncludeAllocationSiteInLeakDiagnostics(AO)) {}
@ -2617,7 +2617,7 @@ public:
void checkPostStmt(const ObjCIvarRefExpr *IRE, CheckerContext &C) const;
void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
void checkSummary(const RetainSummary &Summ, const CallEvent &Call,
CheckerContext &C) const;
@ -2630,13 +2630,13 @@ public:
ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
bool Assumption) const;
ProgramStateRef
ProgramStateRef
checkRegionChanges(ProgramStateRef state,
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call) const;
bool wantsRegionChangeUpdate(ProgramStateRef state) const {
return true;
}
@ -2645,7 +2645,7 @@ public:
void checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C,
ExplodedNode *Pred, RetEffect RE, RefVal X,
SymbolRef Sym, ProgramStateRef state) const;
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
void checkEndFunction(CheckerContext &C) const;
@ -2656,7 +2656,7 @@ public:
void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange,
RefVal::Kind ErrorKind, SymbolRef Sym,
CheckerContext &C) const;
void processObjCLiterals(CheckerContext &C, const Expr *Ex) const;
const ProgramPointTag *getDeadSymbolTag(SymbolRef sym) const;
@ -2740,21 +2740,21 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE,
const ObjCBridgedCastExpr *BE = dyn_cast<ObjCBridgedCastExpr>(CE);
if (!BE)
return;
ArgEffect AE = IncRef;
switch (BE->getBridgeKind()) {
case clang::OBC_Bridge:
// Do nothing.
return;
case clang::OBC_BridgeRetained:
AE = IncRef;
break;
break;
case clang::OBC_BridgeTransfer:
AE = DecRefBridgedTransferred;
break;
}
ProgramStateRef state = C.getState();
SymbolRef Sym = state->getSVal(CE, C.getLocationContext()).getAsLocSymbol();
if (!Sym)
@ -2765,7 +2765,7 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE,
RefVal::Kind hasErr = (RefVal::Kind) 0;
state = updateSymbol(state, Sym, *T, AE, hasErr, C);
if (hasErr) {
// FIXME: If we get an error during a bridge cast, should we report it?
return;
@ -2777,7 +2777,7 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE,
void RetainCountChecker::processObjCLiterals(CheckerContext &C,
const Expr *Ex) const {
ProgramStateRef state = C.getState();
const ExplodedNode *pred = C.getPredecessor();
const ExplodedNode *pred = C.getPredecessor();
for (const Stmt *Child : Ex->children()) {
SVal V = state->getSVal(Child, pred->getLocationContext());
if (SymbolRef sym = V.getAsSymbol())
@ -2790,17 +2790,17 @@ void RetainCountChecker::processObjCLiterals(CheckerContext &C,
}
}
}
// Return the object as autoreleased.
// RetEffect RE = RetEffect::MakeNotOwned(RetEffect::ObjC);
if (SymbolRef sym =
if (SymbolRef sym =
state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) {
QualType ResultTy = Ex->getType();
state = setRefBinding(state, sym,
RefVal::makeNotOwned(RetEffect::ObjC, ResultTy));
}
C.addTransition(state);
C.addTransition(state);
}
void RetainCountChecker::checkPostStmt(const ObjCArrayLiteral *AL,
@ -2817,7 +2817,7 @@ void RetainCountChecker::checkPostStmt(const ObjCDictionaryLiteral *DL,
void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex,
CheckerContext &C) const {
const ExplodedNode *Pred = C.getPredecessor();
const ExplodedNode *Pred = C.getPredecessor();
const LocationContext *LCtx = Pred->getLocationContext();
ProgramStateRef State = Pred->getState();
@ -2966,7 +2966,7 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
if (Sym)
state = removeRefBinding(state, Sym);
}
C.addTransition(state);
}
@ -3062,7 +3062,7 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
if (ReceiverIsTracked)
RE = getSummaryManager(C).getObjAllocRetEffect();
RE = getSummaryManager(C).getObjAllocRetEffect();
else
RE = RetEffect::MakeNoRet();
}
@ -3130,7 +3130,7 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
}
ProgramStateRef
ProgramStateRef
RetainCountChecker::updateSymbol(ProgramStateRef state, SymbolRef sym,
RefVal V, ArgEffect E, RefVal::Kind &hasErr,
CheckerContext &C) const {
@ -3388,7 +3388,7 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
isMakeCollectable(FD, FName);
}
}
if (!canEval)
return false;
@ -3700,7 +3700,7 @@ ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
return state;
}
ProgramStateRef
ProgramStateRef
RetainCountChecker::checkRegionChanges(ProgramStateRef state,
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
@ -3810,7 +3810,7 @@ RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state,
return nullptr;
}
ProgramStateRef
ProgramStateRef
RetainCountChecker::handleSymbolDeath(ProgramStateRef state,
SymbolRef sid, RefVal V,
SmallVectorImpl<SymbolRef> &Leaked) const {
@ -3890,7 +3890,7 @@ void RetainCountChecker::checkEndFunction(CheckerContext &Ctx) const {
// and suggest annotations.
if (LCtx->getParent())
return;
B = state->get<RefBindings>();
SmallVector<SymbolRef, 10> Leaked;
@ -3910,7 +3910,7 @@ RetainCountChecker::getDeadSymbolTag(SymbolRef sym) const {
sym->dumpToStream(out);
tag = new CheckerProgramPointTag(this, out.str());
}
return tag;
return tag;
}
void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,

View File

@ -23,7 +23,7 @@ using namespace clang;
using namespace ento;
namespace {
class ReturnPointerRangeChecker :
class ReturnPointerRangeChecker :
public Checker< check::PreStmt<ReturnStmt> > {
mutable std::unique_ptr<BuiltinBug> BT;
@ -39,7 +39,7 @@ void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
const Expr *RetE = RS->getRetValue();
if (!RetE)
return;
SVal V = state->getSVal(RetE, C.getLocationContext());
const MemRegion *R = V.getAsRegion();
@ -66,7 +66,7 @@ void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
if (!N)
return;
// FIXME: This bug correspond to CWE-466. Eventually we should have bug
// types explicitly reference such exploit categories (when applicable).
if (!BT)

View File

@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines stack address leak checker, which checks if an invalid
// This file defines stack address leak checker, which checks if an invalid
// stack address is stored into a global or heap location. See CERT DCL30-C.
//
//===----------------------------------------------------------------------===//
@ -49,20 +49,20 @@ SourceRange StackAddrEscapeChecker::genName(raw_ostream &os, const MemRegion *R,
SourceManager &SM = Ctx.getSourceManager();
SourceRange range;
os << "Address of ";
// Check if the region is a compound literal.
if (const CompoundLiteralRegion* CR = dyn_cast<CompoundLiteralRegion>(R)) {
if (const CompoundLiteralRegion* CR = dyn_cast<CompoundLiteralRegion>(R)) {
const CompoundLiteralExpr *CL = CR->getLiteralExpr();
os << "stack memory associated with a compound literal "
"declared on line "
<< SM.getExpansionLineNumber(CL->getLocStart())
<< " returned to caller";
<< " returned to caller";
range = CL->getSourceRange();
}
else if (const AllocaRegion* AR = dyn_cast<AllocaRegion>(R)) {
const Expr *ARE = AR->getExpr();
SourceLocation L = ARE->getLocStart();
range = ARE->getSourceRange();
range = ARE->getSourceRange();
os << "stack memory allocated by call to alloca() on line "
<< SM.getExpansionLineNumber(L);
}
@ -87,8 +87,8 @@ SourceRange StackAddrEscapeChecker::genName(raw_ostream &os, const MemRegion *R,
}
else {
llvm_unreachable("Invalid region in ReturnStackAddressChecker.");
}
}
return range;
}
@ -118,7 +118,7 @@ void StackAddrEscapeChecker::EmitStackError(CheckerContext &C, const MemRegion *
void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS,
CheckerContext &C) const {
const Expr *RetE = RS->getRetValue();
if (!RetE)
return;
@ -130,10 +130,10 @@ void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS,
if (!R)
return;
const StackSpaceRegion *SS =
dyn_cast_or_null<StackSpaceRegion>(R->getMemorySpace());
if (!SS)
return;
@ -175,35 +175,35 @@ void StackAddrEscapeChecker::checkEndFunction(CheckerContext &Ctx) const {
Ctx(CC),
CurSFC(CC.getLocationContext()->getCurrentStackFrame())
{}
bool HandleBinding(StoreManager &SMgr, Store store,
const MemRegion *region, SVal val) override {
if (!isa<GlobalsSpaceRegion>(region->getMemorySpace()))
return true;
const MemRegion *vR = val.getAsRegion();
if (!vR)
return true;
// Under automated retain release, it is okay to assign a block
// directly to a global variable.
if (Ctx.getASTContext().getLangOpts().ObjCAutoRefCount &&
isa<BlockDataRegion>(vR))
return true;
if (const StackSpaceRegion *SSR =
if (const StackSpaceRegion *SSR =
dyn_cast<StackSpaceRegion>(vR->getMemorySpace())) {
// If the global variable holds a location in the current stack frame,
// record the binding to emit a warning.
if (SSR->getStackFrame() == CurSFC)
V.push_back(std::make_pair(region, vR));
}
return true;
}
};
CallBack cb(Ctx);
state->getStateManager().getStoreManager().iterBindings(state->getStore(),cb);

View File

@ -43,8 +43,8 @@ struct StreamState {
static StreamState getOpened(const Stmt *s) { return StreamState(Opened, s); }
static StreamState getClosed(const Stmt *s) { return StreamState(Closed, s); }
static StreamState getOpenFailed(const Stmt *s) {
return StreamState(OpenFailed, s);
static StreamState getOpenFailed(const Stmt *s) {
return StreamState(OpenFailed, s);
}
static StreamState getEscaped(const Stmt *s) {
return StreamState(Escaped, s);
@ -59,14 +59,14 @@ struct StreamState {
class StreamChecker : public Checker<eval::Call,
check::DeadSymbols > {
mutable IdentifierInfo *II_fopen, *II_tmpfile, *II_fclose, *II_fread,
*II_fwrite,
*II_fseek, *II_ftell, *II_rewind, *II_fgetpos, *II_fsetpos,
*II_fwrite,
*II_fseek, *II_ftell, *II_rewind, *II_fgetpos, *II_fsetpos,
*II_clearerr, *II_feof, *II_ferror, *II_fileno;
mutable std::unique_ptr<BuiltinBug> BT_nullfp, BT_illegalwhence,
BT_doubleclose, BT_ResourceLeak;
public:
StreamChecker()
StreamChecker()
: II_fopen(nullptr), II_tmpfile(nullptr), II_fclose(nullptr),
II_fread(nullptr), II_fwrite(nullptr), II_fseek(nullptr),
II_ftell(nullptr), II_rewind(nullptr), II_fgetpos(nullptr),
@ -93,10 +93,10 @@ private:
void Fileno(CheckerContext &C, const CallExpr *CE) const;
void OpenFileAux(CheckerContext &C, const CallExpr *CE) const;
ProgramStateRef CheckNullStream(SVal SV, ProgramStateRef state,
ProgramStateRef CheckNullStream(SVal SV, ProgramStateRef state,
CheckerContext &C) const;
ProgramStateRef CheckDoubleClose(const CallExpr *CE, ProgramStateRef state,
ProgramStateRef CheckDoubleClose(const CallExpr *CE, ProgramStateRef state,
CheckerContext &C) const;
};
@ -216,13 +216,13 @@ void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const {
C.blockCount())
.castAs<DefinedSVal>();
state = state->BindExpr(CE, C.getLocationContext(), RetVal);
ConstraintManager &CM = C.getConstraintManager();
// Bifurcate the state into two: one with a valid FILE* pointer, the other
// with a NULL.
ProgramStateRef stateNotNull, stateNull;
std::tie(stateNotNull, stateNull) = CM.assumeDual(state, RetVal);
if (SymbolRef Sym = RetVal.getAsSymbol()) {
// if RetVal is not NULL, set the symbol's state to Opened.
stateNotNull =
@ -368,13 +368,13 @@ ProgramStateRef StreamChecker::CheckDoubleClose(const CallExpr *CE,
state->getSVal(CE->getArg(0), C.getLocationContext()).getAsSymbol();
if (!Sym)
return state;
const StreamState *SS = state->get<StreamMap>(Sym);
// If the file stream is not tracked, return.
if (!SS)
return state;
// Check: Double close a File Descriptor could cause undefined behaviour.
// Conforming to man-pages
if (SS->isClosed()) {
@ -389,7 +389,7 @@ ProgramStateRef StreamChecker::CheckDoubleClose(const CallExpr *CE,
}
return nullptr;
}
// Close the File Descriptor.
return state->set<StreamMap>(Sym, StreamState::getClosed(CE));
}

View File

@ -30,7 +30,7 @@ class UndefBranchChecker : public Checker<check::BranchCondition> {
ProgramStateRef St;
const LocationContext *LCtx;
FindUndefExpr(ProgramStateRef S, const LocationContext *L)
FindUndefExpr(ProgramStateRef S, const LocationContext *L)
: St(S), LCtx(L) {}
const Expr *FindExpr(const Expr *Ex) {
@ -45,7 +45,7 @@ class UndefBranchChecker : public Checker<check::BranchCondition> {
return Ex;
}
bool MatchesCriteria(const Expr *Ex) {
bool MatchesCriteria(const Expr *Ex) {
return St->getSVal(Ex, LCtx).isUndef();
}
};

View File

@ -83,7 +83,7 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE,
SmallString<128> buf;
llvm::raw_svector_ostream os(buf);
os << "Variable '" << VD->getName()
os << "Variable '" << VD->getName()
<< "' is uninitialized when captured by block";
auto R = llvm::make_unique<BugReport>(*BT, os.str(), N);

View File

@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This defines UndefResultChecker, a builtin check in ExprEngine that
// This defines UndefResultChecker, a builtin check in ExprEngine that
// performs checks for undefined results of non-assignment binary operators.
//
//===----------------------------------------------------------------------===//
@ -25,7 +25,7 @@ using namespace clang;
using namespace ento;
namespace {
class UndefResultChecker
class UndefResultChecker
: public Checker< check::PostStmt<BinaryOperator> > {
mutable std::unique_ptr<BugType> BT;
@ -53,7 +53,7 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
ExplodedNode *N = C.generateSink();
if (!N)
return;
if (!BT)
BT.reset(
new BuiltinBug(this, "Result of operation is garbage or undefined"));
@ -62,7 +62,7 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
llvm::raw_svector_ostream OS(sbuf);
const Expr *Ex = nullptr;
bool isLeft = true;
if (state->getSVal(B->getLHS(), LCtx).isUndef()) {
Ex = B->getLHS()->IgnoreParenCasts();
isLeft = true;
@ -71,13 +71,13 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
Ex = B->getRHS()->IgnoreParenCasts();
isLeft = false;
}
if (Ex) {
OS << "The " << (isLeft ? "left" : "right")
<< " operand of '"
<< BinaryOperator::getOpcodeStr(B->getOpcode())
<< "' is a garbage value";
}
}
else {
// Neither operand was undefined, but the result is undefined.
OS << "The result of the '"
@ -91,7 +91,7 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
}
else
bugreporter::trackNullOrUndefValue(N, B, *report);
C.emitReport(std::move(report));
}
}

View File

@ -32,7 +32,7 @@ public:
};
} // end anonymous namespace
void
void
UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,
CheckerContext &C) const {
const Expr *Index = A->getIdx();

View File

@ -114,7 +114,7 @@ void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
// The definition of O_CREAT is platform specific. We need a better way
// of querying this information from the checking environment.
if (!Val_O_CREAT.hasValue()) {
if (C.getASTContext().getTargetInfo().getTriple().getVendor()
if (C.getASTContext().getTargetInfo().getTriple().getVendor()
== llvm::Triple::Apple)
Val_O_CREAT = 0x0200;
else {
@ -220,7 +220,7 @@ static bool IsZeroByteAllocation(ProgramStateRef state,
ProgramStateRef *falseState) {
std::tie(*trueState, *falseState) =
state->assume(argVal.castAs<DefinedSVal>());
return (*falseState && !*trueState);
}
@ -239,7 +239,7 @@ bool UnixAPIChecker::ReportZeroByteAllocation(CheckerContext &C,
"Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)");
SmallString<256> S;
llvm::raw_svector_ostream os(S);
llvm::raw_svector_ostream os(S);
os << "Call to '" << fn_name << "' has an allocation size of 0 bytes";
auto report = llvm::make_unique<BugReport>(*BT_mallocZero, os.str(), N);
@ -272,13 +272,13 @@ void UnixAPIChecker::BasicAllocationCheck(CheckerContext &C,
// Is the value perfectly constrained to zero?
if (IsZeroByteAllocation(state, argVal, &trueState, &falseState)) {
(void) ReportZeroByteAllocation(C, falseState, arg, fn);
(void) ReportZeroByteAllocation(C, falseState, arg, fn);
return;
}
// Assume the value is non-zero going forward.
assert(trueState);
if (trueState != state)
C.addTransition(trueState);
C.addTransition(trueState);
}
void UnixAPIChecker::CheckCallocZero(CheckerContext &C,

View File

@ -54,7 +54,7 @@ void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G,
BugReporter &B,
ExprEngine &Eng) const {
CFGBlocksSet reachable, visited;
if (Eng.hasWorkRemaining())
return;
@ -88,7 +88,7 @@ void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G,
// Bail out if we didn't get the CFG or the ParentMap.
if (!D || !C || !PM)
return;
// Don't do anything for template instantiations. Proving that code
// in a template instantiation is unreachable means proving that it is
// unreachable in all instantiations.

View File

@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This defines VLASizeChecker, a builtin check in ExprEngine that
// This defines VLASizeChecker, a builtin check in ExprEngine that
// performs checks for declaration of VLA of undefined or zero size.
// In addition, VLASizeChecker is responsible for defining the extent
// of the MemRegion that represents a VLA.
@ -82,7 +82,7 @@ void VLASizeChecker::reportBug(VLASize_Kind Kind,
void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
if (!DS->isSingleDecl())
return;
const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
if (!VD)
return;
@ -106,7 +106,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
// warned about that already.
if (sizeV.isUnknown())
return;
// Check if the size is tainted.
if (state->isTainted(sizeV)) {
reportBug(VLA_Tainted, SE, nullptr, C);
@ -123,7 +123,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
reportBug(VLA_Zero, SE, stateZero, C);
return;
}
// From this point on, assume that the size is not zero.
state = stateNotZero;

View File

@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines a checker that checks virtual function calls during
// This file defines a checker that checks virtual function calls during
// construction or destruction of C++ objects.
//
//===----------------------------------------------------------------------===//
@ -37,13 +37,13 @@ class WalkAST : public StmtVisitor<WalkAST> {
/// A vector representing the worklist which has a chain of CallExprs.
DFSWorkList WList;
// PreVisited : A CallExpr to this FunctionDecl is in the worklist, but the
// body has not been visited yet.
// PostVisited : A CallExpr to this FunctionDecl is in the worklist, and the
// body has been visited.
enum Kind { NotVisited,
PreVisited, /**< A CallExpr to this FunctionDecl is in the
PreVisited, /**< A CallExpr to this FunctionDecl is in the
worklist, but the body has not yet been
visited. */
PostVisited /**< A CallExpr to this FunctionDecl is in the
@ -57,7 +57,7 @@ class WalkAST : public StmtVisitor<WalkAST> {
/// generating bug reports. This is null while visiting the body of a
/// constructor or destructor.
const CallExpr *visitingCallExpr;
public:
WalkAST(const CheckerBase *checker, BugReporter &br,
AnalysisDeclContext *ac)
@ -70,7 +70,7 @@ public:
void Enqueue(WorkListUnit WLUnit) {
const FunctionDecl *FD = WLUnit->getDirectCallee();
if (!FD || !FD->getBody())
return;
return;
Kind &K = VisitedFunctions[FD];
if (K != NotVisited)
return;
@ -81,9 +81,9 @@ public:
/// This method returns an item from the worklist without removing it.
WorkListUnit Dequeue() {
assert(!WList.empty());
return WList.back();
return WList.back();
}
void Execute() {
while (hasWork()) {
WorkListUnit WLUnit = Dequeue();
@ -95,7 +95,7 @@ public:
// Visit the body.
SaveAndRestore<const CallExpr *> SaveCall(visitingCallExpr, WLUnit);
Visit(FD->getBody());
// Mark the function as being PostVisited to indicate we have
// scanned the body.
VisitedFunctions[FD] = PostVisited;
@ -114,7 +114,7 @@ public:
void VisitCXXMemberCallExpr(CallExpr *CE);
void VisitStmt(Stmt *S) { VisitChildren(S); }
void VisitChildren(Stmt *S);
void ReportVirtualCall(const CallExpr *CE, bool isPure);
};
@ -138,7 +138,7 @@ void WalkAST::VisitCallExpr(CallExpr *CE) {
void WalkAST::VisitCXXMemberCallExpr(CallExpr *CE) {
VisitChildren(CE);
bool callIsNonVirtual = false;
// Several situations to elide for checking.
if (MemberExpr *CME = dyn_cast<MemberExpr>(CE->getCallee())) {
// If the member access is fully qualified (i.e., X::F), then treat
@ -170,7 +170,7 @@ void WalkAST::VisitCXXMemberCallExpr(CallExpr *CE) {
void WalkAST::ReportVirtualCall(const CallExpr *CE, bool isPure) {
SmallString<100> buf;
llvm::raw_svector_ostream os(buf);
os << "Call Path : ";
// Name of current visiting CallExpr.
os << *CE->getDirectCallee();
@ -190,7 +190,7 @@ void WalkAST::ReportVirtualCall(const CallExpr *CE, bool isPure) {
PathDiagnosticLocation CELoc =
PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
SourceRange R = CE->getCallee()->getSourceRange();
if (isPure) {
os << "\n" << "Call pure virtual functions during construction or "
<< "destruction may leads undefined behaviour";

View File

@ -18,7 +18,7 @@ AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
const LangOptions &lang,
const PathDiagnosticConsumers &PDC,
StoreManagerCreator storemgr,
ConstraintManagerCreator constraintmgr,
ConstraintManagerCreator constraintmgr,
CheckerManager *checkerMgr,
AnalyzerOptions &Options,
CodeInjector *injector)

View File

@ -65,7 +65,7 @@ IPAKind AnalyzerOptions::getIPAMode() {
// Set the member variable.
IPAMode = IPAConfig;
}
return IPAMode;
}

View File

@ -26,7 +26,7 @@ class CountKey {
unsigned BlockID;
public:
CountKey(const StackFrameContext *CS, unsigned ID)
CountKey(const StackFrameContext *CS, unsigned ID)
: CallSite(CS), BlockID(ID) {}
bool operator==(const CountKey &RHS) const {
@ -55,7 +55,7 @@ static inline CountMap::Factory& GetFactory(void *F) {
return *static_cast<CountMap::Factory*>(F);
}
unsigned BlockCounter::getNumVisited(const StackFrameContext *CallSite,
unsigned BlockCounter::getNumVisited(const StackFrameContext *CallSite,
unsigned BlockID) const {
CountMap M = GetMap(Data);
CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID));
@ -71,10 +71,10 @@ BlockCounter::Factory::~Factory() {
}
BlockCounter
BlockCounter::Factory::IncrementCount(BlockCounter BC,
BlockCounter::Factory::IncrementCount(BlockCounter BC,
const StackFrameContext *CallSite,
unsigned BlockID) {
return BlockCounter(GetFactory(F).add(GetMap(BC.Data),
return BlockCounter(GetFactory(F).add(GetMap(BC.Data),
CountKey(CallSite, BlockID),
BC.getNumVisited(CallSite, BlockID)+1).getRoot());
}

View File

@ -81,13 +81,13 @@ eventsDescribeSameCondition(PathDiagnosticEventPiece *X,
// those that came from TrackConstraintBRVisitor.
const void *tagPreferred = ConditionBRVisitor::getTag();
const void *tagLesser = TrackConstraintBRVisitor::getTag();
if (X->getLocation() != Y->getLocation())
return nullptr;
if (X->getTag() == tagPreferred && Y->getTag() == tagLesser)
return X;
if (Y->getTag() == tagPreferred && X->getTag() == tagLesser)
return Y;
@ -110,7 +110,7 @@ static void removeRedundantMsgs(PathPieces &path) {
for (unsigned i = 0; i < N; ++i) {
IntrusiveRefCntPtr<PathDiagnosticPiece> piece(path.front());
path.pop_front();
switch (piece->getKind()) {
case clang::ento::PathDiagnosticPiece::Call:
removeRedundantMsgs(cast<PathDiagnosticCallPiece>(piece)->path);
@ -123,7 +123,7 @@ static void removeRedundantMsgs(PathPieces &path) {
case clang::ento::PathDiagnosticPiece::Event: {
if (i == N-1)
break;
if (PathDiagnosticEventPiece *nextEvent =
dyn_cast<PathDiagnosticEventPiece>(path.front().get())) {
PathDiagnosticEventPiece *event =
@ -157,13 +157,13 @@ static bool removeUnneededCalls(PathPieces &pieces, BugReport *R,
LocationContextMap &LCM) {
bool containsSomethingInteresting = false;
const unsigned N = pieces.size();
for (unsigned i = 0 ; i < N ; ++i) {
// Remove the front piece from the path. If it is still something we
// want to keep once we are done, we will push it back on the end.
IntrusiveRefCntPtr<PathDiagnosticPiece> piece(pieces.front());
pieces.pop_front();
switch (piece->getKind()) {
case PathDiagnosticPiece::Call: {
PathDiagnosticCallPiece *call = cast<PathDiagnosticCallPiece>(piece);
@ -176,7 +176,7 @@ static bool removeUnneededCalls(PathPieces &pieces, BugReport *R,
if (!removeUnneededCalls(call->path, R, LCM))
continue;
containsSomethingInteresting = true;
break;
}
@ -189,7 +189,7 @@ static bool removeUnneededCalls(PathPieces &pieces, BugReport *R,
}
case PathDiagnosticPiece::Event: {
PathDiagnosticEventPiece *event = cast<PathDiagnosticEventPiece>(piece);
// We never throw away an event, but we do throw it away wholesale
// as part of a path if we throw the entire path away.
containsSomethingInteresting |= !event->isPrunable();
@ -198,10 +198,10 @@ static bool removeUnneededCalls(PathPieces &pieces, BugReport *R,
case PathDiagnosticPiece::ControlFlow:
break;
}
pieces.push_back(piece);
}
return containsSomethingInteresting;
}
@ -213,7 +213,7 @@ static bool hasImplicitBody(const Decl *D) {
}
/// Recursively scan through a path and make sure that all call pieces have
/// valid locations.
/// valid locations.
static void
adjustCallLocations(PathPieces &Pieces,
PathDiagnosticLocation *LastCallLocation = nullptr) {
@ -323,7 +323,7 @@ class PathDiagnosticBuilder : public BugReporterContext {
NodeMapClosure NMC;
public:
const LocationContext *LC;
PathDiagnosticBuilder(GRBugReporter &br,
BugReport *r, InterExplodedGraphMap &Backmap,
PathDiagnosticConsumer *pdc)
@ -339,7 +339,7 @@ public:
BugReport *getBugReport() { return R; }
Decl const &getCodeDecl() { return R->getErrorNode()->getCodeDecl(); }
ParentMap& getParentMap() { return LC->getParentMap(); }
const Stmt *getParent(const Stmt *S) {
@ -957,7 +957,7 @@ static PathDiagnosticLocation cleanUpLocation(PathDiagnosticLocation L,
if (firstCharOnly)
L = PathDiagnosticLocation::createSingleLocation(L);
return L;
}
@ -1001,7 +1001,7 @@ public:
~EdgeBuilder() {
while (!CLocs.empty()) popLocation();
// Finally, add an initial edge from the start location of the first
// statement (if it doesn't already exist).
PathDiagnosticLocation L = PathDiagnosticLocation::createDeclBegin(
@ -1016,7 +1016,7 @@ public:
popLocation();
PrevLoc = PathDiagnosticLocation();
}
void addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd = false,
bool IsPostJump = false);
@ -1101,7 +1101,7 @@ void EdgeBuilder::rawAddEdge(PathDiagnosticLocation NewLoc) {
PrevLoc = NewLoc;
return;
}
if (NewLocClean.asLocation() == PrevLocClean.asLocation())
return;
@ -1242,7 +1242,7 @@ static void reversePropagateIntererstingSymbols(BugReport &R,
SVal V = State->getSVal(Ex, LCtx);
if (!(R.isInteresting(V) || IE.count(Ex)))
return;
switch (Ex->getStmtClass()) {
default:
if (!isa<CastExpr>(Ex))
@ -1260,7 +1260,7 @@ static void reversePropagateIntererstingSymbols(BugReport &R,
break;
}
}
R.markInteresting(V);
}
@ -1275,7 +1275,7 @@ static void reversePropagateInterestingSymbols(BugReport &R,
const Stmt *CallSite = Callee->getCallSite();
if (const CallExpr *CE = dyn_cast_or_null<CallExpr>(CallSite)) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeCtx->getDecl())) {
FunctionDecl::param_const_iterator PI = FD->param_begin(),
FunctionDecl::param_const_iterator PI = FD->param_begin(),
PE = FD->param_end();
CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end();
for (; AI != AE && PI != PE; ++AI, ++PI) {
@ -1406,7 +1406,7 @@ static bool GenerateExtensivePathDiagnostic(
N->getState().get(), Ex,
N->getLocationContext());
}
if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) {
const Stmt *S = CE->getCalleeContext()->getCallSite();
if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) {
@ -1414,7 +1414,7 @@ static bool GenerateExtensivePathDiagnostic(
N->getState().get(), Ex,
N->getLocationContext());
}
PathDiagnosticCallPiece *C =
PathDiagnosticCallPiece::construct(N, *CE, SM);
LCM[&C->path] = CE->getCalleeContext();
@ -1427,7 +1427,7 @@ static bool GenerateExtensivePathDiagnostic(
CallStack.push_back(StackDiagPair(C, N));
break;
}
// Pop the call hierarchy if we are done walking the contents
// of a function call.
if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
@ -1436,7 +1436,7 @@ static bool GenerateExtensivePathDiagnostic(
PathDiagnosticLocation pos =
PathDiagnosticLocation::createBegin(D, SM);
EB.addEdge(pos);
// Flush all locations, and pop the active path.
bool VisitedEntireCall = PD.isWithinCall();
EB.flushLocations();
@ -1466,7 +1466,7 @@ static bool GenerateExtensivePathDiagnostic(
}
break;
}
// Note that is important that we update the LocationContext
// after looking at CallExits. CallExit basically adds an
// edge in the *caller*, so we don't want to update the LocationContext
@ -1486,7 +1486,7 @@ static bool GenerateExtensivePathDiagnostic(
CalleeCtx, CallerCtx);
}
}
// Are we jumping to the head of a loop? Add a special diagnostic.
if (const Stmt *Loop = BE->getSrc()->getLoopTarget()) {
PathDiagnosticLocation L(Loop, SM, PDB.LC);
@ -1552,11 +1552,11 @@ static bool GenerateExtensivePathDiagnostic(
else
EB.addExtendedContext(PDB.getEnclosingStmtLocation(stmt).asStmt());
}
break;
}
} while (0);
if (!NextNode)
@ -2410,7 +2410,7 @@ static bool optimizeEdges(PathPieces &path, SourceManager &SM,
// Trim edges on expressions that are consumed by
// the parent expression.
if (isa<Expr>(s1End) && PM.isConsumedExpr(cast<Expr>(s1End))) {
removeEdge = true;
removeEdge = true;
}
// Trim edges where a lexical containment doesn't exist.
// For example:
@ -2557,7 +2557,7 @@ BugReport::~BugReport() {
const Decl *BugReport::getDeclWithIssue() const {
if (DeclWithIssue)
return DeclWithIssue;
const ExplodedNode *N = getErrorNode();
if (!N)
return nullptr;
@ -2973,14 +2973,14 @@ static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) {
for (PathPieces::const_iterator I = path.begin(), E = path.end();
I!=E; ++I) {
PathDiagnosticPiece *piece = I->get();
// Recursively compact calls.
if (PathDiagnosticCallPiece *call=dyn_cast<PathDiagnosticCallPiece>(piece)){
CompactPathDiagnostic(call->path, SM);
}
// Get the location of the PathDiagnosticPiece.
const FullSourceLoc Loc = piece->getLocation().asLocation();
@ -3126,7 +3126,7 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD,
PD.resetPath();
origReportConfigToken = R->getConfigurationChangeToken();
// Generate the very last diagnostic piece - the piece is visible before
// Generate the very last diagnostic piece - the piece is visible before
// the trace is expanded.
std::unique_ptr<PathDiagnosticPiece> LastPiece;
for (BugReport::visitor_iterator I = visitors.begin(), E = visitors.end();
@ -3234,7 +3234,7 @@ void BugReporter::emitReport(std::unique_ptr<BugReport> R) {
!DeclCtx->isBodyAutosynthesizedFromModelFile())
return;
}
bool ValidSourceLoc = R->getLocation(getSourceManager()).isValid();
assert(ValidSourceLoc);
// If we mess up in a release build, we'd still prefer to just drop the bug
@ -3269,10 +3269,10 @@ namespace {
struct FRIEC_WLItem {
const ExplodedNode *N;
ExplodedNode::const_succ_iterator I, E;
FRIEC_WLItem(const ExplodedNode *n)
: N(n), I(N->succ_begin()), E(N->succ_end()) {}
};
};
}
static BugReport *
@ -3324,21 +3324,21 @@ FindReportInEquivalenceClass(BugReportEquivClass& EQ,
}
// At this point we know that 'N' is not a sink and it has at least one
// successor. Use a DFS worklist to find a non-sink end-of-path node.
// successor. Use a DFS worklist to find a non-sink end-of-path node.
typedef FRIEC_WLItem WLItem;
typedef SmallVector<WLItem, 10> DFSWorkList;
llvm::DenseMap<const ExplodedNode *, unsigned> Visited;
DFSWorkList WL;
WL.push_back(errorNode);
Visited[errorNode] = 1;
while (!WL.empty()) {
WLItem &WI = WL.back();
assert(!WI.N->succ_empty());
for (; WI.I != WI.E; ++WI.I) {
const ExplodedNode *Succ = *WI.I;
const ExplodedNode *Succ = *WI.I;
// End-of-path node?
if (Succ->succ_empty()) {
// If we found an end-of-path node that is not a sink.

View File

@ -169,7 +169,7 @@ public:
bool InEnableNullFPSuppression) {
if (!CallEvent::isCallStmt(S))
return;
// First, find when we processed the statement.
do {
if (Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>())
@ -192,11 +192,11 @@ public:
Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>();
if (!CEE)
return;
const StackFrameContext *CalleeContext = CEE->getCalleeContext();
if (CalleeContext->getCallSite() != S)
return;
// Check the return value.
ProgramStateRef State = Node->getState();
SVal RetVal = State->getSVal(S, Node->getLocationContext());
@ -281,7 +281,7 @@ public:
EnableNullFPSuppression);
return nullptr;
}
// If we're returning 0, we should track where that 0 came from.
bugreporter::trackNullOrUndefValue(N, RetE, BR, /*IsArg*/ false,
EnableNullFPSuppression);
@ -472,7 +472,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
InitE = PIP->getInitializer()->getInit();
}
}
// Otherwise, see if this is the store site:
// (1) Succ has this binding and Pred does not, i.e. this is
// where the binding first occurred.
@ -504,7 +504,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) {
if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
ProgramStateManager &StateMgr = BRC.getStateManager();
CallEventManager &CallMgr = StateMgr.getCallEventManager();
@ -681,7 +681,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
else
os << "Assigning value";
}
if (R->canPrintPretty()) {
os << " to ";
R->printPretty(os);
@ -931,7 +931,7 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
if (!N)
return false;
}
ProgramStateRef state = N->getState();
// The message send could be nil due to the receiver being nil.
@ -959,7 +959,7 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
assert(LVNode && "Unable to find the lvalue node.");
ProgramStateRef LVState = LVNode->getState();
SVal LVal = LVState->getSVal(Inner, LVNode->getLocationContext());
if (LVState->isNull(LVal).isConstrainedTrue()) {
// In case of C++ references, we want to differentiate between a null
// reference and reference to null pointer.
@ -1162,11 +1162,11 @@ PathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
const ExplodedNode *Prev,
BugReporterContext &BRC,
BugReport &BR) {
ProgramPoint progPoint = N->getLocation();
ProgramStateRef CurrentState = N->getState();
ProgramStateRef PrevState = Prev->getState();
// Compare the GDMs of the state, because that is where constraints
// are managed. Note that ensure that we only look at nodes that
// were generated by the analyzer engine proper, not checkers.
@ -1177,16 +1177,16 @@ PathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
// If an assumption was made on a branch, it should be caught
// here by looking at the state transition.
if (Optional<BlockEdge> BE = progPoint.getAs<BlockEdge>()) {
const CFGBlock *srcBlk = BE->getSrc();
const CFGBlock *srcBlk = BE->getSrc();
if (const Stmt *term = srcBlk->getTerminator())
return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
return nullptr;
}
if (Optional<PostStmt> PS = progPoint.getAs<PostStmt>()) {
// FIXME: Assuming that BugReporter is a GRBugReporter is a layering
// violation.
const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
cast<GRBugReporter>(BRC.getBugReporter()).
getEngine().geteagerlyAssumeBinOpBifurcationTags();
@ -1222,7 +1222,7 @@ ConditionBRVisitor::VisitTerminator(const Stmt *Term,
case Stmt::ConditionalOperatorClass:
Cond = cast<ConditionalOperator>(Term)->getCond();
break;
}
}
assert(Cond);
assert(srcBlk->succ_size() == 2);
@ -1236,9 +1236,9 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
BugReporterContext &BRC,
BugReport &R,
const ExplodedNode *N) {
const Expr *Ex = Cond;
while (true) {
Ex = Ex->IgnoreParenCasts();
switch (Ex->getStmtClass()) {
@ -1294,7 +1294,7 @@ bool ConditionBRVisitor::patternMatch(const Expr *Ex, raw_ostream &Out,
Out << '\'';
return quotes;
}
if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(Ex)) {
QualType OriginalTy = OriginalExpr->getType();
if (OriginalTy->isPointerType()) {
@ -1309,11 +1309,11 @@ bool ConditionBRVisitor::patternMatch(const Expr *Ex, raw_ostream &Out,
return false;
}
}
Out << IL->getValue();
return false;
}
return false;
}
@ -1324,10 +1324,10 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
BugReporterContext &BRC,
BugReport &R,
const ExplodedNode *N) {
bool shouldInvert = false;
Optional<bool> shouldPrune;
SmallString<128> LhsString, RhsString;
{
llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
@ -1335,10 +1335,10 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
shouldPrune);
const bool isVarRHS = patternMatch(BExpr->getRHS(), OutRHS, BRC, R, N,
shouldPrune);
shouldInvert = !isVarLHS && isVarRHS;
shouldInvert = !isVarLHS && isVarRHS;
}
BinaryOperator::Opcode Op = BExpr->getOpcode();
if (BinaryOperator::isAssignmentOp(Op)) {
@ -1380,7 +1380,7 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
default:
return nullptr;
}
switch (Op) {
case BO_EQ:
Out << "equal to ";
@ -1392,7 +1392,7 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
Out << BinaryOperator::getOpcodeStr(Op) << ' ';
break;
}
Out << (shouldInvert ? LhsString : RhsString);
const LocationContext *LCtx = N->getLocationContext();
PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
@ -1416,7 +1416,7 @@ ConditionBRVisitor::VisitConditionVariable(StringRef LhsString,
SmallString<256> buf;
llvm::raw_svector_ostream Out(buf);
Out << "Assuming " << LhsString << " is ";
QualType Ty = CondVarExpr->getType();
if (Ty->isPointerType())
@ -1444,10 +1444,10 @@ ConditionBRVisitor::VisitConditionVariable(StringRef LhsString,
}
}
}
return event;
}
PathDiagnosticPiece *
ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
const DeclRefExpr *DR,
@ -1462,11 +1462,11 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
SmallString<256> Buf;
llvm::raw_svector_ostream Out(Buf);
Out << "Assuming '" << VD->getDeclName() << "' is ";
QualType VDTy = VD->getType();
if (VDTy->isPointerType())
Out << (tookTrue ? "non-null" : "null");
else if (VDTy->isObjCObjectPointerType())
@ -1480,7 +1480,7 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
PathDiagnosticEventPiece *event =
new PathDiagnosticEventPiece(Loc, Out.str());
const ProgramState *state = N->getState().get();
if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
if (report.isInteresting(R))
@ -1615,13 +1615,13 @@ UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
// Function can only change the value passed in by address.
continue;
}
// If it is a const pointer value, the function does not intend to
// change the value.
if (T->getPointeeType().isConstQualified())
continue;
// Mark the call site (LocationContext) as interesting if the value of the
// Mark the call site (LocationContext) as interesting if the value of the
// argument is undefined or '0'/'NULL'.
SVal BoundVal = State->getSVal(R);
if (BoundVal.isUndef() || BoundVal.isZeroConstant()) {

View File

@ -96,7 +96,7 @@ bool CallEvent::hasNonZeroCallbackArg() const {
if (isCallbackArg(getArgSVal(Idx), *I))
return true;
}
return false;
}
@ -159,7 +159,7 @@ ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
// below for efficiency.
if (PreserveArgs.count(Idx))
if (const MemRegion *MR = getArgSVal(Idx).getAsRegion())
ETraits.setTrait(MR->StripCasts(),
ETraits.setTrait(MR->StripCasts(),
RegionAndSymbolInvalidationTraits::TK_PreserveContents);
// TODO: Factor this out + handle the lower level const pointers.
@ -184,7 +184,7 @@ ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
}
const Decl *D = getDecl();
assert(D && "Cannot get a program point without a statement or decl");
assert(D && "Cannot get a program point without a statement or decl");
SourceLocation Loc = getSourceRange().getBegin();
if (IsPreVisit)
@ -265,7 +265,7 @@ QualType CallEvent::getDeclaredResultType(const Decl *D) {
return QualType();
}
llvm_unreachable("unknown callable kind");
}
@ -336,7 +336,7 @@ bool AnyFunctionCall::argumentsMayEscape() const {
if (!II)
return false;
// This set of "escaping" APIs is
// This set of "escaping" APIs is
// - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
// value into thread local storage. The value can later be retrieved with
@ -455,7 +455,7 @@ RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
// However, we should at least be able to search up and down our own class
// hierarchy, and some real bugs have been caught by checking this.
assert(!RD->isDerivedFrom(MD->getParent()) && "Couldn't find known method");
// FIXME: This is checking that our DynamicTypeInfo is at least as good as
// the static type. However, because we currently don't update
// DynamicTypeInfo when an object is cast, we can't actually be sure the
@ -525,7 +525,7 @@ RuntimeDefinition CXXMemberCall::getRuntimeDefinition() const {
if (const MemberExpr *ME = dyn_cast<MemberExpr>(getOriginExpr()->getCallee()))
if (ME->hasQualifier())
return AnyFunctionCall::getRuntimeDefinition();
return CXXInstanceCall::getRuntimeDefinition();
}
@ -628,7 +628,7 @@ SVal ObjCMethodCall::getReceiverSVal() const {
// FIXME: Is this the best way to handle class receivers?
if (!isInstanceMessage())
return UnknownVal();
if (const Expr *RecE = getOriginExpr()->getInstanceReceiver())
return getSVal(RecE);
@ -709,7 +709,7 @@ ObjCMessageKind ObjCMethodCall::getMessageKind() const {
return K;
}
}
const_cast<ObjCMethodCall *>(this)->Data
= ObjCMessageDataTy(nullptr, 1).getOpaqueValue();
assert(getMessageKind() == OCM_Message);
@ -730,7 +730,7 @@ bool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
getState()->getStateManager().getContext().getSourceManager();
// If the class interface is declared inside the main file, assume it is not
// subcassed.
// subcassed.
// TODO: It could actually be subclassed if the subclass is private as well.
// This is probably very rare.
SourceLocation InterfLoc = IDecl->getEndOfDefinitionLoc();

View File

@ -23,7 +23,7 @@ StringRef CheckerBase::getTagDescription() const {
CheckName CheckerBase::getCheckName() const { return Name; }
CheckerProgramPointTag::CheckerProgramPointTag(StringRef CheckerName,
CheckerProgramPointTag::CheckerProgramPointTag(StringRef CheckerName,
StringRef Msg)
: SimpleProgramPointTag(CheckerName, Msg) {}

View File

@ -357,9 +357,9 @@ void CheckerManager::runCheckersForEndFunction(NodeBuilderContext &BC,
ExplodedNodeSet &Dst,
ExplodedNode *Pred,
ExprEngine &Eng) {
// We define the builder outside of the loop bacause if at least one checkers
// creates a sucsessor for Pred, we do not need to generate an
// creates a sucsessor for Pred, we do not need to generate an
// autotransition for it.
NodeBuilder Bldr(Pred, Dst, BC);
for (unsigned i = 0, e = EndFunctionCheckers.size(); i != e; ++i) {
@ -467,7 +467,7 @@ bool CheckerManager::wantsRegionChangeUpdate(ProgramStateRef state) {
}
/// \brief Run checkers for region changes.
ProgramStateRef
ProgramStateRef
CheckerManager::runCheckersForRegionChanges(ProgramStateRef state,
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
@ -478,7 +478,7 @@ CheckerManager::runCheckersForRegionChanges(ProgramStateRef state,
// bail out.
if (!state)
return nullptr;
state = RegionChangesCheckers[i].CheckFn(state, invalidated,
state = RegionChangesCheckers[i].CheckFn(state, invalidated,
ExplicitRegions, Regions, Call);
}
return state;
@ -506,7 +506,7 @@ CheckerManager::runCheckersForPointerEscape(ProgramStateRef State,
}
/// \brief Run checkers for handling assumptions on symbolic values.
ProgramStateRef
ProgramStateRef
CheckerManager::runCheckersForEvalAssume(ProgramStateRef state,
SVal Cond, bool Assumption) {
for (unsigned i = 0, e = EvalAssumeCheckers.size(); i != e; ++i) {
@ -558,7 +558,7 @@ void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst,
#endif
}
}
// If none of the checkers evaluated the call, ask ExprEngine to handle it.
if (!anyEvaluated) {
NodeBuilder B(Pred, Dst, Eng.getBuilderContext());

View File

@ -94,7 +94,7 @@ void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name,
}
}
void CheckerRegistry::initializeManager(CheckerManager &checkerMgr,
void CheckerRegistry::initializeManager(CheckerManager &checkerMgr,
SmallVectorImpl<CheckerOptInfo> &opts) const {
// Sort checkers for efficient collection.
std::sort(Checkers.begin(), Checkers.end(), checkerNameLT);

View File

@ -26,7 +26,7 @@ static DefinedSVal getLocFromSymbol(const ProgramStateRef &State,
}
ConditionTruthVal ConstraintManager::checkNull(ProgramStateRef State,
SymbolRef Sym) {
SymbolRef Sym) {
QualType Ty = Sym->getType();
DefinedSVal V = Loc::isLocType(Ty) ? getLocFromSymbol(State, Sym)
: nonloc::SymbolVal(Sym);

View File

@ -271,7 +271,7 @@ void CoreEngine::dispatchWorkItem(ExplodedNode* Pred, ProgramPoint Loc,
bool CoreEngine::ExecuteWorkListWithInitialState(const LocationContext *L,
unsigned Steps,
ProgramStateRef InitState,
ProgramStateRef InitState,
ExplodedNodeSet &Dst) {
bool DidNotFinish = ExecuteWorkList(L, Steps, InitState);
for (ExplodedGraph::eop_iterator I = G.eop_begin(), E = G.eop_end(); I != E;
@ -386,7 +386,7 @@ void CoreEngine::HandleBlockExit(const CFGBlock * B, ExplodedNode *Pred) {
}
return;
}
case Stmt::DoStmtClass:
HandleBranch(cast<DoStmt>(Term)->getCond(), Term, B, Pred);
return;
@ -456,7 +456,7 @@ void CoreEngine::HandleBlockExit(const CFGBlock * B, ExplodedNode *Pred) {
Pred->State, Pred);
}
void CoreEngine::HandleBranch(const Stmt *Cond, const Stmt *Term,
void CoreEngine::HandleBranch(const Stmt *Cond, const Stmt *Term,
const CFGBlock * B, ExplodedNode *Pred) {
assert(B->succ_size() == 2);
NodeBuilderContext Ctx(*this, B, Pred);
@ -491,7 +491,7 @@ void CoreEngine::HandleStaticInit(const DeclStmt *DS, const CFGBlock *B,
}
void CoreEngine::HandlePostStmt(const CFGBlock *B, unsigned StmtIdx,
void CoreEngine::HandlePostStmt(const CFGBlock *B, unsigned StmtIdx,
ExplodedNode *Pred) {
assert(B);
assert(!B->empty());

View File

@ -97,9 +97,9 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry,
const ReturnStmt *RS = cast<ReturnStmt>(S);
if (const Expr *RE = RS->getRetValue())
return getSVal(EnvironmentEntry(RE, LCtx), svalBuilder);
return UndefinedVal();
return UndefinedVal();
}
// Handle all other Stmt* using a lookup.
default:
return lookupExpr(EnvironmentEntry(S, LCtx));
@ -194,16 +194,16 @@ void Environment::print(raw_ostream &Out, const char *NL,
for (Environment::iterator I = begin(), E = end(); I != E; ++I) {
const EnvironmentEntry &En = I.getKey();
if (isFirst) {
Out << NL << NL
<< "Expressions:"
<< NL;
<< NL;
isFirst = false;
} else {
Out << NL;
}
const Stmt *S = En.getStmt();
assert(S != nullptr && "Expected non-null Stmt");

View File

@ -90,8 +90,8 @@ bool ExplodedGraph::shouldCollect(const ExplodedNode *node) {
// (7) The LocationContext is the same as the predecessor.
// (8) Expressions that are *not* lvalue expressions.
// (9) The PostStmt isn't for a non-consumed Stmt or Expr.
// (10) The successor is neither a CallExpr StmtPoint nor a CallEnter or
// PreImplicitCall (so that we would be able to find it when retrying a
// (10) The successor is neither a CallExpr StmtPoint nor a CallEnter or
// PreImplicitCall (so that we would be able to find it when retrying a
// call with no inlining).
// FIXME: It may be safe to reclaim PreCall and PostCall nodes as well.
@ -102,7 +102,7 @@ bool ExplodedGraph::shouldCollect(const ExplodedNode *node) {
const ExplodedNode *pred = *(node->pred_begin());
if (pred->succ_size() != 1)
return false;
const ExplodedNode *succ = *(node->succ_begin());
if (succ->pred_size() != 1)
return false;
@ -123,7 +123,7 @@ bool ExplodedGraph::shouldCollect(const ExplodedNode *node) {
// Conditions 5, 6, and 7.
ProgramStateRef state = node->getState();
ProgramStateRef pred_state = pred->getState();
ProgramStateRef pred_state = pred->getState();
if (state->store != pred_state->store || state->GDM != pred_state->GDM ||
progPoint.getLocationContext() != pred->getLocationContext())
return false;
@ -174,7 +174,7 @@ void ExplodedGraph::collectNode(ExplodedNode *node) {
FreeNodes.push_back(node);
Nodes.RemoveNode(node);
--NumNodes;
node->~ExplodedNode();
node->~ExplodedNode();
}
void ExplodedGraph::reclaimRecentlyAllocatedNodes() {

View File

@ -174,7 +174,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
}
}
}
return state;
}
@ -265,7 +265,7 @@ bool ExprEngine::wantsRegionChangeUpdate(ProgramStateRef state) {
return getCheckerManager().wantsRegionChangeUpdate(state);
}
ProgramStateRef
ProgramStateRef
ExprEngine::processRegionChanges(ProgramStateRef state,
const InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> Explicits,
@ -315,7 +315,7 @@ static bool shouldRemoveDeadBindings(AnalysisManager &AMgr,
const CFGStmt S,
const ExplodedNode *Pred,
const LocationContext *LC) {
// Are we never purging state values?
if (AMgr.options.AnalysisPurgeOpt == PurgeNone)
return false;
@ -327,7 +327,7 @@ static bool shouldRemoveDeadBindings(AnalysisManager &AMgr,
// Is this on a non-expression?
if (!isa<Expr>(S.getStmt()))
return true;
// Run before processing a call.
if (CallEvent::isCallStmt(S.getStmt()))
return true;
@ -512,7 +512,7 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init,
assert(Tmp.size() == 1 && "have not generated any new nodes yet");
assert(*Tmp.begin() == Pred && "have not generated any new nodes yet");
Tmp.clear();
PostInitializer PP(BMI, FieldLoc.getAsRegion(), stackFrame);
evalBind(Tmp, Init, Pred, FieldLoc, InitVal, /*isInit=*/true, &PP);
}
@ -775,7 +775,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
Engine.addAbortedBlock(node, currBldrCtx->getBlock());
break;
}
case Stmt::ParenExprClass:
llvm_unreachable("ParenExprs already handled.");
case Stmt::GenericSelectionExprClass:
@ -966,7 +966,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
ExplodedNodeSet preVisit;
getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
ExplodedNodeSet Tmp;
StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx);
@ -974,7 +974,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
QualType resultType = Ex->getType();
for (ExplodedNodeSet::iterator it = preVisit.begin(), et = preVisit.end();
it != et; ++it) {
it != et; ++it) {
ExplodedNode *N = *it;
const LocationContext *LCtx = N->getLocationContext();
SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
@ -983,10 +983,10 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
ProgramStateRef state = N->getState()->BindExpr(Ex, LCtx, result);
Bldr2.generateNode(S, N, state);
}
getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
Bldr.addNodes(Dst);
break;
break;
}
case Stmt::ArraySubscriptExprClass:
@ -1031,7 +1031,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
}
Bldr.takeNodes(Pred);
if (AMgr.options.eagerlyAssumeBinOpBifurcation &&
(B->isRelationalOp() || B->isEqualityOp())) {
ExplodedNodeSet Tmp;
@ -1076,7 +1076,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
Bldr.addNodes(Dst);
break;
}
case Stmt::CXXCatchStmtClass: {
Bldr.takeNodes(Pred);
VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst);
@ -1085,7 +1085,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
}
case Stmt::CXXTemporaryObjectExprClass:
case Stmt::CXXConstructExprClass: {
case Stmt::CXXConstructExprClass: {
Bldr.takeNodes(Pred);
VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst);
Bldr.addNodes(Dst);
@ -1107,7 +1107,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S);
getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
for (ExplodedNodeSet::iterator i = PreVisit.begin(),
for (ExplodedNodeSet::iterator i = PreVisit.begin(),
e = PreVisit.end(); i != e ; ++i)
VisitCXXDeleteExpr(CDE, *i, Dst);
@ -1173,18 +1173,18 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::CXXDynamicCastExprClass:
case Stmt::CXXReinterpretCastExprClass:
case Stmt::CXXConstCastExprClass:
case Stmt::CXXFunctionalCastExprClass:
case Stmt::CXXFunctionalCastExprClass:
case Stmt::ObjCBridgedCastExprClass: {
Bldr.takeNodes(Pred);
const CastExpr *C = cast<CastExpr>(S);
// Handle the previsit checks.
ExplodedNodeSet dstPrevisit;
getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, C, *this);
// Handle the expression itself.
ExplodedNodeSet dstExpr;
for (ExplodedNodeSet::iterator i = dstPrevisit.begin(),
e = dstPrevisit.end(); i != e ; ++i) {
e = dstPrevisit.end(); i != e ; ++i) {
VisitCast(C, C->getSubExpr(), *i, dstExpr);
}
@ -1201,7 +1201,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
Bldr.addNodes(Dst);
break;
}
case Stmt::InitListExprClass:
Bldr.takeNodes(Pred);
VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
@ -1296,7 +1296,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
Bldr.takeNodes(Pred);
ProgramStateRef state = Pred->getState();
const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S);
if (const Expr *Result = PE->getResultExpr()) {
if (const Expr *Result = PE->getResultExpr()) {
SVal V = state->getSVal(Result, Pred->getLocationContext());
Bldr.generateNode(S, Pred,
state->BindExpr(S, Pred->getLocationContext(), V));
@ -1377,7 +1377,7 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N,
/// Block entrance. (Update counters).
void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
NodeBuilderWithSinks &nodeBuilder,
NodeBuilderWithSinks &nodeBuilder,
ExplodedNode *Pred) {
PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
@ -1585,7 +1585,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
}
}
}
// If the condition is still unknown, give up.
if (X.isUnknownOrUndef()) {
builder.generateNode(PrevState, true, PredI);
@ -1752,7 +1752,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
DefinedOrUnknownSVal CondV = CondV_untested.castAs<DefinedOrUnknownSVal>();
ProgramStateRef DefaultSt = state;
iterator I = builder.begin(), EI = builder.end();
bool defaultIsFeasible = I == EI;
@ -1760,7 +1760,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
// Successor may be pruned out during CFG construction.
if (!I.getBlock())
continue;
const CaseStmt *Case = I.getCase();
// Evaluate the LHS of the case value.
@ -1851,7 +1851,7 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
// C permits "extern void v", and if you cast the address to a valid type,
// you can even do things with it. We simply pretend
// you can even do things with it. We simply pretend
assert(Ex->isGLValue() || VD->getType()->isVoidType());
SVal V = state->getLValue(VD, Pred->getLocationContext());
@ -1902,7 +1902,7 @@ void ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A,
const Expr *Base = A->getBase()->IgnoreParens();
const Expr *Idx = A->getIdx()->IgnoreParens();
ExplodedNodeSet checkerPreStmt;
getCheckerManager().runCheckersForPreStmt(checkerPreStmt, Pred, A, *this);
@ -2066,14 +2066,14 @@ ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
return State;
}
ProgramStateRef
ProgramStateRef
ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State,
const InvalidatedSymbols *Invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call,
RegionAndSymbolInvalidationTraits &ITraits) {
if (!Invalidated || Invalidated->empty())
return State;
@ -2084,7 +2084,7 @@ ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State,
PSK_EscapeOther,
&ITraits);
// If the symbols were invalidated by a call, we want to find out which ones
// If the symbols were invalidated by a call, we want to find out which ones
// were invalidated directly due to being arguments to the call.
InvalidatedSymbols SymbolsDirectlyInvalidated;
for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
@ -2144,13 +2144,13 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
Bldr.generateNode(L, state, Pred);
return;
}
for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
I!=E; ++I) {
ExplodedNode *PredI = *I;
ProgramStateRef state = PredI->getState();
state = processPointerEscapedOnBind(state, location, Val);
// When binding the value, pass on the hint that this is a initialization.
@ -2303,7 +2303,7 @@ void ExprEngine::evalLocation(ExplodedNodeSet &Dst,
// "p = 0" is not noted as "Null pointer value stored to 'p'" but
// instead "int *p" is noted as
// "Variable 'p' initialized to a null pointer value"
static SimpleProgramPointTag tag(TagProviderName, "Location");
Bldr.generateNode(NodeEx, Pred, state, &tag);
}
@ -2328,7 +2328,7 @@ void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
ExplodedNodeSet &Src,
const Expr *Ex) {
StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx);
for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
ExplodedNode *Pred = *I;
// Test if the previous node was as the same expression. This can happen
@ -2351,7 +2351,7 @@ void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
// First assume that the condition is true.
if (StateTrue) {
SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());
SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());
StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val);
Bldr.generateNode(Ex, Pred, StateTrue, tags.first);
}
@ -2643,10 +2643,10 @@ struct DOTGraphTraits<ExplodedNode*> :
<< " NodeID: " << (const void*) N << "\\|";
state->printDOT(Out);
Out << "\\l";
Out << "\\l";
if (const ProgramPointTag *tag = Loc.getTag()) {
Out << "\\|Tag: " << tag->getTagDescription();
Out << "\\|Tag: " << tag->getTagDescription();
Out << "\\l";
}
return Out.str();

View File

@ -25,23 +25,23 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
Expr *LHS = B->getLHS()->IgnoreParens();
Expr *RHS = B->getRHS()->IgnoreParens();
// FIXME: Prechecks eventually go in ::Visit().
ExplodedNodeSet CheckedSet;
ExplodedNodeSet Tmp2;
getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this);
// With both the LHS and RHS evaluated, process the operation itself.
for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
it != ei; ++it) {
ProgramStateRef state = (*it)->getState();
const LocationContext *LCtx = (*it)->getLocationContext();
SVal LeftV = state->getSVal(LHS, LCtx);
SVal RightV = state->getSVal(RHS, LCtx);
BinaryOperator::Opcode Op = B->getOpcode();
if (Op == BO_Assign) {
// EXPERIMENTAL: "Conjured" symbols.
// FIXME: Handle structs.
@ -57,7 +57,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
LeftV, RightV);
continue;
}
if (!B->isAssignmentOp()) {
StmtNodeBuilder Bldr(*it, Tmp2, *currBldrCtx);
@ -90,19 +90,19 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
// Process non-assignments except commas or short-circuited
// logical expressions (LAnd and LOr).
SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
if (Result.isUnknown()) {
Bldr.generateNode(B, *it, state);
continue;
}
}
state = state->BindExpr(B, LCtx, Result);
state = state->BindExpr(B, LCtx, Result);
Bldr.generateNode(B, *it, state);
continue;
}
assert (B->isCompoundAssignmentOp());
switch (Op) {
default:
llvm_unreachable("Invalid opcode for compound assignment.");
@ -117,43 +117,43 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
case BO_XorAssign: Op = BO_Xor; break;
case BO_OrAssign: Op = BO_Or; break;
}
// Perform a load (the LHS). This performs the checks for
// null dereferences, and so on.
ExplodedNodeSet Tmp;
SVal location = LeftV;
evalLoad(Tmp, B, LHS, *it, state, location);
for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E;
++I) {
state = (*I)->getState();
const LocationContext *LCtx = (*I)->getLocationContext();
SVal V = state->getSVal(LHS, LCtx);
// Get the computation type.
QualType CTy =
cast<CompoundAssignOperator>(B)->getComputationResultType();
CTy = getContext().getCanonicalType(CTy);
QualType CLHSTy =
cast<CompoundAssignOperator>(B)->getComputationLHSType();
CLHSTy = getContext().getCanonicalType(CLHSTy);
QualType LTy = getContext().getCanonicalType(LHS->getType());
// Promote LHS.
V = svalBuilder.evalCast(V, CLHSTy, LTy);
// Compute the result of the operation.
SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
B->getType(), CTy);
// EXPERIMENTAL: "Conjured" symbols.
// FIXME: Handle structs.
SVal LHSVal;
if (Result.isUnknown()) {
// The symbolic value is actually for the type of the left-hand side
// expression, not the computation type, as this is the value the
@ -168,42 +168,42 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
// computation type.
LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
}
// In C++, assignment and compound assignment operators return an
// In C++, assignment and compound assignment operators return an
// lvalue.
if (B->isGLValue())
state = state->BindExpr(B, LCtx, location);
else
state = state->BindExpr(B, LCtx, Result);
evalStore(Tmp2, B, LHS, *I, state, location, LHSVal);
}
}
// FIXME: postvisits eventually go in ::Visit()
getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
}
void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
CanQualType T = getContext().getCanonicalType(BE->getType());
// Get the value of the block itself.
SVal V = svalBuilder.getBlockPointer(BE->getBlockDecl(), T,
Pred->getLocationContext(),
currBldrCtx->blockCount());
ProgramStateRef State = Pred->getState();
// If we created a new MemRegion for the block, we should explicitly bind
// the captured variables.
if (const BlockDataRegion *BDR =
dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(),
E = BDR->referenced_vars_end();
for (; I != E; ++I) {
const MemRegion *capturedR = I.getCapturedRegion();
const MemRegion *originalR = I.getOriginalRegion();
@ -213,7 +213,7 @@ void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
}
}
}
ExplodedNodeSet Tmp;
StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
Bldr.generateNode(BE, Pred,
@ -224,12 +224,12 @@ void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
}
void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
ExplodedNodeSet dstPreStmt;
getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this);
if (CastE->getCastKind() == CK_LValueToRValue) {
for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
I!=E; ++I) {
@ -240,18 +240,18 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
}
return;
}
// All other casts.
// All other casts.
QualType T = CastE->getType();
QualType ExTy = Ex->getType();
if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
T = ExCast->getTypeAsWritten();
StmtNodeBuilder Bldr(dstPreStmt, Dst, *currBldrCtx);
for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
I != E; ++I) {
Pred = *I;
ProgramStateRef state = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
@ -316,8 +316,8 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
case CK_IntegralComplexToFloatingComplex:
case CK_CPointerToObjCPointerCast:
case CK_BlockPointerToObjCPointerCast:
case CK_AnyPointerToBlockPointerCast:
case CK_ObjCObjectLValueCast:
case CK_AnyPointerToBlockPointerCast:
case CK_ObjCObjectLValueCast:
case CK_ZeroToOCLEvent:
case CK_LValueBitCast: {
// Delegate to SValBuilder to process.
@ -371,7 +371,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
currBldrCtx->blockCount());
state = state->BindExpr(CastE, LCtx, NewSym);
} else
} else
// Else, bind to the derived region value.
state = state->BindExpr(CastE, LCtx, val);
}
@ -417,7 +417,7 @@ void ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
const Expr *Init = CL->getInitializer();
SVal V = State->getSVal(CL->getInitializer(), LCtx);
if (isa<CXXConstructExpr>(Init)) {
// No work needed. Just pass the value up to this expression.
} else {
@ -450,11 +450,11 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
Dst.insert(Pred);
return;
}
// FIXME: all pre/post visits should eventually be handled by ::Visit().
ExplodedNodeSet dstPreVisit;
getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
ExplodedNodeSet dstEvaluated;
StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
@ -485,7 +485,7 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
assert(InitVal.getAs<nonloc::LazyCompoundVal>());
}
}
// Recover some path-sensitivity if a scalar value evaluated to
// UnknownVal.
if (InitVal.isUnknown()) {
@ -596,7 +596,7 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
(T->isArrayType() || T->isRecordType() || T->isVectorType() ||
T->isAnyComplexType())) {
llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
// Handle base case where the initializer has no elements.
// e.g: static int* myArray[] = {};
if (NumInitElements == 0) {
@ -604,13 +604,13 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
return;
}
for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
ei = IE->rend(); it != ei; ++it) {
SVal V = state->getSVal(cast<Expr>(*it), LCtx);
vals = getBasicVals().consVals(V, vals);
}
B.generateNode(IE, Pred,
state->BindExpr(IE, LCtx,
svalBuilder.makeCompoundVal(T, vals)));
@ -632,7 +632,7 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
}
void ExprEngine::VisitGuardedExpr(const Expr *Ex,
const Expr *L,
const Expr *L,
const Expr *R,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
@ -692,7 +692,7 @@ void ExprEngine::VisitGuardedExpr(const Expr *Ex,
}
void ExprEngine::
VisitOffsetOfExpr(const OffsetOfExpr *OOE,
VisitOffsetOfExpr(const OffsetOfExpr *OOE,
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
APSInt IV;
@ -728,7 +728,7 @@ VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
if (Ex->getKind() == UETT_SizeOf) {
if (!T->isIncompleteType() && !T->isConstantSizeType()) {
assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
// FIXME: Add support for VLA type arguments and VLA expressions.
// When that happens, we should probably refactor VLASizeChecker's code.
continue;
@ -739,10 +739,10 @@ VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
continue;
}
}
APSInt Value = Ex->EvaluateKnownConstInt(getContext());
CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
ProgramStateRef state = (*I)->getState();
state = state->BindExpr(Ex, (*I)->getLocationContext(),
svalBuilder.makeIntVal(amt.getQuantity(),
@ -753,7 +753,7 @@ VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
}
void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
// FIXME: Prechecks eventually go in ::Visit().
@ -775,13 +775,13 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
}
case UO_Real: {
const Expr *Ex = U->getSubExpr()->IgnoreParens();
// FIXME: We don't have complex SValues yet.
if (Ex->getType()->isAnyComplexType()) {
// Just report "Unknown."
break;
}
// For all other types, UO_Real is an identity operation.
assert (U->getType() == Ex->getType());
ProgramStateRef state = (*I)->getState();
@ -790,8 +790,8 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
state->getSVal(Ex, LCtx)));
break;
}
case UO_Imag: {
case UO_Imag: {
const Expr *Ex = U->getSubExpr()->IgnoreParens();
// FIXME: We don't have complex SValues yet.
if (Ex->getType()->isAnyComplexType()) {
@ -805,7 +805,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
break;
}
case UO_Plus:
assert(!U->isGLValue());
// FALL-THROUGH.
@ -818,7 +818,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
// Unary "+" is a no-op, similar to a parentheses. We still have places
// where it may be a block-level expression, so we need to
// generate an extra node that just propagates the value of the
// subexpression.
// subexpression.
const Expr *Ex = U->getSubExpr()->IgnoreParens();
ProgramStateRef state = (*I)->getState();
const LocationContext *LCtx = (*I)->getLocationContext();
@ -826,7 +826,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
state->getSVal(Ex, LCtx)));
break;
}
case UO_LNot:
case UO_Minus:
case UO_Not: {
@ -834,15 +834,15 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
const Expr *Ex = U->getSubExpr()->IgnoreParens();
ProgramStateRef state = (*I)->getState();
const LocationContext *LCtx = (*I)->getLocationContext();
// Get the value of the subexpression.
SVal V = state->getSVal(Ex, LCtx);
if (V.isUnknownOrUndef()) {
Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V));
break;
}
switch (U->getOpcode()) {
default:
llvm_unreachable("Invalid Opcode.");
@ -859,7 +859,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
//
// Note: technically we do "E == 0", but this is the same in the
// transfer functions as "0 == E".
SVal Result;
SVal Result;
if (Optional<Loc> LV = V.getAs<Loc>()) {
Loc X = svalBuilder.makeNull();
Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
@ -872,8 +872,8 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X,
U->getType());
}
state = state->BindExpr(U, LCtx, Result);
state = state->BindExpr(U, LCtx, Result);
break;
}
Bldr.generateNode(U, *I, state);
@ -891,81 +891,81 @@ void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
// Handle ++ and -- (both pre- and post-increment).
assert (U->isIncrementDecrementOp());
const Expr *Ex = U->getSubExpr()->IgnoreParens();
const LocationContext *LCtx = Pred->getLocationContext();
ProgramStateRef state = Pred->getState();
SVal loc = state->getSVal(Ex, LCtx);
// Perform a load.
ExplodedNodeSet Tmp;
evalLoad(Tmp, U, Ex, Pred, state, loc);
ExplodedNodeSet Dst2;
StmtNodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) {
state = (*I)->getState();
assert(LCtx == (*I)->getLocationContext());
SVal V2_untested = state->getSVal(Ex, LCtx);
// Propagate unknown and undefined values.
if (V2_untested.isUnknownOrUndef()) {
Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V2_untested));
continue;
}
DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
// Handle all other values.
BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
// If the UnaryOperator has non-location type, use its type to create the
// constant value. If the UnaryOperator has location type, create the
// constant with int type and pointer width.
SVal RHS;
if (U->getType()->isAnyPointerType())
RHS = svalBuilder.makeArrayIndex(1);
else if (U->getType()->isIntegralOrEnumerationType())
RHS = svalBuilder.makeIntVal(1, U->getType());
else
RHS = UnknownVal();
SVal Result = evalBinOp(state, Op, V2, RHS, U->getType());
// Conjure a new symbol if necessary to recover precision.
if (Result.isUnknown()){
DefinedOrUnknownSVal SymVal =
svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
currBldrCtx->blockCount());
Result = SymVal;
// If the value is a location, ++/-- should always preserve
// non-nullness. Check if the original value was non-null, and if so
// propagate that constraint.
if (Loc::isLocType(U->getType())) {
DefinedOrUnknownSVal Constraint =
svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
if (!state->assume(Constraint, true)) {
// It isn't feasible for the original value to be null.
// Propagate this constraint.
Constraint = svalBuilder.evalEQ(state, SymVal,
svalBuilder.makeZeroVal(U->getType()));
state = state->assume(Constraint, false);
assert(state);
}
}
}
// Since the lvalue-to-rvalue conversion is explicit in the AST,
// we bind an l-value if the operator is prefix and an lvalue (in C++).
if (U->isGLValue())
state = state->BindExpr(U, LCtx, loc);
else
state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
// Perform the store.
Bldr.takeNodes(*I);
ExplodedNodeSet Dst3;

View File

@ -300,7 +300,7 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType,
const MemRegion *Dest,
const Stmt *S,
bool IsBaseDtor,
ExplodedNode *Pred,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
const LocationContext *LCtx = Pred->getLocationContext();
ProgramStateRef State = Pred->getState();
@ -373,7 +373,7 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
// Also, we need to decide how allocators actually work -- they're not
// really part of the CXXNewExpr because they happen BEFORE the
// CXXConstructExpr subexpression. See PR12014 for some discussion.
unsigned blockCount = currBldrCtx->blockCount();
const LocationContext *LCtx = Pred->getLocationContext();
DefinedOrUnknownSVal symVal = UnknownVal();
@ -392,8 +392,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
IsStandardGlobalOpNewFunction = (FD->getNumParams() == 1);
}
// We assume all standard global 'operator new' functions allocate memory in
// heap. We realize this is an approximation that might not correctly model
// We assume all standard global 'operator new' functions allocate memory in
// heap. We realize this is an approximation that might not correctly model
// a custom global allocator.
if (IsStandardGlobalOpNewFunction)
symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount);
@ -472,7 +472,7 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
}
}
void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
ProgramStateRef state = Pred->getState();

View File

@ -44,19 +44,19 @@ void ExprEngine::processCallEnter(CallEnter CE, ExplodedNode *Pred) {
const CFG *CalleeCFG = calleeCtx->getCFG();
const CFGBlock *Entry = &(CalleeCFG->getEntry());
// Validate the CFG.
assert(Entry->empty());
assert(Entry->succ_size() == 1);
// Get the solitary successor.
const CFGBlock *Succ = *(Entry->succ_begin());
// Construct an edge representing the starting location in the callee.
BlockEdge Loc(Entry, Succ, calleeCtx);
ProgramStateRef state = Pred->getState();
// Construct a new node and add it to the worklist.
bool isNew;
ExplodedNode *Node = G.getNode(Loc, state, false, &isNew);
@ -207,8 +207,8 @@ static bool isTemporaryPRValue(const CXXConstructExpr *E, SVal V) {
return isa<CXXTempObjectRegion>(MR);
}
/// The call exit is simulated with a sequence of nodes, which occur between
/// CallExitBegin and CallExitEnd. The following operations occur between the
/// The call exit is simulated with a sequence of nodes, which occur between
/// CallExitBegin and CallExitEnd. The following operations occur between the
/// two program points:
/// 1. CallExitBegin (triggers the start of call exit sequence)
/// 2. Bind the return value
@ -220,12 +220,12 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
PrettyStackTraceLocationContext CrashInfo(CEBNode->getLocationContext());
const StackFrameContext *calleeCtx =
CEBNode->getLocationContext()->getCurrentStackFrame();
// The parent context might not be a stack frame, so make sure we
// look up the first enclosing stack frame.
const StackFrameContext *callerCtx =
calleeCtx->getParent()->getCurrentStackFrame();
const Stmt *CE = calleeCtx->getCallSite();
ProgramStateRef state = CEBNode->getState();
// Find the last statement in the function and the corresponding basic block.
@ -429,7 +429,7 @@ bool ExprEngine::inlineCall(const CallEvent &Call, const Decl *D,
cast<BlockDecl>(D),
BR);
}
// This may be NULL, but that's fine.
const Expr *CallE = Call.getOriginExpr();
@ -439,8 +439,8 @@ bool ExprEngine::inlineCall(const CallEvent &Call, const Decl *D,
CalleeADC->getStackFrame(ParentOfCallee, CallE,
currBldrCtx->getBlock(),
currStmtIdx);
CallEnter Loc(CallE, CalleeSFC, CurLC);
// Construct a new state which contains the mapping from actual to
@ -769,7 +769,7 @@ static bool mayInlineDecl(AnalysisDeclContext *CalleeADC,
if (!Ctx.getSourceManager().isInMainFile(FD->getLocation()))
if (isContainerMethod(Ctx, FD))
return false;
// Conditionally control the inlining of the destructor of C++ shared_ptr.
// We don't currently do a good job modeling shared_ptr because we can't
// see the reference count, so treating as opaque is probably the best
@ -992,12 +992,12 @@ void ExprEngine::BifurcateCall(const MemRegion *BifurReg,
void ExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
ExplodedNodeSet dstPreVisit;
getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, RS, *this);
StmtNodeBuilder B(dstPreVisit, Dst, *currBldrCtx);
if (RS->getRetValue()) {
for (ExplodedNodeSet::iterator it = dstPreVisit.begin(),
ei = dstPreVisit.end(); it != ei; ++it) {

View File

@ -19,18 +19,18 @@
using namespace clang;
using namespace ento;
void ExprEngine::VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *Ex,
void ExprEngine::VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *Ex,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
ProgramStateRef state = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
SVal baseVal = state->getSVal(Ex->getBase(), LCtx);
SVal location = state->getLValue(Ex->getDecl(), baseVal);
ExplodedNodeSet dstIvar;
StmtNodeBuilder Bldr(Pred, dstIvar, *currBldrCtx);
Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, location));
// Perform the post-condition check of the ObjCIvarRefExpr and store
// the created nodes in 'Dst'.
getCheckerManager().runCheckersForPostStmt(Dst, dstIvar, Ex, *this);
@ -45,7 +45,7 @@ void ExprEngine::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S,
void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
// ObjCForCollectionStmts are processed in two places. This method
// handles the case where an ObjCForCollectionStmt* occurs as one of the
// statements within a basic block. This transfer function does two things:
@ -74,7 +74,7 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
const Stmt *elem = S->getElement();
ProgramStateRef state = Pred->getState();
SVal elementV;
if (const DeclStmt *DS = dyn_cast<DeclStmt>(elem)) {
const VarDecl *elemD = cast<VarDecl>(DS->getSingleDecl());
assert(elemD->getInit() == nullptr);
@ -83,7 +83,7 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
else {
elementV = state->getSVal(elem, Pred->getLocationContext());
}
ExplodedNodeSet dstLocation;
evalLocation(dstLocation, S, elem, Pred, state, elementV, nullptr, false);
@ -95,17 +95,17 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
Pred = *NI;
ProgramStateRef state = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
// Handle the case where the container still has elements.
SVal TrueV = svalBuilder.makeTruthVal(1);
ProgramStateRef hasElems = state->BindExpr(S, LCtx, TrueV);
// Handle the case where the container has no elements.
SVal FalseV = svalBuilder.makeTruthVal(0);
ProgramStateRef noElems = state->BindExpr(S, LCtx, FalseV);
if (Optional<loc::MemRegionVal> MV = elementV.getAs<loc::MemRegionVal>())
if (const TypedValueRegion *R =
if (const TypedValueRegion *R =
dyn_cast<TypedValueRegion>(MV->getRegion())) {
// FIXME: The proper thing to do is to really iterate over the
// container. We will do this with dispatch logic to the store.
@ -116,12 +116,12 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
currBldrCtx->blockCount());
SVal V = svalBuilder.makeLoc(Sym);
hasElems = hasElems->bindLoc(elementV, V);
// Bind the location to 'nil' on the false branch.
SVal nilV = svalBuilder.makeIntVal(0, T);
noElems = noElems->bindLoc(elementV, nilV);
}
// Create the new nodes.
Bldr.generateNode(S, Pred, hasElems);
Bldr.generateNode(S, Pred, noElems);
@ -156,7 +156,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
ExplodedNode *Pred = *DI;
ProgramStateRef State = Pred->getState();
CallEventRef<ObjCMethodCall> UpdatedMsg = Msg.cloneWithState(State);
if (UpdatedMsg->isInstanceMessage()) {
SVal recVal = UpdatedMsg->getReceiverSVal();
if (!recVal.isUndef()) {
@ -166,7 +166,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
ProgramStateRef notNilState, nilState;
std::tie(notNilState, nilState) = State->assume(receiverVal);
// There are three cases: can be nil or non-nil, must be nil, must be
// non-nil. We ignore must be nil, and merge the rest two into non-nil.
// FIXME: This ignores many potential bugs (<rdar://problem/11733396>).
@ -174,7 +174,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
if (nilState && !notNilState) {
continue;
}
// Check if the "raise" message was sent.
assert(notNilState);
if (ObjCNoRet.isImplicitNoReturn(ME)) {
@ -183,7 +183,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
Bldr.generateSink(ME, Pred, State);
continue;
}
// Generate a transition to non-Nil state.
if (notNilState != State) {
Pred = Bldr.generateNode(ME, Pred, notNilState);
@ -203,7 +203,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
defaultEvalCall(Bldr, Pred, *UpdatedMsg);
}
ExplodedNodeSet dstPostvisit;
getCheckerManager().runCheckersForPostCall(dstPostvisit, dstEval,
*Msg, *this);

View File

@ -1,13 +1,13 @@
##===- clang/lib/StaticAnalyzer/Core/Makefile --------------*- Makefile -*-===##
#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#
##===----------------------------------------------------------------------===##
#
# This implements analyses built on top of source-level CFGs.
# This implements analyses built on top of source-level CFGs.
#
##===----------------------------------------------------------------------===##

View File

@ -756,7 +756,7 @@ getStackOrCaptureRegionForDeclContext(const LocationContext *LC,
return cast<VarRegion>(I.getCapturedRegion());
}
}
LC = LC->getParent();
}
return (const StackFrameContext *)nullptr;
@ -788,18 +788,18 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
else
sReg = getGlobalsRegion();
}
// Finally handle static locals.
// Finally handle static locals.
} else {
// FIXME: Once we implement scope handling, we will need to properly lookup
// 'D' to the proper LocationContext.
const DeclContext *DC = D->getDeclContext();
llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
getStackOrCaptureRegionForDeclContext(LC, DC, D);
if (V.is<const VarRegion*>())
return V.get<const VarRegion*>();
const StackFrameContext *STC = V.get<const StackFrameContext*>();
if (!STC)
@ -1239,7 +1239,7 @@ RegionOffset MemRegion::getAsOffset() const {
Ty = SR->getSymbol()->getType()->getPointeeType();
RootIsSymbolic = true;
}
const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
if (!Child) {
// We cannot compute the offset of the base class.
@ -1290,7 +1290,7 @@ RegionOffset MemRegion::getAsOffset() const {
if (Optional<nonloc::ConcreteInt> CI =
Index.getAs<nonloc::ConcreteInt>()) {
// Don't bother calculating precise offsets if we already have a
// symbolic offset somewhere in the chain.
// symbolic offset somewhere in the chain.
if (SymbolicOffsetBase)
continue;
@ -1324,7 +1324,7 @@ RegionOffset MemRegion::getAsOffset() const {
// Get the field number.
unsigned idx = 0;
for (RecordDecl::field_iterator FI = RD->field_begin(),
for (RecordDecl::field_iterator FI = RD->field_begin(),
FE = RD->field_end(); FI != FE; ++FI, ++idx)
if (FR->getDecl() == *FI)
break;
@ -1420,7 +1420,7 @@ BlockDataRegion::referenced_vars_begin() const {
BumpVector<const MemRegion*> *VecOriginal =
static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
return BlockDataRegion::referenced_vars_iterator(Vec->begin(),
VecOriginal->begin());
}
@ -1456,12 +1456,12 @@ const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const {
// RegionAndSymbolInvalidationTraits
//===----------------------------------------------------------------------===//
void RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym,
void RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym,
InvalidationKinds IK) {
SymTraitsMap[Sym] |= IK;
}
void RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR,
void RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR,
InvalidationKinds IK) {
assert(MR);
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
@ -1470,13 +1470,13 @@ void RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR,
MRTraitsMap[MR] |= IK;
}
bool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym,
bool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym,
InvalidationKinds IK) {
const_symbol_iterator I = SymTraitsMap.find(Sym);
if (I != SymTraitsMap.end())
return I->second & IK;
return false;
return false;
}
bool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR,

View File

@ -179,7 +179,7 @@ void PathDiagnostic::resetDiagnosticLocationToMainFile() {
// Reset the report containing declaration and location.
DeclWithIssue = CP->getCaller();
Loc = CP->getLocation();
return;
}
}
@ -199,7 +199,7 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(
std::unique_ptr<PathDiagnostic> D) {
if (!D || D->path.empty())
return;
// We need to flatten the locations (convert Stmt* to locations) because
// the referenced statements may be freed by the time the diagnostics
// are emitted.
@ -221,12 +221,12 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(
++I) {
const PathDiagnosticPiece *piece = I->get();
FullSourceLoc L = piece->getLocation().asLocation().getExpansionLoc();
if (FID.isInvalid()) {
FID = SMgr.getFileID(L);
} else if (SMgr.getFileID(L) != FID)
return; // FIXME: Emit a warning?
// Check the source ranges.
ArrayRef<SourceRange> Ranges = piece->getRanges();
for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
@ -238,7 +238,7 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(
if (!L.isFileID() || SMgr.getFileID(L) != FID)
return; // FIXME: Emit a warning?
}
if (const PathDiagnosticCallPiece *call =
dyn_cast<PathDiagnosticCallPiece>(piece)) {
WorkList.push_back(&call->path);
@ -249,10 +249,10 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(
}
}
}
if (FID.isInvalid())
return; // FIXME: Emit a warning?
}
}
// Profile the node to see if we already have something matching it
llvm::FoldingSetNodeID profile;
@ -318,7 +318,7 @@ static Optional<bool> comparePiece(const PathDiagnosticPiece &X,
const PathDiagnosticPiece &Y) {
if (X.getKind() != Y.getKind())
return X.getKind() < Y.getKind();
FullSourceLoc XL = X.getLocation().asLocation();
FullSourceLoc YL = Y.getLocation().asLocation();
if (XL != YL)
@ -331,7 +331,7 @@ static Optional<bool> comparePiece(const PathDiagnosticPiece &X,
return X.getRanges().size() < Y.getRanges().size();
const SourceManager &SM = XL.getManager();
for (unsigned i = 0, n = X.getRanges().size(); i < n; ++i) {
SourceRange XR = X.getRanges()[i];
SourceRange YR = Y.getRanges()[i];
@ -341,7 +341,7 @@ static Optional<bool> comparePiece(const PathDiagnosticPiece &X,
return SM.isBeforeInTranslationUnit(XR.getEnd(), YR.getEnd());
}
}
switch (X.getKind()) {
case clang::ento::PathDiagnosticPiece::ControlFlow:
return compareControlFlow(cast<PathDiagnosticControlFlowPiece>(X),
@ -418,9 +418,9 @@ void PathDiagnosticConsumer::FlushDiagnostics(
PathDiagnosticConsumer::FilesMade *Files) {
if (flushed)
return;
flushed = true;
std::vector<const PathDiagnostic *> BatchDiags;
for (llvm::FoldingSet<PathDiagnostic>::iterator it = Diags.begin(),
et = Diags.end(); it != et; ++it) {
@ -448,7 +448,7 @@ void PathDiagnosticConsumer::FlushDiagnostics(
const PathDiagnostic *D = *it;
delete D;
}
// Clear out the FoldingSet.
Diags.clear();
}
@ -470,7 +470,7 @@ void PathDiagnosticConsumer::FilesMade::addDiagnostic(const PathDiagnostic &PD,
Entry = new (Entry) PDFileEntry(NodeID);
Set.InsertNode(Entry, InsertPos);
}
// Allocate persistent storage for the file name.
char *FileName_cstr = (char*) Alloc.Allocate(FileName.size(), 1);
memcpy(FileName_cstr, FileName.data(), FileName.size());
@ -845,7 +845,7 @@ PathDiagnosticRange
SourceRange R = S->getSourceRange();
if (R.isValid())
return R;
break;
break;
}
case DeclK:
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
@ -947,7 +947,7 @@ static bool describeCodeDecl(raw_ostream &Out, const Decl *D,
Out << "constructor";
describeClass(Out, MD->getParent(), " for ");
} else if (isa<CXXDestructorDecl>(MD)) {
if (!MD->isUserProvided()) {
Out << "destructor";
@ -1039,7 +1039,7 @@ static void compute_path_size(const PathPieces &pieces, unsigned &size) {
for (PathPieces::const_iterator it = pieces.begin(),
et = pieces.end(); it != et; ++it) {
const PathDiagnosticPiece *piece = it->get();
if (const PathDiagnosticCallPiece *cp =
if (const PathDiagnosticCallPiece *cp =
dyn_cast<PathDiagnosticCallPiece>(piece)) {
compute_path_size(cp->path, size);
}
@ -1075,12 +1075,12 @@ void PathDiagnosticPiece::Profile(llvm::FoldingSetNodeID &ID) const {
I != E; ++I) {
ID.AddInteger(I->getBegin().getRawEncoding());
ID.AddInteger(I->getEnd().getRawEncoding());
}
}
}
void PathDiagnosticCallPiece::Profile(llvm::FoldingSetNodeID &ID) const {
PathDiagnosticPiece::Profile(ID);
for (PathPieces::const_iterator it = path.begin(),
for (PathPieces::const_iterator it = path.begin(),
et = path.end(); it != et; ++it) {
ID.Add(**it);
}

View File

@ -171,7 +171,7 @@ static void ReportEvent(raw_ostream &o, const PathDiagnosticPiece& P,
--indent;
Indent(o, indent) << "</array>\n";
}
// Output the call depth.
Indent(o, indent) << "<key>depth</key>";
EmitInteger(o, depth) << '\n';
@ -187,7 +187,7 @@ static void ReportEvent(raw_ostream &o, const PathDiagnosticPiece& P,
Indent(o, indent) << "<key>message</key>\n";
Indent(o, indent);
EmitString(o, P.getString()) << '\n';
// Finish up.
--indent;
Indent(o, indent); o << "</dict>\n";
@ -208,9 +208,9 @@ static void ReportCall(raw_ostream &o,
const LangOptions &LangOpts,
unsigned indent,
unsigned depth) {
IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnter =
P.getCallEnterEvent();
P.getCallEnterEvent();
if (callEnter)
ReportPiece(o, *callEnter, FM, SM, LangOpts, indent, depth, true,
@ -218,18 +218,18 @@ static void ReportCall(raw_ostream &o,
IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnterWithinCaller =
P.getCallEnterWithinCallerEvent();
++depth;
if (callEnterWithinCaller)
ReportPiece(o, *callEnterWithinCaller, FM, SM, LangOpts,
indent, depth, true);
for (PathPieces::const_iterator I = P.path.begin(), E = P.path.end();I!=E;++I)
ReportPiece(o, **I, FM, SM, LangOpts, indent, depth, true);
--depth;
IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit =
P.getCallExitEvent();
@ -297,7 +297,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
if (!Diags.empty())
SM = &(*(*Diags.begin())->path.begin())->getLocation().getManager();
for (std::vector<const PathDiagnostic*>::iterator DI = Diags.begin(),
DE = Diags.end(); DI != DE; ++DI) {
@ -374,7 +374,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
o << " <array>\n";
for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
I != E; ++I)
ReportDiag(o, **I, FM, *SM, LangOpts);
@ -389,7 +389,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
EmitString(o, D->getBugType()) << '\n';
o << " <key>check_name</key>";
EmitString(o, D->getCheckName()) << '\n';
// Output information about the semantic context where
// the issue occurred.
if (const Decl *DeclWithIssue = D->getDeclWithIssue()) {
@ -423,7 +423,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
// Output the bug hash for issue unique-ing. Currently, it's just an
// offset from the beginning of the function.
if (const Stmt *Body = DeclWithIssue->getBody()) {
// If the bug uniqueing location exists, use it for the hash.
// For example, this ensures that two leaks reported on the same line
// will have different issue_hashes and that the hash will identify
@ -486,5 +486,5 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
o << " </array>\n";
// Finish.
o << "</dict>\n</plist>";
o << "</dict>\n</plist>";
}

View File

@ -36,7 +36,7 @@ void ProgramStateRelease(const ProgramState *state) {
if (--s->refCount == 0) {
ProgramStateManager &Mgr = s->getStateManager();
Mgr.StateSet.RemoveNode(s);
s->~ProgramState();
s->~ProgramState();
Mgr.freeStates.push_back(s);
}
}
@ -86,7 +86,7 @@ ProgramStateManager::~ProgramStateManager() {
I->second.second(I->second.first);
}
ProgramStateRef
ProgramStateRef
ProgramStateManager::removeDeadBindings(ProgramStateRef state,
const StackFrameContext *LCtx,
SymbolReaper& SymReaper) {
@ -113,7 +113,7 @@ ProgramStateManager::removeDeadBindings(ProgramStateRef state,
ProgramStateRef ProgramState::bindLoc(Loc LV, SVal V, bool notifyChanges) const {
ProgramStateManager &Mgr = getStateManager();
ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
LV, V));
const MemRegion *MR = LV.getAsRegion();
if (MR && Mgr.getOwningEngine() && notifyChanges)
@ -127,15 +127,15 @@ ProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const {
const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
ProgramStateRef new_state = makeWithStore(newStore);
return Mgr.getOwningEngine() ?
Mgr.getOwningEngine()->processRegionChange(new_state, R) :
return Mgr.getOwningEngine() ?
Mgr.getOwningEngine()->processRegionChange(new_state, R) :
new_state;
}
typedef ArrayRef<const MemRegion *> RegionList;
typedef ArrayRef<SVal> ValueList;
ProgramStateRef
ProgramStateRef
ProgramState::invalidateRegions(RegionList Regions,
const Expr *E, unsigned Count,
const LocationContext *LCtx,
@ -197,11 +197,11 @@ ProgramState::invalidateRegionsImpl(ValueList Values,
if (CausedByPointerEscape) {
newState = Eng->notifyCheckersOfPointerEscape(newState, IS,
TopLevelInvalidated,
Invalidated, Call,
Invalidated, Call,
*ITraits);
}
return Eng->processRegionChanges(newState, IS, TopLevelInvalidated,
return Eng->processRegionChanges(newState, IS, TopLevelInvalidated,
Invalidated, Call);
}
@ -224,7 +224,7 @@ ProgramStateRef ProgramState::killBinding(Loc LV) const {
return makeWithStore(newStore);
}
ProgramStateRef
ProgramStateRef
ProgramState::enterStackFrame(const CallEvent &Call,
const StackFrameContext *CalleeCtx) const {
const StoreRef &NewStore =
@ -275,7 +275,7 @@ SVal ProgramState::getSVal(Loc location, QualType T) const {
// symbol for the call to foo(); the type of that symbol is 'char',
// not unsigned.
const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int);
if (V.getAs<Loc>())
return loc::ConcreteInt(NewV);
else
@ -283,7 +283,7 @@ SVal ProgramState::getSVal(Loc location, QualType T) const {
}
}
}
return V;
}
@ -353,11 +353,11 @@ ConditionTruthVal ProgramState::isNull(SVal V) const {
if (V.isConstant())
return false;
SymbolRef Sym = V.getAsSymbol(/* IncludeBaseRegion */ true);
if (!Sym)
return ConditionTruthVal();
return getStateManager().ConstraintMgr->isNull(this, Sym);
}
@ -390,7 +390,7 @@ ProgramStateRef ProgramStateManager::getPersistentState(ProgramState &State) {
ProgramState *newState = nullptr;
if (!freeStates.empty()) {
newState = freeStates.back();
freeStates.pop_back();
freeStates.pop_back();
}
else {
newState = (ProgramState*) Alloc.Allocate<ProgramState>();
@ -530,10 +530,10 @@ bool ScanReachableSymbols::scan(const SymExpr *sym) {
bool wasVisited = !visited.insert(sym).second;
if (wasVisited)
return true;
if (!visitor.VisitSymbol(sym))
return false;
// TODO: should be rewritten using SymExpr::symbol_iterator.
switch (sym->getKind()) {
case SymExpr::RegionValueKind:
@ -582,11 +582,11 @@ bool ScanReachableSymbols::scan(SVal val) {
bool ScanReachableSymbols::scan(const MemRegion *R) {
if (isa<MemSpaceRegion>(R))
return true;
bool wasVisited = !visited.insert(R).second;
if (wasVisited)
return true;
if (!visitor.VisitMemRegion(R))
return false;
@ -722,14 +722,14 @@ bool ProgramState::isTainted(const MemRegion *Reg, TaintTagType K) const {
bool ProgramState::isTainted(SymbolRef Sym, TaintTagType Kind) const {
if (!Sym)
return false;
// Traverse all the symbols this symbol depends on to see if any are tainted.
bool Tainted = false;
for (SymExpr::symbol_iterator SI = Sym->symbol_begin(), SE =Sym->symbol_end();
SI != SE; ++SI) {
if (!isa<SymbolData>(*SI))
continue;
const TaintTagType *Tag = get<TaintMap>(*SI);
Tainted = (Tag && *Tag == Kind);
@ -748,7 +748,7 @@ bool ProgramState::isTainted(SymbolRef Sym, TaintTagType Kind) const {
if (Tainted)
return true;
}
return Tainted;
}

View File

@ -365,7 +365,7 @@ ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
/// Scan all symbols referenced by the constraints. If the symbol is not alive
/// as marked in LSymbols, mark it as dead in DSymbols.
ProgramStateRef
ProgramStateRef
RangeConstraintManager::removeDeadBindings(ProgramStateRef state,
SymbolReaper& SymReaper) {
@ -415,7 +415,7 @@ RangeConstraintManager::GetRange(ProgramStateRef state, SymbolRef sym) {
// As an example, the range [UINT_MAX-1, 3) contains five values: UINT_MAX-1,
// UINT_MAX, 0, 1, and 2.
ProgramStateRef
ProgramStateRef
RangeConstraintManager::assumeSymNE(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) {
@ -435,7 +435,7 @@ RangeConstraintManager::assumeSymNE(ProgramStateRef St, SymbolRef Sym,
return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
}
ProgramStateRef
ProgramStateRef
RangeConstraintManager::assumeSymEQ(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) {
@ -450,7 +450,7 @@ RangeConstraintManager::assumeSymEQ(ProgramStateRef St, SymbolRef Sym,
return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
}
ProgramStateRef
ProgramStateRef
RangeConstraintManager::assumeSymLT(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) {
@ -479,7 +479,7 @@ RangeConstraintManager::assumeSymLT(ProgramStateRef St, SymbolRef Sym,
return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
}
ProgramStateRef
ProgramStateRef
RangeConstraintManager::assumeSymGT(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) {
@ -508,7 +508,7 @@ RangeConstraintManager::assumeSymGT(ProgramStateRef St, SymbolRef Sym,
return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
}
ProgramStateRef
ProgramStateRef
RangeConstraintManager::assumeSymGE(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) {
@ -537,7 +537,7 @@ RangeConstraintManager::assumeSymGE(ProgramStateRef St, SymbolRef Sym,
return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
}
ProgramStateRef
ProgramStateRef
RangeConstraintManager::assumeSymLE(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) {

View File

@ -464,9 +464,9 @@ public: // Part of public interface to class.
StoreRef killBinding(Store ST, Loc L) override;
void incrementReferenceCount(Store store) override {
getRegionBindings(store).manualRetain();
getRegionBindings(store).manualRetain();
}
/// If the StoreManager supports it, decrement the reference count of
/// the specified Store object. If the reference count hits 0, the memory
/// associated with the object is recycled.
@ -508,7 +508,7 @@ public: // Part of public interface to class.
SVal getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
const TypedValueRegion *R,
QualType Ty);
SVal getLazyBinding(const SubRegion *LazyBindingRegion,
RegionBindingsRef LazyBinding);
@ -987,8 +987,8 @@ void invalidateRegionsWorker::VisitBinding(SVal V) {
void invalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
const ClusterBindings *C) {
bool PreserveRegionsContents =
ITraits.hasTrait(baseR,
bool PreserveRegionsContents =
ITraits.hasTrait(baseR,
RegionAndSymbolInvalidationTraits::TK_PreserveContents);
if (C) {
@ -1456,7 +1456,7 @@ RegionStoreManager::findLazyBinding(RegionBindingsConstRef B,
// through to look for lazy compound value. It is like a field region.
Result = findLazyBinding(B, cast<SubRegion>(BaseReg->getSuperRegion()),
originalRegion);
if (Result.second)
Result.second = MRMgr.getCXXBaseObjectRegionWithSuper(BaseReg,
Result.second);
@ -1502,7 +1502,7 @@ SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,
return svalBuilder.makeIntVal(c, T);
}
}
// Check for loads from a code text region. For such loads, just give up.
if (isa<CodeTextRegion>(superR))
return UnknownVal();
@ -1514,12 +1514,12 @@ SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,
// return *y;
// FIXME: This is a hack, and doesn't do anything really intelligent yet.
const RegionRawOffset &O = R->getAsArrayOffset();
// If we cannot reason about the offset, return an unknown value.
if (!O.getRegion())
return UnknownVal();
if (const TypedValueRegion *baseR =
if (const TypedValueRegion *baseR =
dyn_cast_or_null<TypedValueRegion>(O.getRegion())) {
QualType baseT = baseR->getValueType();
if (baseT->isScalarType()) {
@ -1610,7 +1610,7 @@ SVal RegionStoreManager::getLazyBinding(const SubRegion *LazyBindingRegion,
return Result;
}
SVal
RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
const TypedValueRegion *R,
@ -1664,7 +1664,7 @@ RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
if (!index.isConstant())
hasSymbolicIndex = true;
}
// If our super region is a field or element itself, walk up the region
// hierarchy to see if there is a default value installed in an ancestor.
SR = dyn_cast<SubRegion>(Base);
@ -1674,7 +1674,7 @@ RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
if (isa<ElementRegion>(R)) {
// Currently we don't reason specially about Clang-style vectors. Check
// if superR is a vector and if so return Unknown.
if (const TypedValueRegion *typedSuperR =
if (const TypedValueRegion *typedSuperR =
dyn_cast<TypedValueRegion>(R->getSuperRegion())) {
if (typedSuperR->getValueType()->isVectorType())
return UnknownVal();
@ -1801,7 +1801,7 @@ RegionStoreManager::getInterestingValues(nonloc::LazyCompoundVal LCV) {
List.insert(List.end(), InnerList.begin(), InnerList.end());
continue;
}
List.push_back(V);
}
@ -1838,7 +1838,7 @@ SVal RegionStoreManager::getBindingForArray(RegionBindingsConstRef B,
const TypedValueRegion *R) {
assert(Ctx.getAsConstantArrayType(R->getValueType()) &&
"Only constant array types can have compound bindings.");
return createLazyBinding(B, R);
}
@ -2012,11 +2012,11 @@ RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B,
QualType T = R->getValueType();
assert(T->isVectorType());
const VectorType *VT = T->getAs<VectorType>(); // Use getAs for typedefs.
// Handle lazy compound values and symbolic values.
if (V.getAs<nonloc::LazyCompoundVal>() || V.getAs<nonloc::SymbolVal>())
return bindAggregate(B, R, V);
// We may get non-CompoundVal accidentally due to imprecise cast logic or
// that we are binding symbolic struct value. Kill the field values, and if
// the value is symbolic go and bind it as a "default" binding.
@ -2033,7 +2033,7 @@ RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B,
for ( ; index != numElements ; ++index) {
if (VI == VE)
break;
NonLoc Idx = svalBuilder.makeArrayIndex(index);
const ElementRegion *ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx);
@ -2075,7 +2075,7 @@ RegionStoreManager::tryBindSmallStruct(RegionBindingsConstRef B,
}
RegionBindingsRef NewB = B;
for (FieldVector::iterator I = Fields.begin(), E = Fields.end(); I != E; ++I){
const FieldRegion *SourceFR = MRMgr.getFieldRegion(*I, LCV.getRegion());
SVal V = getBindingForField(getRegionBindings(LCV.getStore()), SourceFR);
@ -2259,7 +2259,7 @@ void removeDeadBindingsWorker::VisitBinding(SVal V) {
// If V is a region, then add it to the worklist.
if (const MemRegion *R = V.getAsRegion()) {
AddToWorkList(R);
// All regions captured by a block are also live.
if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) {
BlockDataRegion::referenced_vars_iterator I = BR->referenced_vars_begin(),
@ -2268,7 +2268,7 @@ void removeDeadBindingsWorker::VisitBinding(SVal V) {
AddToWorkList(I.getCapturedRegion());
}
}
// Update the set of live symbols.
for (SymExpr::symbol_iterator SI = V.symbol_begin(), SE = V.symbol_end();

View File

@ -91,7 +91,7 @@ nonloc::ConcreteInt SValBuilder::makeBoolVal(const CXXBoolLiteralExpr *boolean){
return makeTruthVal(boolean->getValue());
}
DefinedOrUnknownSVal
DefinedOrUnknownSVal
SValBuilder::getRegionValueSymbolVal(const TypedValueRegion* region) {
QualType T = region->getValueType();
@ -146,10 +146,10 @@ DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const Stmt *stmt,
return UnknownVal();
SymbolRef sym = SymMgr.conjureSymbol(stmt, LCtx, type, visitCount);
if (Loc::isLocType(type))
return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
return nonloc::SymbolVal(sym);
}
@ -307,7 +307,7 @@ SVal SValBuilder::makeSymExprValNN(ProgramStateRef State,
QualType ResultTy) {
if (!State->isTainted(RHS) && !State->isTainted(LHS))
return UnknownVal();
const SymExpr *symLHS = LHS.getAsSymExpr();
const SymExpr *symRHS = RHS.getAsSymExpr();
// TODO: When the Max Complexity is reached, we should conjure a symbol
@ -430,7 +430,7 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
if (shouldBeModeledWithNoOp(Context, Context.getPointerType(castTy),
Context.getPointerType(originalTy)))
return val;
// Check for casts from pointers to integers.
if (castTy->isIntegralOrEnumerationType() && Loc::isLocType(originalTy))
return evalCastFromLoc(val.castAs<Loc>(), castTy);

View File

@ -638,7 +638,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
// on the ABI).
// FIXME: we can probably do a comparison against other MemRegions, though.
// FIXME: is there a way to tell if two labels refer to the same location?
return UnknownVal();
return UnknownVal();
case loc::ConcreteIntKind: {
// If one of the operands is a symbol and the other is a constant,
@ -863,7 +863,7 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
// Special case: rhs is a zero constant.
if (rhs.isZeroConstant())
return lhs;
// We are dealing with pointer arithmetic.
// Handle pointer arithmetic on constant values.
@ -880,7 +880,7 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
// Offset the increment by the pointer size.
llvm::APSInt Multiplicand(rightI.getBitWidth(), /* isUnsigned */ true);
rightI *= Multiplicand;
// Compute the adjusted pointer.
switch (op) {
case BO_Add:
@ -922,7 +922,7 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
superR, getContext()));
}
}
return UnknownVal();
return UnknownVal();
}
const llvm::APSInt *SimpleSValBuilder::getKnownValue(ProgramStateRef state,

View File

@ -52,7 +52,7 @@ StoreRef StoreManager::BindDefault(Store store, const MemRegion *R, SVal V) {
return StoreRef(store, *this);
}
const ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R,
const ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R,
QualType T) {
NonLoc idx = svalBuilder.makeZeroArrayIndex();
assert(!T.isNull());
@ -366,22 +366,22 @@ SVal StoreManager::evalDynamicCast(SVal Base, QualType TargetType,
/// as another region.
SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R,
QualType castTy, bool performTestOnly) {
if (castTy.isNull() || V.isUnknownOrUndef())
return V;
ASTContext &Ctx = svalBuilder.getContext();
if (performTestOnly) {
if (performTestOnly) {
// Automatically translate references to pointers.
QualType T = R->getValueType();
if (const ReferenceType *RT = T->getAs<ReferenceType>())
T = Ctx.getPointerType(RT->getPointeeType());
assert(svalBuilder.getContext().hasSameUnqualifiedType(castTy, T));
return V;
}
return svalBuilder.dispatchCast(V, castTy);
}
@ -424,7 +424,7 @@ SVal StoreManager::getLValueIvar(const ObjCIvarDecl *decl, SVal base) {
return getLValueFieldOrIvar(decl, base);
}
SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
SVal Base) {
// If the base is an unknown or undefined value, just return it back.

View File

@ -409,7 +409,7 @@ bool SymbolReaper::maybeDead(SymbolRef sym) {
bool SymbolReaper::isLiveRegion(const MemRegion *MR) {
if (RegionRoots.count(MR))
return true;
MR = MR->getBaseRegion();
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
@ -442,9 +442,9 @@ bool SymbolReaper::isLive(SymbolRef sym) {
markDependentsLive(sym);
return true;
}
bool KnownLive;
switch (sym->getKind()) {
case SymExpr::RegionValueKind:
KnownLive = isLiveRegion(cast<SymbolRegionValue>(sym)->getRegion());
@ -525,7 +525,7 @@ bool SymbolReaper::isLive(const VarRegion *VR, bool includeStoreBindings) const{
if (!includeStoreBindings)
return false;
unsigned &cachedQuery =
const_cast<SymbolReaper*>(this)->includedRegionCache[VR];
@ -535,12 +535,12 @@ bool SymbolReaper::isLive(const VarRegion *VR, bool includeStoreBindings) const{
// Query the store to see if the region occurs in any live bindings.
if (Store store = reapedStore.getStore()) {
bool hasRegion =
bool hasRegion =
reapedStore.getStoreManager().includedInBindings(store, VR);
cachedQuery = hasRegion ? 1 : 2;
return hasRegion;
}
return false;
}

View File

@ -168,7 +168,7 @@ public:
/// The local declaration to all declarations ratio might be very small when
/// working with a PCH file.
SetOfDecls LocalTUDecls;
// Set of PathDiagnosticConsumers. Owned by AnalysisManager.
PathDiagnosticConsumers PathConsumers;
@ -364,7 +364,7 @@ public:
}
return true;
}
bool VisitBlockDecl(BlockDecl *BD) {
if (BD->hasBody()) {
assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
@ -475,7 +475,7 @@ void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) {
CallGraphNode *N = *I;
Decl *D = N->getDecl();
// Skip the abstract root node.
if (!D)
continue;
@ -679,11 +679,11 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D,
case LangOptions::NonGC:
ActionExprEngine(D, false, IMode, Visited);
break;
case LangOptions::GCOnly:
ActionExprEngine(D, true, IMode, Visited);
break;
case LangOptions::HybridGC:
ActionExprEngine(D, false, IMode, Visited);
ActionExprEngine(D, true, IMode, Visited);

View File

@ -42,7 +42,7 @@ public:
ClangCheckerRegistry(ArrayRef<std::string> plugins,
DiagnosticsEngine *diags = nullptr);
};
} // end anonymous namespace
ClangCheckerRegistry::ClangCheckerRegistry(ArrayRef<std::string> plugins,

View File

@ -1,10 +1,10 @@
##===- clang/lib/StaticAnalyzer/Frontend/Makefile ----------*- Makefile -*-===##
#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#
##===----------------------------------------------------------------------===##
#
# Starting point into the static analyzer land for the driver.

View File

@ -282,7 +282,7 @@ sub Analyze {
# We save the output file in the 'crashes' directory if clang encounters
# any problems with the file.
my ($ofh, $ofile) = tempfile("clang_output_XXXXXX", DIR => $HtmlDir);
my $OutputStream = silent_system($HtmlDir, $Cmd, @CmdArgs);
while ( <$OutputStream> ) {
print $ofh $_;

View File

@ -1400,7 +1400,7 @@ my $ForceDisplayHelp = 0;
sub ProcessArgs {
my $Args = shift;
while (@$Args) {
# Scan for options we recognize.

View File

@ -5,7 +5,7 @@ CmpRuns - A simple tool for comparing two static analyzer runs to determine
which reports have been added, removed, or changed.
This is designed to support automated testing using the static analyzer, from
two perspectives:
two perspectives:
1. To monitor changes in the static analyzer's reports on real code bases, for
regression testing.
@ -19,11 +19,11 @@ Usage:
#
resultsA = loadResultsFromSingleRun(singleRunInfoA, deleteEmpty)
resultsB = loadResultsFromSingleRun(singleRunInfoB, deleteEmpty)
# Generate a relation from diagnostics in run A to diagnostics in run B
# to obtain a list of triples (a, b, confidence).
# Generate a relation from diagnostics in run A to diagnostics in run B
# to obtain a list of triples (a, b, confidence).
diff = compareResults(resultsA, resultsB)
"""
import os
@ -32,7 +32,7 @@ import CmpRuns
# Information about analysis run:
# path - the analysis output directory
# root - the name of the root directory, which will be disregarded when
# root - the name of the root directory, which will be disregarded when
# determining the source file name
class SingleRunInfo:
def __init__(self, path, root="", verboseLog=None):
@ -56,7 +56,7 @@ class AnalysisDiagnostic:
def getLine(self):
return self._loc['line']
def getColumn(self):
return self._loc['col']
@ -80,12 +80,12 @@ class AnalysisDiagnostic:
return os.path.join(self._report.run.path, self._htmlReport)
def getReadableName(self):
return '%s:%d:%d, %s: %s' % (self.getFileName(), self.getLine(),
self.getColumn(), self.getCategory(),
return '%s:%d:%d, %s: %s' % (self.getFileName(), self.getLine(),
self.getColumn(), self.getCategory(),
self.getDescription())
# Note, the data format is not an API and may change from one analyzer
# version to another.
# Note, the data format is not an API and may change from one analyzer
# version to another.
def getRawData(self):
return self._data
@ -94,7 +94,7 @@ class multidict:
self.data = {}
for key,value in elts:
self[key] = value
def __getitem__(self, item):
return self.data[item]
def __setitem__(self, key, value):
@ -134,15 +134,15 @@ class AnalysisRun:
# Cumulative list of all diagnostics from all the reports.
self.diagnostics = []
self.clang_version = None
def getClangVersion(self):
return self.clang_version
def readSingleFile(self, p, deleteEmpty):
data = plistlib.readPlist(p)
# We want to retrieve the clang version even if there are no
# reports. Assume that all reports were created using the same
# We want to retrieve the clang version even if there are no
# reports. Assume that all reports were created using the same
# clang version (this is always true and is more efficient).
if 'clang_version' in data:
if self.clang_version == None:
@ -166,9 +166,9 @@ class AnalysisRun:
htmlFiles.append(d.pop('HTMLDiagnostics_files')[0])
else:
htmlFiles = [None] * len(data['diagnostics'])
report = AnalysisReport(self, data.pop('files'))
diagnostics = [AnalysisDiagnostic(d, report, h)
diagnostics = [AnalysisDiagnostic(d, report, h)
for d,h in zip(data.pop('diagnostics'),
htmlFiles)]
@ -179,7 +179,7 @@ class AnalysisRun:
self.diagnostics.extend(diagnostics)
# Backward compatibility API.
# Backward compatibility API.
def loadResults(path, opts, root = "", deleteEmpty=True):
return loadResultsFromSingleRun(SingleRunInfo(path, root, opts.verboseLog),
deleteEmpty)
@ -257,7 +257,7 @@ def dumpScanBuildResultsDiff(dirA, dirB, opts, deleteEmpty=True):
# Load the run results.
resultsA = loadResults(dirA, opts, opts.rootA, deleteEmpty)
resultsB = loadResults(dirB, opts, opts.rootB, deleteEmpty)
# Open the verbose log, if given.
if opts.verboseLog:
auxLog = open(opts.verboseLog, "wb")
@ -285,7 +285,7 @@ def dumpScanBuildResultsDiff(dirA, dirB, opts, deleteEmpty=True):
b.getReadableName())
foundDiffs += 1
if auxLog:
print >>auxLog, ("('CHANGED', %r, %r, %r, %r)"
print >>auxLog, ("('CHANGED', %r, %r, %r, %r)"
% (a.getReadableName(),
b.getReadableName(),
a.getReport(),
@ -299,7 +299,7 @@ def dumpScanBuildResultsDiff(dirA, dirB, opts, deleteEmpty=True):
if auxLog:
print >>auxLog, "('TOTAL NEW REPORTS', %r)" % TotalReports
print >>auxLog, "('TOTAL DIFFERENCES', %r)" % foundDiffs
return foundDiffs, len(resultsA.diagnostics), len(resultsB.diagnostics)
def main():
@ -322,7 +322,7 @@ def main():
dirA,dirB = args
dumpScanBuildResultsDiff(dirA, dirB, opts)
dumpScanBuildResultsDiff(dirA, dirB, opts)
if __name__ == '__main__':
main()

View File

@ -1,20 +1,20 @@
#!/usr/bin/env python
"""
Static Analyzer qualification infrastructure: adding a new project to
Static Analyzer qualification infrastructure: adding a new project to
the Repository Directory.
Add a new project for testing: build it and add to the Project Map file.
Assumes it's being run from the Repository Directory.
The project directory should be added inside the Repository Directory and
The project directory should be added inside the Repository Directory and
have the same name as the project ID
The project should use the following files for set up:
- pre_run_static_analyzer.sh - prepare the build environment.
Ex: make clean can be a part of it.
- run_static_analyzer.cmd - a list of commands to run through scan-build.
Each command should be on a separate line.
Choose from: configure, make, xcodebuild
Choose from: configure, make, xcodebuild
"""
import SATestBuild
@ -27,7 +27,7 @@ def isExistingProject(PMapFile, projectID) :
for I in PMapReader:
if projectID == I[0]:
return True
return False
return False
# Add a new project for testing: build it and add to the Project Map file.
# Params:
@ -39,7 +39,7 @@ def addNewProject(ID, BuildMode) :
if not os.path.exists(Dir):
print "Error: Project directory is missing: %s" % Dir
sys.exit(-1)
# Build the project.
SATestBuild.testProject(ID, BuildMode, IsReferenceBuild=True, Dir=Dir)
@ -51,19 +51,19 @@ def addNewProject(ID, BuildMode) :
print "Warning: Creating the Project Map file!!"
PMapFile = open(ProjectMapPath, "w+b")
try:
if (isExistingProject(PMapFile, ID)) :
if (isExistingProject(PMapFile, ID)) :
print >> sys.stdout, 'Warning: Project with ID \'', ID, \
'\' already exists.'
print >> sys.stdout, "Reference output has been regenerated."
else:
else:
PMapWriter = csv.writer(PMapFile)
PMapWriter.writerow( (ID, int(BuildMode)) );
print "The project map is updated: ", ProjectMapPath
finally:
PMapFile.close()
# TODO: Add an option not to build.
# TODO: Add an option not to build.
# TODO: Set the path to the Repository directory.
if __name__ == '__main__':
if len(sys.argv) < 2:
@ -73,10 +73,10 @@ if __name__ == '__main__':
'1 for scan_build; ' \
'2 for single file c++11 project'
sys.exit(-1)
BuildMode = 1
BuildMode = 1
if (len(sys.argv) >= 3):
BuildMode = int(sys.argv[2])
BuildMode = int(sys.argv[2])
assert((BuildMode == 0) | (BuildMode == 1) | (BuildMode == 2))
addNewProject(sys.argv[1], BuildMode)

View File

@ -6,8 +6,8 @@ Static Analyzer qualification infrastructure.
The goal is to test the analyzer against different projects, check for failures,
compare results, and measure performance.
Repository Directory will contain sources of the projects as well as the
information on how to build them and the expected output.
Repository Directory will contain sources of the projects as well as the
information on how to build them and the expected output.
Repository Directory structure:
- ProjectMap file
- Historical Performance Data
@ -19,16 +19,16 @@ Repository Directory structure:
Note that the build tree must be inside the project dir.
To test the build of the analyzer one would:
- Copy over a copy of the Repository Directory. (TODO: Prefer to ensure that
- Copy over a copy of the Repository Directory. (TODO: Prefer to ensure that
the build directory does not pollute the repository to min network traffic).
- Build all projects, until error. Produce logs to report errors.
- Compare results.
- Compare results.
The files which should be kept around for failure investigations:
The files which should be kept around for failure investigations:
RepositoryCopy/Project DirI/ScanBuildResults
RepositoryCopy/Project DirI/run_static_analyzer.log
Assumptions (TODO: shouldn't need to assume these.):
RepositoryCopy/Project DirI/run_static_analyzer.log
Assumptions (TODO: shouldn't need to assume these.):
The script is being run from the Repository Directory.
The compiler for scan-build and scan-build are in the PATH.
export PATH=/Users/zaks/workspace/c2llvm/build/Release+Asserts/bin:$PATH
@ -36,7 +36,7 @@ Assumptions (TODO: shouldn't need to assume these.):
For more logging, set the env variables:
zaks:TI zaks$ export CCC_ANALYZER_LOG=1
zaks:TI zaks$ export CCC_ANALYZER_VERBOSE=1
The list of checkers tested are hardcoded in the Checkers variable.
For testing additional checkers, use the SA_ADDITIONAL_CHECKERS environment
variable. It should contain a comma separated list.
@ -120,16 +120,16 @@ class flushfile(object):
sys.stdout = flushfile(sys.stdout)
def getProjectMapPath():
ProjectMapPath = os.path.join(os.path.abspath(os.curdir),
ProjectMapPath = os.path.join(os.path.abspath(os.curdir),
ProjectMapFile)
if not os.path.exists(ProjectMapPath):
print "Error: Cannot find the Project Map file " + ProjectMapPath +\
"\nRunning script for the wrong directory?"
sys.exit(-1)
return ProjectMapPath
sys.exit(-1)
return ProjectMapPath
def getProjectDir(ID):
return os.path.join(os.path.abspath(os.curdir), ID)
return os.path.join(os.path.abspath(os.curdir), ID)
def getSBOutputDirName(IsReferenceBuild) :
if IsReferenceBuild == True :
@ -156,13 +156,13 @@ ProjectMapFile = "projectMap.csv"
# Names of the project specific scripts.
# The script that needs to be executed before the build can start.
CleanupScript = "cleanup_run_static_analyzer.sh"
# This is a file containing commands for scan-build.
# This is a file containing commands for scan-build.
BuildScript = "run_static_analyzer.cmd"
# The log file name.
LogFolderName = "Logs"
BuildLogName = "run_static_analyzer.log"
# Summary file - contains the summary of the failures. Ex: This info can be be
# Summary file - contains the summary of the failures. Ex: This info can be be
# displayed when buildbot detects a build failure.
NumOfFailuresInSummary = 10
FailuresSummaryFileName = "failures.txt"
@ -189,21 +189,21 @@ def runCleanupScript(Dir, PBuildLogFile):
ScriptPath = os.path.join(Dir, CleanupScript)
if os.path.exists(ScriptPath):
try:
if Verbose == 1:
if Verbose == 1:
print " Executing: %s" % (ScriptPath,)
check_call("chmod +x %s" % ScriptPath, cwd = Dir,
check_call("chmod +x %s" % ScriptPath, cwd = Dir,
stderr=PBuildLogFile,
stdout=PBuildLogFile,
shell=True)
stdout=PBuildLogFile,
shell=True)
check_call(ScriptPath, cwd = Dir, stderr=PBuildLogFile,
stdout=PBuildLogFile,
stdout=PBuildLogFile,
shell=True)
except:
print "Error: The pre-processing step failed. See ", \
PBuildLogFile.name, " for details."
sys.exit(-1)
# Build the project with scan-build by reading in the commands and
# Build the project with scan-build by reading in the commands and
# prefixing them with the scan-build options.
def runScanBuild(Dir, SBOutputDir, PBuildLogFile):
BuildScriptPath = os.path.join(Dir, BuildScript)
@ -212,9 +212,9 @@ def runScanBuild(Dir, SBOutputDir, PBuildLogFile):
sys.exit(-1)
SBOptions = "--use-analyzer " + Clang + " "
SBOptions += "-plist-html -o " + SBOutputDir + " "
SBOptions += "-enable-checker " + Checkers + " "
SBOptions += "-enable-checker " + Checkers + " "
SBOptions += "--keep-empty "
# Always use ccc-analyze to ensure that we can locate the failures
# Always use ccc-analyze to ensure that we can locate the failures
# directory.
SBOptions += "--override-compiler "
try:
@ -231,10 +231,10 @@ def runScanBuild(Dir, SBOutputDir, PBuildLogFile):
"-j" not in Command:
Command += " -j%d" % Jobs
SBCommand = SBPrefix + Command
if Verbose == 1:
if Verbose == 1:
print " Executing: %s" % (SBCommand,)
check_call(SBCommand, cwd = Dir, stderr=PBuildLogFile,
stdout=PBuildLogFile,
stdout=PBuildLogFile,
shell=True)
except:
print "Error: scan-build failed. See ",PBuildLogFile.name,\
@ -249,97 +249,97 @@ def hasNoExtension(FileName):
def isValidSingleInputFile(FileName):
(Root, Ext) = os.path.splitext(FileName)
if ((Ext == ".i") | (Ext == ".ii") |
(Ext == ".c") | (Ext == ".cpp") |
if ((Ext == ".i") | (Ext == ".ii") |
(Ext == ".c") | (Ext == ".cpp") |
(Ext == ".m") | (Ext == "")) :
return True
return False
# Run analysis on a set of preprocessed files.
def runAnalyzePreprocessed(Dir, SBOutputDir, Mode):
if os.path.exists(os.path.join(Dir, BuildScript)):
print "Error: The preprocessed files project should not contain %s" % \
BuildScript
raise Exception()
raise Exception()
CmdPrefix = Clang + " -cc1 -analyze -analyzer-output=plist -w "
CmdPrefix += "-analyzer-checker=" + Checkers +" -fcxx-exceptions -fblocks "
CmdPrefix += "-analyzer-checker=" + Checkers +" -fcxx-exceptions -fblocks "
if (Mode == 2) :
CmdPrefix += "-std=c++11 "
CmdPrefix += "-std=c++11 "
PlistPath = os.path.join(Dir, SBOutputDir, "date")
FailPath = os.path.join(PlistPath, "failures");
os.makedirs(FailPath);
for FullFileName in glob.glob(Dir + "/*"):
FileName = os.path.basename(FullFileName)
Failed = False
# Only run the analyzes on supported files.
if (hasNoExtension(FileName)):
continue
if (isValidSingleInputFile(FileName) == False):
print "Error: Invalid single input file %s." % (FullFileName,)
raise Exception()
# Build and call the analyzer command.
OutputOption = "-o " + os.path.join(PlistPath, FileName) + ".plist "
Command = CmdPrefix + OutputOption + FileName
LogFile = open(os.path.join(FailPath, FileName + ".stderr.txt"), "w+b")
try:
if Verbose == 1:
if Verbose == 1:
print " Executing: %s" % (Command,)
check_call(Command, cwd = Dir, stderr=LogFile,
stdout=LogFile,
stdout=LogFile,
shell=True)
except CalledProcessError, e:
print "Error: Analyzes of %s failed. See %s for details." \
"Error code %d." % \
(FullFileName, LogFile.name, e.returncode)
Failed = True
Failed = True
finally:
LogFile.close()
LogFile.close()
# If command did not fail, erase the log file.
if Failed == False:
os.remove(LogFile.name);
def buildProject(Dir, SBOutputDir, ProjectBuildMode, IsReferenceBuild):
TBegin = time.time()
TBegin = time.time()
BuildLogPath = os.path.join(SBOutputDir, LogFolderName, BuildLogName)
print "Log file: %s" % (BuildLogPath,)
print "Log file: %s" % (BuildLogPath,)
print "Output directory: %s" %(SBOutputDir, )
# Clean up the log file.
if (os.path.exists(BuildLogPath)) :
RmCommand = "rm " + BuildLogPath
if Verbose == 1:
print " Executing: %s" % (RmCommand,)
check_call(RmCommand, shell=True)
# Clean up scan build results.
if (os.path.exists(SBOutputDir)) :
RmCommand = "rm -r " + SBOutputDir
if Verbose == 1:
if Verbose == 1:
print " Executing: %s" % (RmCommand,)
check_call(RmCommand, shell=True)
assert(not os.path.exists(SBOutputDir))
os.makedirs(os.path.join(SBOutputDir, LogFolderName))
# Open the log file.
PBuildLogFile = open(BuildLogPath, "wb+")
# Build and analyze the project.
try:
runCleanupScript(Dir, PBuildLogFile)
if (ProjectBuildMode == 1):
runScanBuild(Dir, SBOutputDir, PBuildLogFile)
else:
runAnalyzePreprocessed(Dir, SBOutputDir, ProjectBuildMode)
if IsReferenceBuild :
runCleanupScript(Dir, PBuildLogFile)
@ -354,28 +354,28 @@ def buildProject(Dir, SBOutputDir, ProjectBuildMode, IsReferenceBuild):
else SourceFile for SourceFile in Data['files']]
Data['files'] = Paths
plistlib.writePlist(Data, Plist)
finally:
PBuildLogFile.close()
print "Build complete (time: %.2f). See the log for more details: %s" % \
((time.time()-TBegin), BuildLogPath)
((time.time()-TBegin), BuildLogPath)
# A plist file is created for each call to the analyzer(each source file).
# We are only interested on the once that have bug reports, so delete the rest.
# We are only interested on the once that have bug reports, so delete the rest.
def CleanUpEmptyPlists(SBOutputDir):
for F in glob.glob(SBOutputDir + "/*/*.plist"):
P = os.path.join(SBOutputDir, F)
Data = plistlib.readPlist(P)
# Delete empty reports.
if not Data['files']:
os.remove(P)
continue
# Given the scan-build output directory, checks if the build failed
# (by searching for the failures directories). If there are failures, it
# creates a summary file in the output directory.
# Given the scan-build output directory, checks if the build failed
# (by searching for the failures directories). If there are failures, it
# creates a summary file in the output directory.
def checkBuild(SBOutputDir):
# Check if there are failures.
Failures = glob.glob(SBOutputDir + "/*/failures/*.stderr.txt")
@ -386,37 +386,37 @@ def checkBuild(SBOutputDir):
print "Number of bug reports (non-empty plist files) produced: %d" %\
len(Plists)
return;
# Create summary file to display when the build fails.
SummaryPath = os.path.join(SBOutputDir, LogFolderName, FailuresSummaryFileName)
if (Verbose > 0):
print " Creating the failures summary file %s" % (SummaryPath,)
SummaryLog = open(SummaryPath, "w+")
try:
SummaryLog.write("Total of %d failures discovered.\n" % (TotalFailed,))
if TotalFailed > NumOfFailuresInSummary:
SummaryLog.write("See the first %d below.\n"
SummaryLog.write("See the first %d below.\n"
% (NumOfFailuresInSummary,))
# TODO: Add a line "See the results folder for more."
FailuresCopied = NumOfFailuresInSummary
Idx = 0
for FailLogPathI in Failures:
if Idx >= NumOfFailuresInSummary:
break;
Idx += 1
Idx += 1
SummaryLog.write("\n-- Error #%d -----------\n" % (Idx,));
FailLogI = open(FailLogPathI, "r");
try:
try:
shutil.copyfileobj(FailLogI, SummaryLog);
finally:
FailLogI.close()
finally:
SummaryLog.close()
print "Error: analysis failed. See ", SummaryPath
sys.exit(-1)
sys.exit(-1)
# Auxiliary object to discard stdout.
class Discarder(object):
@ -428,44 +428,44 @@ class Discarder(object):
# 0 - success if there are no crashes or analyzer failure.
# 1 - success if there are no difference in the number of reported bugs.
# 2 - success if all the bug reports are identical.
def runCmpResults(Dir, Strictness = 0):
TBegin = time.time()
def runCmpResults(Dir, Strictness = 0):
TBegin = time.time()
RefDir = os.path.join(Dir, SBOutputDirReferencePrefix + SBOutputDirName)
NewDir = os.path.join(Dir, SBOutputDirName)
# We have to go one level down the directory tree.
RefList = glob.glob(RefDir + "/*")
RefList = glob.glob(RefDir + "/*")
NewList = glob.glob(NewDir + "/*")
# Log folders are also located in the results dir, so ignore them.
RefLogDir = os.path.join(RefDir, LogFolderName)
if RefLogDir in RefList:
RefList.remove(RefLogDir)
NewList.remove(os.path.join(NewDir, LogFolderName))
if len(RefList) == 0 or len(NewList) == 0:
return False
assert(len(RefList) == len(NewList))
# There might be more then one folder underneath - one per each scan-build
# There might be more then one folder underneath - one per each scan-build
# command (Ex: one for configure and one for make).
if (len(RefList) > 1):
# Assume that the corresponding folders have the same names.
RefList.sort()
NewList.sort()
# Iterate and find the differences.
NumDiffs = 0
PairList = zip(RefList, NewList)
for P in PairList:
RefDir = P[0]
PairList = zip(RefList, NewList)
for P in PairList:
RefDir = P[0]
NewDir = P[1]
assert(RefDir != NewDir)
if Verbose == 1:
assert(RefDir != NewDir)
if Verbose == 1:
print " Comparing Results: %s %s" % (RefDir, NewDir)
DiffsPath = os.path.join(NewDir, DiffsSummaryFileName)
Opts = CmpRuns.CmpOptions(DiffsPath, "", Dir)
# Discard everything coming out of stdout (CmpRun produces a lot of them).
@ -480,70 +480,70 @@ def runCmpResults(Dir, Strictness = 0):
(NumDiffs, DiffsPath,)
if Strictness >= 2 and NumDiffs > 0:
print "Error: Diffs found in strict mode (2)."
sys.exit(-1)
sys.exit(-1)
elif Strictness >= 1 and ReportsInRef != ReportsInNew:
print "Error: The number of results are different in strict mode (1)."
sys.exit(-1)
print "Diagnostic comparison complete (time: %.2f)." % (time.time()-TBegin)
sys.exit(-1)
print "Diagnostic comparison complete (time: %.2f)." % (time.time()-TBegin)
return (NumDiffs > 0)
def updateSVN(Mode, ProjectsMap):
try:
ProjectsMap.seek(0)
ProjectsMap.seek(0)
for I in csv.reader(ProjectsMap):
ProjName = I[0]
ProjName = I[0]
Path = os.path.join(ProjName, getSBOutputDirName(True))
if Mode == "delete":
Command = "svn delete %s" % (Path,)
else:
Command = "svn add %s" % (Path,)
if Verbose == 1:
if Verbose == 1:
print " Executing: %s" % (Command,)
check_call(Command, shell=True)
check_call(Command, shell=True)
if Mode == "delete":
CommitCommand = "svn commit -m \"[analyzer tests] Remove " \
"reference results.\""
"reference results.\""
else:
CommitCommand = "svn commit -m \"[analyzer tests] Add new " \
"reference results.\""
if Verbose == 1:
if Verbose == 1:
print " Executing: %s" % (CommitCommand,)
check_call(CommitCommand, shell=True)
check_call(CommitCommand, shell=True)
except:
print "Error: SVN update failed."
sys.exit(-1)
def testProject(ID, ProjectBuildMode, IsReferenceBuild=False, Dir=None, Strictness = 0):
print " \n\n--- Building project %s" % (ID,)
TBegin = time.time()
TBegin = time.time()
if Dir is None :
Dir = getProjectDir(ID)
if Verbose == 1:
Dir = getProjectDir(ID)
if Verbose == 1:
print " Build directory: %s." % (Dir,)
# Set the build results directory.
RelOutputDir = getSBOutputDirName(IsReferenceBuild)
SBOutputDir = os.path.join(Dir, RelOutputDir)
buildProject(Dir, SBOutputDir, ProjectBuildMode, IsReferenceBuild)
checkBuild(SBOutputDir)
if IsReferenceBuild == False:
runCmpResults(Dir, Strictness)
print "Completed tests for project %s (time: %.2f)." % \
(ID, (time.time()-TBegin))
def testAll(IsReferenceBuild = False, UpdateSVN = False, Strictness = 0):
PMapFile = open(getProjectMapPath(), "rb")
try:
try:
# Validate the input.
for I in csv.reader(PMapFile):
if (len(I) != 2) :
@ -552,16 +552,16 @@ def testAll(IsReferenceBuild = False, UpdateSVN = False, Strictness = 0):
if (not ((I[1] == "0") | (I[1] == "1") | (I[1] == "2"))):
print "Error: Second entry in the ProjectMapFile should be 0" \
" (single file), 1 (project), or 2(single file c++11)."
raise Exception()
raise Exception()
# When we are regenerating the reference results, we might need to
# When we are regenerating the reference results, we might need to
# update svn. Remove reference results from SVN.
if UpdateSVN == True:
assert(IsReferenceBuild == True);
updateSVN("delete", PMapFile);
# Test the projects.
PMapFile.seek(0)
PMapFile.seek(0)
for I in csv.reader(PMapFile):
testProject(I[0], int(I[1]), IsReferenceBuild, None, Strictness)
@ -571,10 +571,10 @@ def testAll(IsReferenceBuild = False, UpdateSVN = False, Strictness = 0):
except:
print "Error occurred. Premature termination."
raise
raise
finally:
PMapFile.close()
PMapFile.close()
if __name__ == '__main__':
# Parse command line arguments.
Parser = argparse.ArgumentParser(description='Test the Clang Static Analyzer.')

View File

@ -3,7 +3,7 @@
"""
Script to Summarize statistics in the scan-build output.
Statistics are enabled by passing '-internal-stats' option to scan-build
Statistics are enabled by passing '-internal-stats' option to scan-build
(or '-analyzer-stats' to the analyzer).
"""
@ -69,7 +69,7 @@ if __name__ == '__main__':
if ((") Total" in line) and (Mode == 1)) :
s = line.split()
TotalTime = TotalTime + float(s[6])
print "TU Count %d" % (Count)
print "Time %f" % (Time)
print "Warnings %d" % (Warnings)
@ -81,4 +81,3 @@ if __name__ == '__main__':
print "MaxTime %f" % (MaxTime)
print "TotalTime %f" % (TotalTime)
print "Max CFG Size %d" % (MaxCFGSize)

View File

@ -18,7 +18,7 @@ import sys
def Error(message):
print >> sys.stderr, 'ubiviz: ' + message
sys.exit(1)
def StreamData(filename):
file = open(filename)
for ln in file:
@ -55,20 +55,19 @@ def Display(G, data):
def main(args):
if len(args) == 0:
Error('no input files')
Error('no input files')
server = xmlrpclib.Server('http://127.0.0.1:20738/RPC2')
G = server.ubigraph
for arg in args:
G.clear()
for x in StreamData(arg):
Display(G,x)
sys.exit(0)
if __name__ == '__main__':
main(sys.argv[1:])