From 6c07bdba93b095b66e2c8c82dd5ed458fa8285ea Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 26 Jun 2009 00:05:51 +0000 Subject: [PATCH] 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 --- include/clang/Analysis/LocalCheckers.h | 1 - .../Analysis/PathSensitive/GRExprEngine.h | 37 +- .../Analysis/PathSensitive/GRTransferFuncs.h | 45 +- include/clang/Analysis/PathSensitive/SVals.h | 6 +- include/clang/Analysis/PathSensitive/Store.h | 2 +- .../Analysis/PathSensitive/ValueManager.h | 8 +- include/clang/Frontend/Analyses.def | 4 - lib/Analysis/BugReporter.cpp | 2 +- lib/Analysis/CFRefCount.cpp | 16 +- lib/Analysis/CMakeLists.txt | 3 +- lib/Analysis/GRExprEngine.cpp | 67 +-- lib/Analysis/GRSimpleVals.cpp | 414 ------------------ lib/Analysis/GRTransferFuncs.cpp | 27 -- lib/Analysis/RegionStore.cpp | 2 +- lib/Analysis/SVals.cpp | 24 +- lib/Frontend/AnalysisConsumer.cpp | 4 - test/Analysis/NoReturn.m | 2 - test/Analysis/ObjCProperties.m | 2 - test/Analysis/array-struct.c | 1 - test/Analysis/complex.c | 1 - test/Analysis/dead-stores.c | 2 - test/Analysis/elementtype.c | 2 +- test/Analysis/exercise-ps.c | 1 - test/Analysis/func.c | 2 - test/Analysis/null-deref-ps.c | 8 +- test/Analysis/outofbound.c | 2 +- test/Analysis/ptr-arith.c | 1 - test/Analysis/region-only-test.c | 2 +- test/Analysis/stack-addr-ps.c | 1 - test/Analysis/uninit-msg-expr.m | 1 - test/Analysis/uninit-vals-ps-region.c | 2 +- test/Coverage/html-diagnostics.c | 2 +- 32 files changed, 77 insertions(+), 617 deletions(-) delete mode 100644 lib/Analysis/GRSimpleVals.cpp delete mode 100644 lib/Analysis/GRTransferFuncs.cpp diff --git a/include/clang/Analysis/LocalCheckers.h b/include/clang/Analysis/LocalCheckers.h index 23610f9a2d..9ff3f52f89 100644 --- a/include/clang/Analysis/LocalCheckers.h +++ b/include/clang/Analysis/LocalCheckers.h @@ -37,7 +37,6 @@ void CheckDeadStores(LiveVariables& L, BugReporter& BR); void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags, bool FullUninitTaint=false); -GRTransferFuncs* MakeGRSimpleValsTF(); GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled, const LangOptions& lopts); diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 5db666c4b8..f05bc680a7 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -20,6 +20,7 @@ #include "clang/Analysis/PathSensitive/GRState.h" #include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h" #include "clang/Analysis/PathSensitive/GRTransferFuncs.h" +#include "clang/Analysis/PathSensitive/SValuator.h" #include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/AST/Type.h" #include "clang/AST/ExprObjC.h" @@ -67,6 +68,9 @@ protected: /// ValMgr - Object that manages/creates SVals. ValueManager &ValMgr; + /// SVator - SValuator object that creates SVals from expressions. + llvm::OwningPtr SVator; + /// EntryNode - The immediate predecessor node. NodeTy* EntryNode; @@ -603,41 +607,32 @@ protected: return X; if (isa(X)) - return getTF().EvalCast(*this, cast(X), CastT); + return SVator->EvalCast(cast(X), CastT); else - return getTF().EvalCast(*this, cast(X), CastT); + return SVator->EvalCast(cast(X), CastT); } - SVal EvalMinus(UnaryOperator* U, SVal X) { - return X.isValid() ? getTF().EvalMinus(*this, U, cast(X)) : X; + SVal EvalMinus(SVal X) { + return X.isValid() ? SVator->EvalMinus(cast(X)) : X; } SVal EvalComplement(SVal X) { - return X.isValid() ? getTF().EvalComplement(*this, cast(X)) : X; + return X.isValid() ? SVator->EvalComplement(cast(X)) : X; } public: - SVal EvalBinOp(BinaryOperator::Opcode Op, NonLoc L, NonLoc R, QualType T) { - return R.isValid() ? getTF().DetermEvalBinOpNN(*this, Op, L, R, T) - : R; + SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T) { + return SVator->EvalBinOpNN(op, L, R, T); } - SVal EvalBinOp(BinaryOperator::Opcode Op, NonLoc L, SVal R, QualType T) { - return R.isValid() ? getTF().DetermEvalBinOpNN(*this, Op, L, - cast(R), T) : R; + SVal EvalBinOp(BinaryOperator::Opcode op, NonLoc L, SVal R, QualType T) { + return R.isValid() ? SVator->EvalBinOpNN(op, L, cast(R), T) : R; } - void EvalBinOp(ExplodedNodeSet& Dst, Expr* Ex, - BinaryOperator::Opcode Op, NonLoc L, NonLoc R, - ExplodedNode* 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); - + SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op, + SVal lhs, SVal rhs, QualType T); + protected: void EvalCall(NodeSet& Dst, CallExpr* CE, SVal L, NodeTy* Pred); diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h index c2f8f5aae0..db23f81e2d 100644 --- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h +++ b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h @@ -22,20 +22,12 @@ namespace clang { - class GRExprEngine; - class BugReporter; - class ObjCMessageExpr; - class GRStmtNodeBuilderRef; +class GRExprEngine; +class BugReporter; +class ObjCMessageExpr; +class GRStmtNodeBuilderRef; class GRTransferFuncs { - friend class GRExprEngine; -protected: - virtual SVal DetermEvalBinOpNN(GRExprEngine& Eng, - BinaryOperator::Opcode Op, - NonLoc L, NonLoc R, QualType T) { - return UnknownVal(); - } - public: GRTransferFuncs() {} virtual ~GRTransferFuncs() {} @@ -43,33 +35,7 @@ public: virtual void RegisterPrinters(std::vector& Printers) {} 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. virtual void EvalCall(ExplodedNodeSet& Dst, @@ -108,8 +74,7 @@ public: ReturnStmt* S, ExplodedNode* Pred) {} - // Assumptions. - + // Assumptions. virtual const GRState* EvalAssume(const GRState *state, SVal Cond, bool Assumption) { return state; diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h index e553940470..36137fb117 100644 --- a/include/clang/Analysis/PathSensitive/SVals.h +++ b/include/clang/Analysis/PathSensitive/SVals.h @@ -254,12 +254,12 @@ public: } // 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; - ConcreteInt EvalComplement(BasicValueFactory& BasicVals) const; + ConcreteInt evalComplement(ValueManager &ValMgr) const; - ConcreteInt EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const; + ConcreteInt evalMinus(ValueManager &ValMgr) const; // Implement isa support. static inline bool classof(const SVal* V) { diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index cbe0b3c835..5aa53507fd 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -138,7 +138,7 @@ public: /// EvalBinOp - Perform pointer arithmetic. virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op, - Loc lhs, NonLoc rhs) { + Loc lhs, NonLoc rhs, QualType resultTy) { return UnknownVal(); } diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h index d8e557f760..de318a0f03 100644 --- a/include/clang/Analysis/PathSensitive/ValueManager.h +++ b/include/clang/Analysis/PathSensitive/ValueManager.h @@ -87,14 +87,18 @@ public: return nonloc::ConcreteInt(BasicVals.getZeroWithPtrWidth(false)); } - NonLoc makeIntVal(const IntegerLiteral* I) { + nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) { return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(), I->getType()->isUnsignedIntegerType())); } - NonLoc makeIntVal(const llvm::APSInt& V) { + nonloc::ConcreteInt makeIntVal(const llvm::APSInt& 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) { return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned)); diff --git a/include/clang/Frontend/Analyses.def b/include/clang/Frontend/Analyses.def index 3492d09c10..ad799c3a8b 100644 --- a/include/clang/Frontend/Analyses.def +++ b/include/clang/Frontend/Analyses.def @@ -41,13 +41,9 @@ ANALYSIS(WarnObjCDealloc, "warn-objc-missing-dealloc", ANALYSIS(WarnObjCUnusedIvars, "warn-objc-unused-ivars", "Warn about private ivars that are never used", ObjCImplementation) -ANALYSIS(CheckerSimple, "checker-simple", - "Perform simple path-sensitive checks.", Code) - ANALYSIS(CheckerCFRef, "checker-cfref", "Run the [Core] Foundation reference count checker", Code) - #ifndef ANALYSIS_STORE #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) #endif diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 9c9029cfff..38ea458a65 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file defines BugReporter, a utility class for generating -// PathDiagnostics for analyses based on GRSimpleVals. +// PathDiagnostics. // //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 5e542a3c48..f4a28e0c19 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// -#include "GRSimpleVals.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceManager.h" #include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h" @@ -22,6 +21,7 @@ #include "clang/Analysis/PathDiagnostic.h" #include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/Analysis/PathSensitive/SymbolManager.h" +#include "clang/Analysis/PathSensitive/GRTransferFuncs.h" #include "clang/AST/DeclObjC.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" @@ -1826,7 +1826,7 @@ static const GRState * SendAutorelease(const GRState *state, namespace { -class VISIBILITY_HIDDEN CFRefCount : public GRSimpleVals { +class VISIBILITY_HIDDEN CFRefCount : public GRTransferFuncs { public: class BindingsPrinter : public GRState::Printer { public: @@ -2789,10 +2789,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, if (Summ.getArg(idx) == DoNothingByRef) continue; - // 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." + // Invalidate the value of the variable passed by reference. // FIXME: We can have collisions on the conjured symbol if the // expression *I also creates conjured symbols. We probably want @@ -2941,11 +2938,10 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, default: assert (false && "Unhandled RetEffect."); break; - case RetEffect::NoRet: { - + case RetEffect::NoRet: { // Make up a symbol for the return value (not reference counted). - // FIXME: This is basically copy-and-paste from GRSimpleVals. We - // should compose behavior, not copy it. + // FIXME: Most of this logic is not specific to the retain/release + // checker. // FIXME: We eventually should handle structs and other compound types // that are returned by value. diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt index e064e3c71a..7d6a619736 100644 --- a/lib/Analysis/CMakeLists.txt +++ b/lib/Analysis/CMakeLists.txt @@ -18,15 +18,14 @@ add_clang_library(clangAnalysis GRCoreEngine.cpp GRExprEngine.cpp GRExprEngineInternalChecks.cpp - GRSimpleVals.cpp GRState.cpp - GRTransferFuncs.cpp LiveVariables.cpp MemRegion.cpp PathDiagnostic.cpp RangeConstraintManager.cpp RegionStore.cpp SimpleConstraintManager.cpp + SimpleSValuator.cpp Store.cpp SVals.cpp SymbolManager.cpp diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index d3df92df34..779d70661c 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -15,7 +15,6 @@ #include "clang/Analysis/PathSensitive/GRExprEngine.h" #include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h" -#include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/AST/ParentMap.h" #include "clang/AST/StmtObjC.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), SymMgr(StateMgr.getSymbolManager()), ValMgr(StateMgr.getValueManager()), + SVator(clang::CreateSimpleSValuator(ValMgr)), // FIXME: Generalize later. CurrentStmt(NULL), NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL), RaiseSel(GetNullarySelector("raise", G.getContext())), @@ -1296,9 +1296,8 @@ static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet& Dst, SVal oldValueVal = stateLoad->getSVal(oldValueExpr); // Perform the comparison. - SVal Cmp = Engine.EvalBinOp(stateLoad, - BinaryOperator::EQ, theValueVal, oldValueVal, - Engine.getContext().IntTy); + SVal Cmp = Engine.EvalBinOp(stateLoad, BinaryOperator::EQ, theValueVal, + oldValueVal, Engine.getContext().IntTy); const GRState *stateEqual = stateLoad->assume(Cmp, true); @@ -2562,7 +2561,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, case UnaryOperator::Minus: // FIXME: Do we need to handle promotions? - state = state->bindExpr(U, EvalMinus(U, cast(V))); + state = state->bindExpr(U, EvalMinus(cast(V))); break; 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 // transfer functions as "0 == E". + SVal Result; if (isa(V)) { Loc X = ValMgr.makeNull(); - SVal Result = EvalBinOp(state,BinaryOperator::EQ, cast(V), X, - U->getType()); - state = state->bindExpr(U, Result); + Result = EvalBinOp(state, BinaryOperator::EQ, cast(V), X, + U->getType()); } else { nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType())); -#if 0 - SVal Result = EvalBinOp(BinaryOperator::EQ, cast(V), X); - state = SetSVal(state, U, Result); -#else - EvalBinOp(Dst, U, BinaryOperator::EQ, cast(V), X, *I, - U->getType()); - continue; -#endif + Result = EvalBinOp(BinaryOperator::EQ, cast(V), X, + U->getType()); } + state = state->bindExpr(U, Result); + break; } @@ -2640,8 +2635,8 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, Builder->getCurrentBlockCount()); // 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. + // non-nullness. Check if the original value was non-null, and if so + // propagate that constraint. if (Loc::IsLocType(U->getType())) { SVal Constraint = EvalBinOp(state, BinaryOperator::EQ, V2, ValMgr.makeZeroVal(U->getType()), @@ -2907,9 +2902,8 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, if (B->isAssignmentOp()) break; - // Process non-assignements except commas or short-circuited - // logical expressions (LAnd and LOr). - + // Process non-assignments except commas or short-circuited + // logical expressions (LAnd and LOr). SVal Result = EvalBinOp(state, Op, LeftV, RightV, B->getType()); if (Result.isUnknown()) { @@ -3024,7 +3018,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, } // 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()); if (Result.isUndef()) { @@ -3073,26 +3067,6 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, // Transfer-function Helpers. //===----------------------------------------------------------------------===// -void GRExprEngine::EvalBinOp(ExplodedNodeSet& Dst, Expr* Ex, - BinaryOperator::Opcode Op, - NonLoc L, NonLoc R, - ExplodedNode* 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 L, SVal R, QualType T) { @@ -3104,9 +3078,9 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op, if (isa(L)) { if (isa(R)) - return getTF().EvalBinOp(*this, Op, cast(L), cast(R)); + return SVator->EvalBinOpLL(Op, cast(L), cast(R), T); else - return getTF().EvalBinOp(*this, state, Op, cast(L), cast(R)); + return SVator->EvalBinOpLN(state, Op, cast(L), cast(R), T); } if (isa(R)) { @@ -3116,11 +3090,10 @@ SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op, assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub); // Commute the operands. - return getTF().EvalBinOp(*this, state, Op, cast(R), cast(L)); + return SVator->EvalBinOpLN(state, Op, cast(R), cast(L), T); } else - return getTF().DetermEvalBinOpNN(*this, Op, cast(L), - cast(R), T); + return SVator->EvalBinOpNN(Op, cast(L), cast(R), T); } //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp deleted file mode 100644 index 9a1b2fc05e..0000000000 --- a/lib/Analysis/GRSimpleVals.cpp +++ /dev/null @@ -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 - -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(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(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(X)) - return Eng.getValueManager().makeLocAsInteger(X, BitWidth); - - llvm::APSInt V = cast(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(X).EvalMinus(Eng.getBasicVals(), U); - - default: - return UnknownVal(); - } -} - -SVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLoc X) { - - switch (X.getSubKind()) { - - case nonloc::ConcreteIntKind: - return cast(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(L).getLoc(); - - switch (R.getSubKind()) { - case nonloc::LocAsIntegerKind: - return EvalBinOp(Eng, Op, LL, - cast(R).getLoc()); - - case nonloc::ConcreteIntKind: { - // Transform the integer into a location and compare. - ASTContext& Ctx = Eng.getContext(); - llvm::APSInt V = cast(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(L).getSymbolicExpression(); - - // Only handle ($sym op constant) for now. - if (const SymIntExpr *E = dyn_cast(&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(R)) { - const nonloc::ConcreteInt& L_CI = cast(L); - const nonloc::ConcreteInt& R_CI = cast(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(R)) { - ValueManager &ValMgr = Eng.getValueManager(); - return ValMgr.makeNonLoc(cast(L).getSymbol(), Op, - cast(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(&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(R)) { - bool b = cast(L).getValue() == - cast(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(L).getValue(), - Eng.getContext().IntTy); - return nonloc::SymExprVal(SE); - } - - break; - - case loc::MemRegionKind: { - if (SymbolRef LSym = L.getAsLocSymbol()) { - if (isa(R)) { - const SymIntExpr *SE = - Eng.getSymbolManager().getSymIntExpr(LSym, - isEqual ? BinaryOperator::EQ - : BinaryOperator::NE, - cast(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& Dst, - GRExprEngine& Eng, - GRStmtNodeBuilder& Builder, - CallExpr* CE, SVal L, - ExplodedNode* 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(V)) { - const MemRegion *R = cast(V).getRegion(); - - if (R->isBoundable()) - state = state->bindLoc(cast(V), UnknownVal()); - } else if (isa(V)) - state = state->bindLoc(cast(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& Dst, - GRExprEngine& Eng, - GRStmtNodeBuilder& Builder, - ObjCMessageExpr* ME, - ExplodedNode* 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(V)) - St = St->bindLoc(cast(V), UnknownVal()); - } - - Builder.MakeNode(Dst, ME, Pred, St); -} diff --git a/lib/Analysis/GRTransferFuncs.cpp b/lib/Analysis/GRTransferFuncs.cpp deleted file mode 100644 index 3c14ee9ab5..0000000000 --- a/lib/Analysis/GRTransferFuncs.cpp +++ /dev/null @@ -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))); -} diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index e87245f9c2..82025877b6 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -780,7 +780,7 @@ SVal RegionStoreManager::EvalBinOp(const GRState *state, // nonloc::ConcreteInt OffConverted(getBasicVals().Convert(Base->getValue(), Offset->getValue())); - SVal NewIdx = Base->EvalBinOp(getBasicVals(), Op, OffConverted); + SVal NewIdx = Base->evalBinOp(ValMgr, Op, OffConverted); const MemRegion* NewER = MRMgr.getElementRegion(ER->getElementType(), NewIdx,ER->getSuperRegion(), getContext()); diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp index a69b611cc3..7d1850d730 100644 --- a/lib/Analysis/SVals.cpp +++ b/lib/Analysis/SVals.cpp @@ -188,12 +188,11 @@ bool SVal::isZeroConstant() const { // Transfer function dispatch for Non-Locs. //===----------------------------------------------------------------------===// -SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, - BinaryOperator::Opcode Op, - const nonloc::ConcreteInt& R) const { - +SVal nonloc::ConcreteInt::evalBinOp(ValueManager &ValMgr, + BinaryOperator::Opcode Op, + const nonloc::ConcreteInt& R) const { const llvm::APSInt* X = - BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue()); + ValMgr.getBasicValueFactory().EvaluateAPSInt(Op, getValue(), R.getValue()); if (X) return nonloc::ConcreteInt(*X); @@ -201,20 +200,13 @@ SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals, return UndefinedVal(); } - // Bitwise-Complement. - nonloc::ConcreteInt -nonloc::ConcreteInt::EvalComplement(BasicValueFactory& BasicVals) const { - return BasicVals.getValue(~getValue()); +nonloc::ConcreteInt::evalComplement(ValueManager &ValMgr) const { + return ValMgr.makeIntVal(~getValue()); } - // Unary Minus. - -nonloc::ConcreteInt -nonloc::ConcreteInt::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const { - assert (U->getType() == U->getSubExpr()->getType()); - assert (U->getType()->isIntegerType()); - return BasicVals.getValue(-getValue()); +nonloc::ConcreteInt nonloc::ConcreteInt::evalMinus(ValueManager &ValMgr) const { + return ValMgr.makeIntVal(-getValue()); } //===----------------------------------------------------------------------===// diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp index ae90594a40..d8fa141d8c 100644 --- a/lib/Frontend/AnalysisConsumer.cpp +++ b/lib/Frontend/AnalysisConsumer.cpp @@ -469,10 +469,6 @@ static void ActionCheckerCFRef(AnalysisManager& mgr) { } } -static void ActionCheckerSimple(AnalysisManager& mgr) { - ActionGRExprEngine(mgr, MakeGRSimpleValsTF()); -} - static void ActionDisplayLiveVariables(AnalysisManager& mgr) { if (LiveVariables* L = mgr.getLiveVariables()) { mgr.DisplayFunction(); diff --git a/test/Analysis/NoReturn.m b/test/Analysis/NoReturn.m index a43f99bdd7..5f5ce281a7 100644 --- a/test/Analysis/NoReturn.m +++ b/test/Analysis/NoReturn.m @@ -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=range -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s && diff --git a/test/Analysis/ObjCProperties.m b/test/Analysis/ObjCProperties.m index 7787a1d6ec..3ad256914a 100644 --- a/test/Analysis/ObjCProperties.m +++ b/test/Analysis/ObjCProperties.m @@ -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=range %s -verify && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic %s -verify && diff --git a/test/Analysis/array-struct.c b/test/Analysis/array-struct.c index 0ad7ae7e82..438e1ccf47 100644 --- a/test/Analysis/array-struct.c +++ b/test/Analysis/array-struct.c @@ -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=range -verify %s diff --git a/test/Analysis/complex.c b/test/Analysis/complex.c index f29fc70c49..cef624577a 100644 --- a/test/Analysis/complex.c +++ b/test/Analysis/complex.c @@ -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=range -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s && diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c index c100344adf..6d3b7e6f54 100644 --- a/test/Analysis/dead-stores.c +++ b/test/Analysis/dead-stores.c @@ -1,6 +1,4 @@ // 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=range -warn-dead-stores -verify %s && // RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -warn-dead-stores -verify %s && diff --git a/test/Analysis/elementtype.c b/test/Analysis/elementtype.c index 10328e69ef..2bdaad423a 100644 --- a/test/Analysis/elementtype.c +++ b/test/Analysis/elementtype.c @@ -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 { int type; diff --git a/test/Analysis/exercise-ps.c b/test/Analysis/exercise-ps.c index 08842b1b8d..c309349ab3 100644 --- a/test/Analysis/exercise-ps.c +++ b/test/Analysis/exercise-ps.c @@ -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=region -verify %s // diff --git a/test/Analysis/func.c b/test/Analysis/func.c index a018d0afc1..2b4e7b0db0 100644 --- a/test/Analysis/func.c +++ b/test/Analysis/func.c @@ -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=region -verify %s diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c index 09b9c2ffa3..6e2074146c 100644 --- a/test/Analysis/null-deref-ps.c +++ b/test/Analysis/null-deref-ps.c @@ -1,7 +1,7 @@ -// RUN: clang-cc -analyze -std=gnu99 -checker-simple -verify %s && -// RUN: clang-cc -analyze -std=gnu99 -checker-simple -verify %s -analyzer-constraints=range && -// 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 -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-cfref -verify %s -analyzer-constraints=range -analyzer-store=basic && +// 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 -analyzer-constraints=range -verify %s #include #include diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c index 953075fe03..527a311d2b 100644 --- a/test/Analysis/outofbound.c +++ b/test/Analysis/outofbound.c @@ -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* s = "abcd"; diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c index 34840c7b7c..4f2c7d9edb 100644 --- a/test/Analysis/ptr-arith.c +++ b/test/Analysis/ptr-arith.c @@ -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 i686-apple-darwin9 %s diff --git a/test/Analysis/region-only-test.c b/test/Analysis/region-only-test.c index fdc740488a..64d3fcd57b 100644 --- a/test/Analysis/region-only-test.c +++ b/test/Analysis/region-only-test.c @@ -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. diff --git a/test/Analysis/stack-addr-ps.c b/test/Analysis/stack-addr-ps.c index 4bc9a7def2..2f7a4bdf74 100644 --- a/test/Analysis/stack-addr-ps.c +++ b/test/Analysis/stack-addr-ps.c @@ -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=region -verify %s diff --git a/test/Analysis/uninit-msg-expr.m b/test/Analysis/uninit-msg-expr.m index 161ab8041d..5ec878ea3c 100644 --- a/test/Analysis/uninit-msg-expr.m +++ b/test/Analysis/uninit-msg-expr.m @@ -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=region -verify %s diff --git a/test/Analysis/uninit-vals-ps-region.c b/test/Analysis/uninit-vals-ps-region.c index 6f3762ee10..32f787db4a 100644 --- a/test/Analysis/uninit-vals-ps-region.c +++ b/test/Analysis/uninit-vals-ps-region.c @@ -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 { int data; diff --git a/test/Coverage/html-diagnostics.c b/test/Coverage/html-diagnostics.c index 6144f2fb98..e3db1668d8 100644 --- a/test/Coverage/html-diagnostics.c +++ b/test/Coverage/html-diagnostics.c @@ -1,5 +1,5 @@ // 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) { int *p = &x;