Introduce a new concept to the static analyzer: SValuator.

GRTransferFuncs had the conflated role of both constructing SVals (symbolic
expressions) as well as handling checker-specific logic. Now SValuator has the
role of constructing SVals from expressions and GRTransferFuncs just handles
checker-specific logic. The motivation is by separating these two concepts we
will be able to much more easily create richer constraint-generating logic
without coupling it to the main checker transfer function logic.

We now have one implementation of SValuator: SimpleSValuator.

SimpleSValuator is essentially the SVal-related logic that was in GRSimpleVals
(which is removed in this patch). This includes the logic for EvalBinOp,
EvalCast, etc. Because SValuator has a narrower role than the old
GRTransferFuncs, the interfaces are much simpler, and so is the implementation
of SimpleSValuator compared to GRSimpleVals. I also did a line-by-line review of
SVal-related logic in GRSimpleVals and cleaned it up while moving it over to
SimpleSValuator.

As a consequence of removing GRSimpleVals, there is no longer a
'-checker-simple' option. The '-checker-cfref' did everything that option did
but also ran the retain/release checker. Of course a user may not always wish to
run the retain/release checker, nor do we wish core analysis logic buried in the
checker-specific logic. The next step is to refactor the logic in CFRefCount.cpp
to separate out these pieces into the core analysis engine.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74229 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2009-06-26 00:05:51 +00:00
Родитель 72b60e3560
Коммит 6c07bdba93
32 изменённых файлов: 77 добавлений и 617 удалений

Просмотреть файл

@ -37,7 +37,6 @@ void CheckDeadStores(LiveVariables& L, BugReporter& BR);
void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags, void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
bool FullUninitTaint=false); bool FullUninitTaint=false);
GRTransferFuncs* MakeGRSimpleValsTF();
GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled, GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
const LangOptions& lopts); const LangOptions& lopts);

Просмотреть файл

@ -20,6 +20,7 @@
#include "clang/Analysis/PathSensitive/GRState.h" #include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h" #include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
#include "clang/Analysis/PathSensitive/GRTransferFuncs.h" #include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
#include "clang/Analysis/PathSensitive/SValuator.h"
#include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/AST/Type.h" #include "clang/AST/Type.h"
#include "clang/AST/ExprObjC.h" #include "clang/AST/ExprObjC.h"
@ -67,6 +68,9 @@ protected:
/// ValMgr - Object that manages/creates SVals. /// ValMgr - Object that manages/creates SVals.
ValueManager &ValMgr; ValueManager &ValMgr;
/// SVator - SValuator object that creates SVals from expressions.
llvm::OwningPtr<SValuator> SVator;
/// EntryNode - The immediate predecessor node. /// EntryNode - The immediate predecessor node.
NodeTy* EntryNode; NodeTy* EntryNode;
@ -603,41 +607,32 @@ protected:
return X; return X;
if (isa<Loc>(X)) if (isa<Loc>(X))
return getTF().EvalCast(*this, cast<Loc>(X), CastT); return SVator->EvalCast(cast<Loc>(X), CastT);
else else
return getTF().EvalCast(*this, cast<NonLoc>(X), CastT); return SVator->EvalCast(cast<NonLoc>(X), CastT);
} }
SVal EvalMinus(UnaryOperator* U, SVal X) { SVal EvalMinus(SVal X) {
return X.isValid() ? getTF().EvalMinus(*this, U, cast<NonLoc>(X)) : X; return X.isValid() ? SVator->EvalMinus(cast<NonLoc>(X)) : X;
} }
SVal EvalComplement(SVal X) { SVal EvalComplement(SVal X) {
return X.isValid() ? getTF().EvalComplement(*this, cast<NonLoc>(X)) : X; return X.isValid() ? SVator->EvalComplement(cast<NonLoc>(X)) : X;
} }
public: public:
SVal EvalBinOp(BinaryOperator::Opcode Op, NonLoc L, NonLoc R, QualType T) { SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T) {
return R.isValid() ? getTF().DetermEvalBinOpNN(*this, Op, L, R, T) return SVator->EvalBinOpNN(op, L, R, T);
: R;
} }
SVal EvalBinOp(BinaryOperator::Opcode Op, NonLoc L, SVal R, QualType T) { SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, SVal R, QualType T) {
return R.isValid() ? getTF().DetermEvalBinOpNN(*this, Op, L, return R.isValid() ? SVator->EvalBinOpNN(op, L, cast<NonLoc>(R), T) : R;
cast<NonLoc>(R), T) : R;
} }
void EvalBinOp(ExplodedNodeSet<GRState>& Dst, Expr* Ex, SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
BinaryOperator::Opcode Op, NonLoc L, NonLoc R, SVal lhs, SVal rhs, QualType T);
ExplodedNode<GRState>* Pred, QualType T);
void EvalBinOp(GRStateSet& OStates, const GRState* St, Expr* Ex,
BinaryOperator::Opcode Op, NonLoc L, NonLoc R, QualType T);
SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op, SVal L,SVal R,
QualType T);
protected: protected:
void EvalCall(NodeSet& Dst, CallExpr* CE, SVal L, NodeTy* Pred); void EvalCall(NodeSet& Dst, CallExpr* CE, SVal L, NodeTy* Pred);

Просмотреть файл

@ -22,20 +22,12 @@
namespace clang { namespace clang {
class GRExprEngine; class GRExprEngine;
class BugReporter; class BugReporter;
class ObjCMessageExpr; class ObjCMessageExpr;
class GRStmtNodeBuilderRef; class GRStmtNodeBuilderRef;
class GRTransferFuncs { class GRTransferFuncs {
friend class GRExprEngine;
protected:
virtual SVal DetermEvalBinOpNN(GRExprEngine& Eng,
BinaryOperator::Opcode Op,
NonLoc L, NonLoc R, QualType T) {
return UnknownVal();
}
public: public:
GRTransferFuncs() {} GRTransferFuncs() {}
virtual ~GRTransferFuncs() {} virtual ~GRTransferFuncs() {}
@ -43,33 +35,7 @@ public:
virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {} virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {}
virtual void RegisterChecks(BugReporter& BR) {} virtual void RegisterChecks(BugReporter& BR) {}
// Casts.
virtual SVal EvalCast(GRExprEngine& Engine, NonLoc V, QualType CastT) =0;
virtual SVal EvalCast(GRExprEngine& Engine, Loc V, QualType CastT) = 0;
// Unary Operators.
virtual SVal EvalMinus(GRExprEngine& Engine, UnaryOperator* U, NonLoc X) = 0;
virtual SVal EvalComplement(GRExprEngine& Engine, NonLoc X) = 0;
// Binary Operators.
// FIXME: We're moving back towards using GREXprEngine directly. No need
// for OStates
virtual void EvalBinOpNN(GRStateSet& OStates, GRExprEngine& Eng,
const GRState* St, Expr* Ex,
BinaryOperator::Opcode Op, NonLoc L, NonLoc R,
QualType T);
virtual SVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
Loc L, Loc R) = 0;
// Pointer arithmetic.
virtual SVal EvalBinOp(GRExprEngine& Engine, const GRState *state,
BinaryOperator::Opcode Op, Loc L, NonLoc R) = 0;
// Calls. // Calls.
virtual void EvalCall(ExplodedNodeSet<GRState>& Dst, virtual void EvalCall(ExplodedNodeSet<GRState>& Dst,
@ -108,8 +74,7 @@ public:
ReturnStmt* S, ReturnStmt* S,
ExplodedNode<GRState>* Pred) {} ExplodedNode<GRState>* Pred) {}
// Assumptions. // Assumptions.
virtual const GRState* EvalAssume(const GRState *state, virtual const GRState* EvalAssume(const GRState *state,
SVal Cond, bool Assumption) { SVal Cond, bool Assumption) {
return state; return state;

Просмотреть файл

@ -254,12 +254,12 @@ public:
} }
// Transfer functions for binary/unary operations on ConcreteInts. // Transfer functions for binary/unary operations on ConcreteInts.
SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op, SVal evalBinOp(ValueManager &ValMgr, BinaryOperator::Opcode Op,
const ConcreteInt& R) const; const ConcreteInt& R) const;
ConcreteInt EvalComplement(BasicValueFactory& BasicVals) const; ConcreteInt evalComplement(ValueManager &ValMgr) const;
ConcreteInt EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const; ConcreteInt evalMinus(ValueManager &ValMgr) const;
// Implement isa<T> support. // Implement isa<T> support.
static inline bool classof(const SVal* V) { static inline bool classof(const SVal* V) {

Просмотреть файл

@ -138,7 +138,7 @@ public:
/// EvalBinOp - Perform pointer arithmetic. /// EvalBinOp - Perform pointer arithmetic.
virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op, virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,
Loc lhs, NonLoc rhs) { Loc lhs, NonLoc rhs, QualType resultTy) {
return UnknownVal(); return UnknownVal();
} }

Просмотреть файл

@ -87,14 +87,18 @@ public:
return nonloc::ConcreteInt(BasicVals.getZeroWithPtrWidth(false)); return nonloc::ConcreteInt(BasicVals.getZeroWithPtrWidth(false));
} }
NonLoc makeIntVal(const IntegerLiteral* I) { nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) {
return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(), return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
I->getType()->isUnsignedIntegerType())); I->getType()->isUnsignedIntegerType()));
} }
NonLoc makeIntVal(const llvm::APSInt& V) { nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) {
return nonloc::ConcreteInt(BasicVals.getValue(V)); return nonloc::ConcreteInt(BasicVals.getValue(V));
} }
loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) {
return loc::ConcreteInt(BasicVals.getValue(v));
}
NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) { NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) {
return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned)); return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned));

Просмотреть файл

@ -41,13 +41,9 @@ ANALYSIS(WarnObjCDealloc, "warn-objc-missing-dealloc",
ANALYSIS(WarnObjCUnusedIvars, "warn-objc-unused-ivars", ANALYSIS(WarnObjCUnusedIvars, "warn-objc-unused-ivars",
"Warn about private ivars that are never used", ObjCImplementation) "Warn about private ivars that are never used", ObjCImplementation)
ANALYSIS(CheckerSimple, "checker-simple",
"Perform simple path-sensitive checks.", Code)
ANALYSIS(CheckerCFRef, "checker-cfref", ANALYSIS(CheckerCFRef, "checker-cfref",
"Run the [Core] Foundation reference count checker", Code) "Run the [Core] Foundation reference count checker", Code)
#ifndef ANALYSIS_STORE #ifndef ANALYSIS_STORE
#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)
#endif #endif

Просмотреть файл

@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file defines BugReporter, a utility class for generating // This file defines BugReporter, a utility class for generating
// PathDiagnostics for analyses based on GRSimpleVals. // PathDiagnostics.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

Просмотреть файл

@ -12,7 +12,6 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "GRSimpleVals.h"
#include "clang/Basic/LangOptions.h" #include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManager.h"
#include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h" #include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h"
@ -22,6 +21,7 @@
#include "clang/Analysis/PathDiagnostic.h" #include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/PathSensitive/SymbolManager.h" #include "clang/Analysis/PathSensitive/SymbolManager.h"
#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclObjC.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/FoldingSet.h"
@ -1826,7 +1826,7 @@ static const GRState * SendAutorelease(const GRState *state,
namespace { namespace {
class VISIBILITY_HIDDEN CFRefCount : public GRSimpleVals { class VISIBILITY_HIDDEN CFRefCount : public GRTransferFuncs {
public: public:
class BindingsPrinter : public GRState::Printer { class BindingsPrinter : public GRState::Printer {
public: public:
@ -2789,10 +2789,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
if (Summ.getArg(idx) == DoNothingByRef) if (Summ.getArg(idx) == DoNothingByRef)
continue; continue;
// Invalidate the value of the variable passed by reference. // Invalidate the value of the variable passed by reference.
// FIXME: Either this logic should also be replicated in GRSimpleVals
// or should be pulled into a separate "constraint engine."
// FIXME: We can have collisions on the conjured symbol if the // FIXME: We can have collisions on the conjured symbol if the
// expression *I also creates conjured symbols. We probably want // expression *I also creates conjured symbols. We probably want
@ -2941,11 +2938,10 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
default: default:
assert (false && "Unhandled RetEffect."); break; assert (false && "Unhandled RetEffect."); break;
case RetEffect::NoRet: { case RetEffect::NoRet: {
// Make up a symbol for the return value (not reference counted). // Make up a symbol for the return value (not reference counted).
// FIXME: This is basically copy-and-paste from GRSimpleVals. We // FIXME: Most of this logic is not specific to the retain/release
// should compose behavior, not copy it. // checker.
// FIXME: We eventually should handle structs and other compound types // FIXME: We eventually should handle structs and other compound types
// that are returned by value. // that are returned by value.

Просмотреть файл

@ -18,15 +18,14 @@ add_clang_library(clangAnalysis
GRCoreEngine.cpp GRCoreEngine.cpp
GRExprEngine.cpp GRExprEngine.cpp
GRExprEngineInternalChecks.cpp GRExprEngineInternalChecks.cpp
GRSimpleVals.cpp
GRState.cpp GRState.cpp
GRTransferFuncs.cpp
LiveVariables.cpp LiveVariables.cpp
MemRegion.cpp MemRegion.cpp
PathDiagnostic.cpp PathDiagnostic.cpp
RangeConstraintManager.cpp RangeConstraintManager.cpp
RegionStore.cpp RegionStore.cpp
SimpleConstraintManager.cpp SimpleConstraintManager.cpp
SimpleSValuator.cpp
Store.cpp Store.cpp
SVals.cpp SVals.cpp
SymbolManager.cpp SymbolManager.cpp

Просмотреть файл

@ -15,7 +15,6 @@
#include "clang/Analysis/PathSensitive/GRExprEngine.h" #include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h" #include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/AST/ParentMap.h" #include "clang/AST/ParentMap.h"
#include "clang/AST/StmtObjC.h" #include "clang/AST/StmtObjC.h"
#include "clang/Basic/Builtins.h" #include "clang/Basic/Builtins.h"
@ -126,6 +125,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
StateMgr(G.getContext(), SMC, CMC, G.getAllocator(), cfg, CD, L), StateMgr(G.getContext(), SMC, CMC, G.getAllocator(), cfg, CD, L),
SymMgr(StateMgr.getSymbolManager()), SymMgr(StateMgr.getSymbolManager()),
ValMgr(StateMgr.getValueManager()), ValMgr(StateMgr.getValueManager()),
SVator(clang::CreateSimpleSValuator(ValMgr)), // FIXME: Generalize later.
CurrentStmt(NULL), CurrentStmt(NULL),
NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL), NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
RaiseSel(GetNullarySelector("raise", G.getContext())), RaiseSel(GetNullarySelector("raise", G.getContext())),
@ -1296,9 +1296,8 @@ static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet<GRState>& Dst,
SVal oldValueVal = stateLoad->getSVal(oldValueExpr); SVal oldValueVal = stateLoad->getSVal(oldValueExpr);
// Perform the comparison. // Perform the comparison.
SVal Cmp = Engine.EvalBinOp(stateLoad, SVal Cmp = Engine.EvalBinOp(stateLoad, BinaryOperator::EQ, theValueVal,
BinaryOperator::EQ, theValueVal, oldValueVal, oldValueVal, Engine.getContext().IntTy);
Engine.getContext().IntTy);
const GRState *stateEqual = stateLoad->assume(Cmp, true); const GRState *stateEqual = stateLoad->assume(Cmp, true);
@ -2562,7 +2561,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
case UnaryOperator::Minus: case UnaryOperator::Minus:
// FIXME: Do we need to handle promotions? // FIXME: Do we need to handle promotions?
state = state->bindExpr(U, EvalMinus(U, cast<NonLoc>(V))); state = state->bindExpr(U, EvalMinus(cast<NonLoc>(V)));
break; break;
case UnaryOperator::LNot: case UnaryOperator::LNot:
@ -2571,25 +2570,21 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
// //
// Note: technically we do "E == 0", but this is the same in the // Note: technically we do "E == 0", but this is the same in the
// transfer functions as "0 == E". // transfer functions as "0 == E".
SVal Result;
if (isa<Loc>(V)) { if (isa<Loc>(V)) {
Loc X = ValMgr.makeNull(); Loc X = ValMgr.makeNull();
SVal Result = EvalBinOp(state,BinaryOperator::EQ, cast<Loc>(V), X, Result = EvalBinOp(state, BinaryOperator::EQ, cast<Loc>(V), X,
U->getType()); U->getType());
state = state->bindExpr(U, Result);
} }
else { else {
nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType())); nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
#if 0 Result = EvalBinOp(BinaryOperator::EQ, cast<NonLoc>(V), X,
SVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLoc>(V), X); U->getType());
state = SetSVal(state, U, Result);
#else
EvalBinOp(Dst, U, BinaryOperator::EQ, cast<NonLoc>(V), X, *I,
U->getType());
continue;
#endif
} }
state = state->bindExpr(U, Result);
break; break;
} }
@ -2640,8 +2635,8 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
Builder->getCurrentBlockCount()); Builder->getCurrentBlockCount());
// If the value is a location, ++/-- should always preserve // If the value is a location, ++/-- should always preserve
// non-nullness. Check if the original value was non-null, and if so propagate // non-nullness. Check if the original value was non-null, and if so
// that constraint. // propagate that constraint.
if (Loc::IsLocType(U->getType())) { if (Loc::IsLocType(U->getType())) {
SVal Constraint = EvalBinOp(state, BinaryOperator::EQ, V2, SVal Constraint = EvalBinOp(state, BinaryOperator::EQ, V2,
ValMgr.makeZeroVal(U->getType()), ValMgr.makeZeroVal(U->getType()),
@ -2907,9 +2902,8 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
if (B->isAssignmentOp()) if (B->isAssignmentOp())
break; break;
// Process non-assignements except commas or short-circuited // Process non-assignments except commas or short-circuited
// logical expressions (LAnd and LOr). // 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()) { if (Result.isUnknown()) {
@ -3024,7 +3018,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
} }
// Compute the result of the operation. // Compute the result of the operation.
SVal Result = EvalCast(EvalBinOp(state, Op, V, RightV, CTy), SVal Result = EvalCast(EvalBinOp(state, Op, V, RightV, CTy),
B->getType()); B->getType());
if (Result.isUndef()) { if (Result.isUndef()) {
@ -3073,26 +3067,6 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
// Transfer-function Helpers. // Transfer-function Helpers.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
void GRExprEngine::EvalBinOp(ExplodedNodeSet<GRState>& Dst, Expr* Ex,
BinaryOperator::Opcode Op,
NonLoc L, NonLoc R,
ExplodedNode<GRState>* Pred, QualType T) {
GRStateSet OStates;
EvalBinOp(OStates, GetState(Pred), Ex, Op, L, R, T);
for (GRStateSet::iterator I=OStates.begin(), E=OStates.end(); I!=E; ++I)
MakeNode(Dst, Ex, Pred, *I);
}
void GRExprEngine::EvalBinOp(GRStateSet& OStates, const GRState* state,
Expr* Ex, BinaryOperator::Opcode Op,
NonLoc L, NonLoc R, QualType T) {
GRStateSet::AutoPopulate AP(OStates, state);
if (R.isValid()) getTF().EvalBinOpNN(OStates, *this, state, Ex, Op, L, R, T);
}
SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op, SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op,
SVal L, SVal R, QualType T) { SVal L, SVal R, QualType T) {
@ -3104,9 +3078,9 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op,
if (isa<Loc>(L)) { if (isa<Loc>(L)) {
if (isa<Loc>(R)) if (isa<Loc>(R))
return getTF().EvalBinOp(*this, Op, cast<Loc>(L), cast<Loc>(R)); return SVator->EvalBinOpLL(Op, cast<Loc>(L), cast<Loc>(R), T);
else else
return getTF().EvalBinOp(*this, state, Op, cast<Loc>(L), cast<NonLoc>(R)); return SVator->EvalBinOpLN(state, Op, cast<Loc>(L), cast<NonLoc>(R), T);
} }
if (isa<Loc>(R)) { if (isa<Loc>(R)) {
@ -3116,11 +3090,10 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op,
assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub); assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
// Commute the operands. // Commute the operands.
return getTF().EvalBinOp(*this, state, Op, cast<Loc>(R), cast<NonLoc>(L)); return SVator->EvalBinOpLN(state, Op, cast<Loc>(R), cast<NonLoc>(L), T);
} }
else else
return getTF().DetermEvalBinOpNN(*this, Op, cast<NonLoc>(L), return SVator->EvalBinOpNN(Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
cast<NonLoc>(R), T);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

Просмотреть файл

@ -1,414 +0,0 @@
// GRSimpleVals.cpp - Transfer functions for tracking simple values -*- C++ -*--
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines GRSimpleVals, a sub-class of GRTransferFuncs that
// provides transfer functions for performing simple value tracking with
// limited support for symbolics.
//
//===----------------------------------------------------------------------===//
#include "GRSimpleVals.h"
#include "BasicObjCFoundationChecks.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/LocalCheckers.h"
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "llvm/Support/Compiler.h"
#include <sstream>
using namespace clang;
//===----------------------------------------------------------------------===//
// Transfer Function creation for External clients.
//===----------------------------------------------------------------------===//
GRTransferFuncs* clang::MakeGRSimpleValsTF() { return new GRSimpleVals(); }
//===----------------------------------------------------------------------===//
// Transfer function for Casts.
//===----------------------------------------------------------------------===//
SVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLoc X, QualType T) {
if (!isa<nonloc::ConcreteInt>(X))
return UnknownVal();
bool isLocType = Loc::IsLocType(T);
// Only handle casts from integers to integers.
if (!isLocType && !T->isIntegerType())
return UnknownVal();
BasicValueFactory& BasicVals = Eng.getBasicVals();
llvm::APSInt V = cast<nonloc::ConcreteInt>(X).getValue();
V.setIsUnsigned(T->isUnsignedIntegerType() || Loc::IsLocType(T));
V.extOrTrunc(Eng.getContext().getTypeSize(T));
if (isLocType)
return loc::ConcreteInt(BasicVals.getValue(V));
else
return nonloc::ConcreteInt(BasicVals.getValue(V));
}
// Casts.
SVal GRSimpleVals::EvalCast(GRExprEngine& Eng, Loc X, QualType T) {
// Casts from pointers -> pointers, just return the lval.
//
// Casts from pointers -> references, just return the lval. These
// can be introduced by the frontend for corner cases, e.g
// casting from va_list* to __builtin_va_list&.
//
assert (!X.isUnknownOrUndef());
if (Loc::IsLocType(T) || T->isReferenceType())
return X;
// FIXME: Handle transparent unions where a value can be "transparently"
// lifted into a union type.
if (T->isUnionType())
return UnknownVal();
assert (T->isIntegerType());
BasicValueFactory& BasicVals = Eng.getBasicVals();
unsigned BitWidth = Eng.getContext().getTypeSize(T);
if (!isa<loc::ConcreteInt>(X))
return Eng.getValueManager().makeLocAsInteger(X, BitWidth);
llvm::APSInt V = cast<loc::ConcreteInt>(X).getValue();
V.setIsUnsigned(T->isUnsignedIntegerType() || Loc::IsLocType(T));
V.extOrTrunc(BitWidth);
return nonloc::ConcreteInt(BasicVals.getValue(V));
}
// Unary operators.
SVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLoc X){
switch (X.getSubKind()) {
case nonloc::ConcreteIntKind:
return cast<nonloc::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);
default:
return UnknownVal();
}
}
SVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLoc X) {
switch (X.getSubKind()) {
case nonloc::ConcreteIntKind:
return cast<nonloc::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());
default:
return UnknownVal();
}
}
// Binary operators.
static unsigned char LNotOpMap[] = {
(unsigned char) BinaryOperator::GE, /* LT => GE */
(unsigned char) BinaryOperator::LE, /* GT => LE */
(unsigned char) BinaryOperator::GT, /* LE => GT */
(unsigned char) BinaryOperator::LT, /* GE => LT */
(unsigned char) BinaryOperator::NE, /* EQ => NE */
(unsigned char) BinaryOperator::EQ /* NE => EQ */
};
SVal GRSimpleVals::DetermEvalBinOpNN(GRExprEngine& Eng,
BinaryOperator::Opcode Op,
NonLoc L, NonLoc R,
QualType T) {
BasicValueFactory& BasicVals = Eng.getBasicVals();
ValueManager& ValMgr = Eng.getValueManager();
unsigned subkind = L.getSubKind();
while (1) {
switch (subkind) {
default:
return UnknownVal();
case nonloc::LocAsIntegerKind: {
Loc LL = cast<nonloc::LocAsInteger>(L).getLoc();
switch (R.getSubKind()) {
case nonloc::LocAsIntegerKind:
return EvalBinOp(Eng, Op, LL,
cast<nonloc::LocAsInteger>(R).getLoc());
case nonloc::ConcreteIntKind: {
// Transform the integer into a location and compare.
ASTContext& Ctx = Eng.getContext();
llvm::APSInt V = cast<nonloc::ConcreteInt>(R).getValue();
V.setIsUnsigned(true);
V.extOrTrunc(Ctx.getTypeSize(Ctx.VoidPtrTy));
return EvalBinOp(Eng, Op, LL, ValMgr.makeLoc(V));
}
default:
switch (Op) {
case BinaryOperator::EQ:
return ValMgr.makeTruthVal(false);
case BinaryOperator::NE:
return ValMgr.makeTruthVal(true);
default:
// This case also handles pointer arithmetic.
return UnknownVal();
}
}
}
case nonloc::SymExprValKind: {
// Logical not?
if (!(Op == BinaryOperator::EQ && R.isZeroConstant()))
return UnknownVal();
const SymExpr &SE=*cast<nonloc::SymExprVal>(L).getSymbolicExpression();
// Only handle ($sym op constant) for now.
if (const SymIntExpr *E = dyn_cast<SymIntExpr>(&SE)) {
BinaryOperator::Opcode Opc = E->getOpcode();
if (Opc < BinaryOperator::LT || Opc > BinaryOperator::NE)
return UnknownVal();
// For comparison operators, translate the constraint by
// changing the opcode.
int idx = (unsigned) Opc - (unsigned) BinaryOperator::LT;
assert (idx >= 0 &&
(unsigned) idx < sizeof(LNotOpMap)/sizeof(unsigned char));
Opc = (BinaryOperator::Opcode) LNotOpMap[idx];
assert(E->getType(Eng.getContext()) == T);
E = Eng.getSymbolManager().getSymIntExpr(E->getLHS(), Opc,
E->getRHS(), T);
return nonloc::SymExprVal(E);
}
return UnknownVal();
}
case nonloc::ConcreteIntKind:
if (isa<nonloc::ConcreteInt>(R)) {
const nonloc::ConcreteInt& L_CI = cast<nonloc::ConcreteInt>(L);
const nonloc::ConcreteInt& R_CI = cast<nonloc::ConcreteInt>(R);
return L_CI.EvalBinOp(BasicVals, Op, R_CI);
}
else {
subkind = R.getSubKind();
NonLoc tmp = R;
R = L;
L = tmp;
// Swap the operators.
switch (Op) {
case BinaryOperator::LT: Op = BinaryOperator::GT; break;
case BinaryOperator::GT: Op = BinaryOperator::LT; break;
case BinaryOperator::LE: Op = BinaryOperator::GE; break;
case BinaryOperator::GE: Op = BinaryOperator::LE; break;
default: break;
}
continue;
}
case nonloc::SymbolValKind:
if (isa<nonloc::ConcreteInt>(R)) {
ValueManager &ValMgr = Eng.getValueManager();
return ValMgr.makeNonLoc(cast<nonloc::SymbolVal>(L).getSymbol(), Op,
cast<nonloc::ConcreteInt>(R).getValue(), T);
}
else
return UnknownVal();
}
}
}
// Binary Operators (except assignments and comma).
SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
Loc L, Loc R) {
switch (Op) {
default:
return UnknownVal();
case BinaryOperator::EQ:
case BinaryOperator::NE:
return EvalEquality(Eng, L, R, Op == BinaryOperator::EQ);
}
}
SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, const GRState *state,
BinaryOperator::Opcode Op, Loc L, NonLoc R) {
// Special case: 'R' is an integer that has the same width as a pointer and
// we are using the integer location in a comparison. Normally this cannot be
// triggered, but transfer functions like those for OSCommpareAndSwapBarrier32
// can generate comparisons that trigger this code.
// FIXME: Are all locations guaranteed to have pointer width?
if (BinaryOperator::isEqualityOp(Op)) {
if (nonloc::ConcreteInt *RInt = dyn_cast<nonloc::ConcreteInt>(&R)) {
const llvm::APSInt *X = &RInt->getValue();
ASTContext &C = Eng.getContext();
if (C.getTypeSize(C.VoidPtrTy) == X->getBitWidth()) {
// Convert the signedness of the integer (if necessary).
if (X->isSigned())
X = &Eng.getBasicVals().getValue(*X, true);
return EvalBinOp(Eng, Op, L, loc::ConcreteInt(*X));
}
}
}
// Delegate pointer arithmetic to store manager.
return Eng.getStoreManager().EvalBinOp(state, Op, L, R);
}
// Equality operators for Locs.
// FIXME: All this logic will be revamped when we have MemRegion::getLocation()
// implemented.
SVal GRSimpleVals::EvalEquality(GRExprEngine& Eng, Loc L, Loc R, bool isEqual) {
ValueManager& ValMgr = Eng.getValueManager();
switch (L.getSubKind()) {
default:
assert(false && "EQ/NE not implemented for this Loc.");
return UnknownVal();
case loc::ConcreteIntKind:
if (isa<loc::ConcreteInt>(R)) {
bool b = cast<loc::ConcreteInt>(L).getValue() ==
cast<loc::ConcreteInt>(R).getValue();
// Are we computing '!='? Flip the result.
if (!isEqual)
b = !b;
return ValMgr.makeTruthVal(b);
}
else if (SymbolRef Sym = R.getAsSymbol()) {
const SymIntExpr * SE =
Eng.getSymbolManager().getSymIntExpr(Sym,
isEqual ? BinaryOperator::EQ
: BinaryOperator::NE,
cast<loc::ConcreteInt>(L).getValue(),
Eng.getContext().IntTy);
return nonloc::SymExprVal(SE);
}
break;
case loc::MemRegionKind: {
if (SymbolRef LSym = L.getAsLocSymbol()) {
if (isa<loc::ConcreteInt>(R)) {
const SymIntExpr *SE =
Eng.getSymbolManager().getSymIntExpr(LSym,
isEqual ? BinaryOperator::EQ
: BinaryOperator::NE,
cast<loc::ConcreteInt>(R).getValue(),
Eng.getContext().IntTy);
return nonloc::SymExprVal(SE);
}
}
}
// Fall-through.
case loc::GotoLabelKind:
return ValMgr.makeTruthVal(isEqual ? L == R : L != R);
}
return ValMgr.makeTruthVal(isEqual ? false : true);
}
//===----------------------------------------------------------------------===//
// Transfer function for function calls.
//===----------------------------------------------------------------------===//
void GRSimpleVals::EvalCall(ExplodedNodeSet<GRState>& Dst,
GRExprEngine& Eng,
GRStmtNodeBuilder<GRState>& Builder,
CallExpr* CE, SVal L,
ExplodedNode<GRState>* Pred) {
const GRState* state = Builder.GetState(Pred);
// Invalidate all arguments passed in by reference (Locs).
for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
I != E; ++I) {
SVal V = state->getSVal(*I);
if (isa<loc::MemRegionVal>(V)) {
const MemRegion *R = cast<loc::MemRegionVal>(V).getRegion();
if (R->isBoundable())
state = state->bindLoc(cast<Loc>(V), UnknownVal());
} else if (isa<nonloc::LocAsInteger>(V))
state = state->bindLoc(cast<nonloc::LocAsInteger>(V).getLoc(),
UnknownVal());
}
// Make up a symbol for the return value of this function.
// FIXME: We eventually should handle structs and other compound types
// that are returned by value.
QualType T = CE->getType();
if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {
unsigned Count = Builder.getCurrentBlockCount();
SVal X = Eng.getValueManager().getConjuredSymbolVal(CE, Count);
state = state->bindExpr(CE, X, Eng.getCFG().isBlkExpr(CE), false);
}
Builder.MakeNode(Dst, CE, Pred, state);
}
//===----------------------------------------------------------------------===//
// Transfer function for Objective-C message expressions.
//===----------------------------------------------------------------------===//
void GRSimpleVals::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
GRExprEngine& Eng,
GRStmtNodeBuilder<GRState>& Builder,
ObjCMessageExpr* ME,
ExplodedNode<GRState>* Pred) {
// The basic transfer function logic for message expressions does nothing.
// We just invalidate all arguments passed in by references.
const GRState *St = Builder.GetState(Pred);
for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
I != E; ++I) {
SVal V = St->getSVal(*I);
if (isa<Loc>(V))
St = St->bindLoc(cast<Loc>(V), UnknownVal());
}
Builder.MakeNode(Dst, ME, Pred, St);
}

Просмотреть файл

@ -1,27 +0,0 @@
//== GRTransferFuncs.cpp - Path-Sens. Transfer Functions Interface -*- C++ -*--=
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines GRTransferFuncs, which provides a base-class that
// defines an interface for transfer functions used by GRExprEngine.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
using namespace clang;
void GRTransferFuncs::EvalBinOpNN(GRStateSet& OStates,
GRExprEngine& Eng,
const GRState *St, Expr* Ex,
BinaryOperator::Opcode Op,
NonLoc L, NonLoc R, QualType T) {
OStates.Add(St->bindExpr(Ex, DetermEvalBinOpNN(Eng, Op, L, R, T)));
}

Просмотреть файл

@ -780,7 +780,7 @@ SVal RegionStoreManager::EvalBinOp(const GRState *state,
// //
nonloc::ConcreteInt OffConverted(getBasicVals().Convert(Base->getValue(), nonloc::ConcreteInt OffConverted(getBasicVals().Convert(Base->getValue(),
Offset->getValue())); Offset->getValue()));
SVal NewIdx = Base->EvalBinOp(getBasicVals(), Op, OffConverted); SVal NewIdx = Base->evalBinOp(ValMgr, Op, OffConverted);
const MemRegion* NewER = const MemRegion* NewER =
MRMgr.getElementRegion(ER->getElementType(), NewIdx,ER->getSuperRegion(), MRMgr.getElementRegion(ER->getElementType(), NewIdx,ER->getSuperRegion(),
getContext()); getContext());

Просмотреть файл

@ -188,12 +188,11 @@ bool SVal::isZeroConstant() const {
// Transfer function dispatch for Non-Locs. // Transfer function dispatch for Non-Locs.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, SVal nonloc::ConcreteInt::evalBinOp(ValueManager &ValMgr,
BinaryOperator::Opcode Op, BinaryOperator::Opcode Op,
const nonloc::ConcreteInt& R) const { const nonloc::ConcreteInt& R) const {
const llvm::APSInt* X = const llvm::APSInt* X =
BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue()); ValMgr.getBasicValueFactory().EvaluateAPSInt(Op, getValue(), R.getValue());
if (X) if (X)
return nonloc::ConcreteInt(*X); return nonloc::ConcreteInt(*X);
@ -201,20 +200,13 @@ SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
return UndefinedVal(); return UndefinedVal();
} }
// Bitwise-Complement.
nonloc::ConcreteInt nonloc::ConcreteInt
nonloc::ConcreteInt::EvalComplement(BasicValueFactory& BasicVals) const { nonloc::ConcreteInt::evalComplement(ValueManager &ValMgr) const {
return BasicVals.getValue(~getValue()); return ValMgr.makeIntVal(~getValue());
} }
// Unary Minus. nonloc::ConcreteInt nonloc::ConcreteInt::evalMinus(ValueManager &ValMgr) const {
return ValMgr.makeIntVal(-getValue());
nonloc::ConcreteInt
nonloc::ConcreteInt::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const {
assert (U->getType() == U->getSubExpr()->getType());
assert (U->getType()->isIntegerType());
return BasicVals.getValue(-getValue());
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

Просмотреть файл

@ -469,10 +469,6 @@ static void ActionCheckerCFRef(AnalysisManager& mgr) {
} }
} }
static void ActionCheckerSimple(AnalysisManager& mgr) {
ActionGRExprEngine(mgr, MakeGRSimpleValsTF());
}
static void ActionDisplayLiveVariables(AnalysisManager& mgr) { static void ActionDisplayLiveVariables(AnalysisManager& mgr) {
if (LiveVariables* L = mgr.getLiveVariables()) { if (LiveVariables* L = mgr.getLiveVariables()) {
mgr.DisplayFunction(); mgr.DisplayFunction();

Просмотреть файл

@ -1,5 +1,3 @@
// RUN: clang-cc -analyze -checker-simple -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
// RUN: clang-cc -analyze -checker-simple -analyzer-store=basic -analyzer-constraints=range -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s &&

Просмотреть файл

@ -1,5 +1,3 @@
// RUN: clang-cc -analyze -checker-simple -analyzer-store=basic -analyzer-constraints=basic %s -verify &&
// RUN: clang-cc -analyze -checker-simple -analyzer-store=basic -analyzer-constraints=range %s -verify &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic %s -verify && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic %s -verify &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range %s -verify && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range %s -verify &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic %s -verify && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic %s -verify &&

Просмотреть файл

@ -1,4 +1,3 @@
// RUN: clang-cc -analyze -checker-simple -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s

Просмотреть файл

@ -1,4 +1,3 @@
// RUN: clang-cc -analyze -checker-simple -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s &&

Просмотреть файл

@ -1,6 +1,4 @@
// RUN: clang-cc -analyze -warn-dead-stores -verify %s && // RUN: clang-cc -analyze -warn-dead-stores -verify %s &&
// RUN: clang-cc -analyze -checker-simple -analyzer-store=basic -analyzer-constraints=basic -warn-dead-stores -verify %s &&
// RUN: clang-cc -analyze -checker-simple -analyzer-store=basic -analyzer-constraints=range -warn-dead-stores -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -warn-dead-stores -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -warn-dead-stores -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -warn-dead-stores -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -warn-dead-stores -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -warn-dead-stores -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -warn-dead-stores -verify %s &&

Просмотреть файл

@ -1,4 +1,4 @@
// RUN: clang-cc -analyze -checker-simple -analyzer-store=region %s // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region %s
typedef struct added_obj_st { typedef struct added_obj_st {
int type; int type;

Просмотреть файл

@ -1,4 +1,3 @@
// RUN: clang-cc -analyze -checker-simple -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s
// //

Просмотреть файл

@ -1,5 +1,3 @@
// RUN: clang-cc -analyze -checker-simple -verify %s &&
// RUN: clang-cc -analyze -checker-simple -analyzer-store=region -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s

Просмотреть файл

@ -1,7 +1,7 @@
// RUN: clang-cc -analyze -std=gnu99 -checker-simple -verify %s && // RUN: clang-cc -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=basic -analyzer-store=basic &&
// RUN: clang-cc -analyze -std=gnu99 -checker-simple -verify %s -analyzer-constraints=range && // RUN: clang-cc -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=range -analyzer-store=basic &&
// RUN: clang-cc -analyze -std=gnu99 -checker-simple -analyzer-store=region -analyzer-purge-dead=false -verify %s && // RUN: clang-cc -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -analyzer-purge-dead=false -verify %s &&
// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -analyzer-store=region -verify %s // RUN: clang-cc -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s
#include<stdint.h> #include<stdint.h>
#include <assert.h> #include <assert.h>

Просмотреть файл

@ -1,4 +1,4 @@
// RUN: clang-cc -analyze -checker-simple -analyzer-store=region -verify %s // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s
char f1() { char f1() {
char* s = "abcd"; char* s = "abcd";

Просмотреть файл

@ -1,4 +1,3 @@
// RUN: clang-cc -analyze -checker-simple -analyzer-store=region -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify -triple i686-apple-darwin9 %s // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify -triple i686-apple-darwin9 %s

Просмотреть файл

@ -1,4 +1,4 @@
// RUN: clang-cc -analyze -checker-simple -analyzer-store=region -verify %s // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s
// Region store must be enabled for tests in this file. // Region store must be enabled for tests in this file.

Просмотреть файл

@ -1,4 +1,3 @@
// RUN: clang-cc -analyze -checker-simple -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s

Просмотреть файл

@ -1,4 +1,3 @@
// RUN: clang-cc -analyze -checker-simple -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s &&
// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s

Просмотреть файл

@ -1,4 +1,4 @@
// RUN: clang-cc -analyze -checker-simple -analyzer-store=region -verify %s // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s
struct s { struct s {
int data; int data;

Просмотреть файл

@ -1,5 +1,5 @@
// RUN: rm -rf %t && // RUN: rm -rf %t &&
// RUN: clang-cc --html-diags=%t -checker-simple %s // RUN: clang-cc --html-diags=%t -checker-cfref %s
void f0(int x) { void f0(int x) {
int *p = &x; int *p = &x;