summaryrefslogtreecommitdiffstats
path: root/include/clang/StaticAnalyzer/Core/PathSensitive
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/StaticAnalyzer/Core/PathSensitive')
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h32
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h11
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h9
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h18
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h15
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h67
9 files changed, 91 insertions, 71 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index 1135b51..2c799c0 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -93,7 +93,7 @@ public:
/// Returns the type of the APSInt used to store values of the given QualType.
APSIntType getAPSIntType(QualType T) const {
- assert(T->isIntegerType() || Loc::isLocType(T));
+ assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T));
return APSIntType(Ctx.getTypeSize(T),
!T->isSignedIntegerOrEnumerationType());
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index cda1366..0b9762a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -110,10 +110,6 @@ public:
StoreManager &getStoreManager() {
return Eng.getStoreManager();
}
-
- const AnalyzerOptions::ConfigTable &getConfig() const {
- return Eng.getAnalysisManager().options.Config;
- }
/// \brief Returns the previous node in the exploded graph, which includes
/// the state of the program before the checker ran. Note, checkers should
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 5211916..edcfc8a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -196,6 +196,10 @@ public:
return const_cast<ExplodedNode*>(this)->getFirstPred();
}
+ const ExplodedNode *getFirstSucc() const {
+ return succ_empty() ? NULL : *(succ_begin());
+ }
+
// Iterators over successor and predecessor vertices.
typedef ExplodedNode* const * succ_iterator;
typedef const ExplodedNode* const * const_succ_iterator;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index af2f365..9b4f77d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -37,11 +37,12 @@ class StackFrameContext;
namespace ento {
+class CodeTextRegion;
class MemRegionManager;
class MemSpaceRegion;
class SValBuilder;
+class SymbolicRegion;
class VarRegion;
-class CodeTextRegion;
/// Represent a region's offset within the top level base region.
class RegionOffset {
@@ -145,6 +146,10 @@ public:
const MemRegion *StripCasts(bool StripBaseCasts = true) const;
+ /// \brief If this is a symbolic region, returns the region. Otherwise,
+ /// goes up the base chain looking for the first symbolic base region.
+ const SymbolicRegion *getSymbolicBase() const;
+
bool hasGlobalsOrParametersStorage() const;
bool hasStackStorage() const;
@@ -169,6 +174,16 @@ public:
/// \brief Print the region for use in diagnostics.
virtual void printPretty(raw_ostream &os) const;
+ /// \brief Returns true if this region's textual representation can be used
+ /// as part of a larger expression.
+ virtual bool canPrintPrettyAsExpr() const;
+
+ /// \brief Print the region as expression.
+ ///
+ /// When this region represents a subexpression, the method is for printing
+ /// an expression containing it.
+ virtual void printPrettyAsExpr(raw_ostream &os) const;
+
Kind getKind() const { return kind; }
template<typename RegionTy> const RegionTy* getAs() const;
@@ -874,8 +889,9 @@ public:
return R->getKind() == VarRegionKind;
}
- bool canPrintPretty() const;
- void printPretty(raw_ostream &os) const;
+ bool canPrintPrettyAsExpr() const;
+
+ void printPrettyAsExpr(raw_ostream &os) const;
};
/// CXXThisRegion - Represents the region for the implicit 'this' parameter
@@ -937,6 +953,8 @@ public:
bool canPrintPretty() const;
void printPretty(raw_ostream &os) const;
+ bool canPrintPrettyAsExpr() const;
+ void printPrettyAsExpr(raw_ostream &os) const;
};
class ObjCIvarRegion : public DeclRegion {
@@ -952,8 +970,8 @@ public:
const ObjCIvarDecl *getDecl() const;
QualType getValueType() const;
- bool canPrintPretty() const;
- void printPretty(raw_ostream &os) const;
+ bool canPrintPrettyAsExpr() const;
+ void printPrettyAsExpr(raw_ostream &os) const;
void dumpToStream(raw_ostream &os) const;
@@ -1082,6 +1100,10 @@ public:
static bool classof(const MemRegion *region) {
return region->getKind() == CXXBaseObjectRegionKind;
}
+
+ bool canPrintPrettyAsExpr() const;
+
+ void printPrettyAsExpr(raw_ostream &os) const;
};
template<typename RegionTy>
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 6ea7211..42ef1db 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -201,14 +201,6 @@ public:
// Binding and retrieving values to/from the environment and symbolic store.
//==---------------------------------------------------------------------==//
- /// \brief Create a new state with the specified CompoundLiteral binding.
- /// \param CL the compound literal expression (the binding key)
- /// \param LC the LocationContext of the binding
- /// \param V the value to bind.
- ProgramStateRef bindCompoundLiteral(const CompoundLiteralExpr *CL,
- const LocationContext *LC,
- SVal V) const;
-
/// Create a new state by binding the value 'V' to the statement 'S' in the
/// state's environment.
ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx,
@@ -711,7 +703,8 @@ ProgramState::getSValAsScalarOrLoc(const Stmt *S,
const LocationContext *LCtx) const {
if (const Expr *Ex = dyn_cast<Expr>(S)) {
QualType T = Ex->getType();
- if (Ex->isGLValue() || Loc::isLocType(T) || T->isIntegerType())
+ if (Ex->isGLValue() || Loc::isLocType(T) ||
+ T->isIntegralOrEnumerationType())
return getSVal(S, LCtx);
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index f7e49a3..bbb5688 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -78,7 +78,8 @@ public:
// FIXME: Remove the second disjunct when we support symbolic
// truncation/extension.
return (Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2) ||
- (Ty1->isIntegerType() && Ty2->isIntegerType()));
+ (Ty1->isIntegralOrEnumerationType() &&
+ Ty2->isIntegralOrEnumerationType()));
}
SVal evalCast(SVal val, QualType castTy, QualType originalType);
@@ -201,6 +202,12 @@ public:
DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy,
const LocationContext *locContext);
+ /// Returns the value of \p E, if it can be determined in a non-path-sensitive
+ /// manner.
+ ///
+ /// If \p E is not a constant or cannot be modeled, returns \c None.
+ Optional<SVal> getConstantVal(const Expr *E);
+
NonLoc makeCompoundVal(QualType type, llvm::ImmutableList<SVal> vals) {
return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals));
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 1c5519e..326e784 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -144,16 +144,24 @@ public:
/// Otherwise return 0.
const FunctionDecl *getAsFunctionDecl() const;
- /// If this SVal is a location (subclasses Loc) and
- /// wraps a symbol, return that SymbolRef. Otherwise return 0.
- SymbolRef getAsLocSymbol() const;
+ /// \brief If this SVal is a location and wraps a symbol, return that
+ /// SymbolRef. Otherwise return 0.
+ ///
+ /// Casts are ignored during lookup.
+ /// \param IncludeBaseRegions The boolean that controls whether the search
+ /// should continue to the base regions if the region is not symbolic.
+ SymbolRef getAsLocSymbol(bool IncludeBaseRegions = false) const;
/// Get the symbol in the SVal or its base region.
SymbolRef getLocSymbolInBase() const;
- /// If this SVal wraps a symbol return that SymbolRef.
+ /// \brief If this SVal wraps a symbol return that SymbolRef.
/// Otherwise, return 0.
- SymbolRef getAsSymbol() const;
+ ///
+ /// Casts are ignored during lookup.
+ /// \param IncludeBaseRegions The boolean that controls whether the search
+ /// should continue to the base regions if the region is not symbolic.
+ SymbolRef getAsSymbol(bool IncludeBaseRegions = false) const;
/// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
/// return that expression. Otherwise return NULL.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index bbfd579..b219495 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -76,21 +76,6 @@ public:
/// \param L the location whose binding should be removed.
virtual StoreRef killBinding(Store ST, Loc L) = 0;
- /// \brief Create a new store that binds a value to a compound literal.
- ///
- /// \param ST The original store whose bindings are the basis for the new
- /// store.
- ///
- /// \param CL The compound literal to bind (the binding key).
- ///
- /// \param LC The LocationContext for the binding.
- ///
- /// \param V The value to bind to the compound literal.
- virtual StoreRef bindCompoundLiteral(Store ST,
- const CompoundLiteralExpr *CL,
- const LocationContext *LC,
- SVal V) = 0;
-
/// getInitialStore - Returns the initial "empty" store representing the
/// value bindings upon entry to an analyzed function.
virtual StoreRef getInitialStore(const LocationContext *InitLoc) = 0;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index 56afca2..914b2be 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -49,7 +49,10 @@ public:
MetadataKind,
BEGIN_SYMBOLS = RegionValueKind,
END_SYMBOLS = MetadataKind,
- SymIntKind, IntSymKind, SymSymKind, CastSymbolKind };
+ SymIntKind, IntSymKind, SymSymKind,
+ BEGIN_BINARYSYMEXPRS = SymIntKind,
+ END_BINARYSYMEXPRS = SymSymKind,
+ CastSymbolKind };
private:
Kind K;
@@ -341,24 +344,39 @@ public:
}
};
-/// SymIntExpr - Represents symbolic expression like 'x' + 3.
-class SymIntExpr : public SymExpr {
- const SymExpr *LHS;
+/// \brief Represents a symbolic expression involving a binary operator
+class BinarySymExpr : public SymExpr {
BinaryOperator::Opcode Op;
- const llvm::APSInt& RHS;
QualType T;
-public:
- SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType t)
- : SymExpr(SymIntKind), LHS(lhs), Op(op), RHS(rhs), T(t) {}
+protected:
+ BinarySymExpr(Kind k, BinaryOperator::Opcode op, QualType t)
+ : SymExpr(k), Op(op), T(t) {}
+public:
// FIXME: We probably need to make this out-of-line to avoid redundant
// generation of virtual functions.
QualType getType() const { return T; }
BinaryOperator::Opcode getOpcode() const { return Op; }
+ // Implement isa<T> support.
+ static inline bool classof(const SymExpr *SE) {
+ Kind k = SE->getKind();
+ return k >= BEGIN_BINARYSYMEXPRS && k <= END_BINARYSYMEXPRS;
+ }
+};
+
+/// \brief Represents a symbolic expression like 'x' + 3.
+class SymIntExpr : public BinarySymExpr {
+ const SymExpr *LHS;
+ const llvm::APSInt& RHS;
+
+public:
+ SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
+ const llvm::APSInt& rhs, QualType t)
+ : BinarySymExpr(SymIntKind, op, t), LHS(lhs), RHS(rhs) {}
+
virtual void dumpToStream(raw_ostream &os) const;
const SymExpr *getLHS() const { return LHS; }
@@ -375,7 +393,7 @@ public:
}
void Profile(llvm::FoldingSetNodeID& ID) {
- Profile(ID, LHS, Op, RHS, T);
+ Profile(ID, LHS, getOpcode(), RHS, getType());
}
// Implement isa<T> support.
@@ -384,21 +402,15 @@ public:
}
};
-/// IntSymExpr - Represents symbolic expression like 3 - 'x'.
-class IntSymExpr : public SymExpr {
+/// \brief Represents a symbolic expression like 3 - 'x'.
+class IntSymExpr : public BinarySymExpr {
const llvm::APSInt& LHS;
- BinaryOperator::Opcode Op;
const SymExpr *RHS;
- QualType T;
public:
IntSymExpr(const llvm::APSInt& lhs, BinaryOperator::Opcode op,
const SymExpr *rhs, QualType t)
- : SymExpr(IntSymKind), LHS(lhs), Op(op), RHS(rhs), T(t) {}
-
- QualType getType() const { return T; }
-
- BinaryOperator::Opcode getOpcode() const { return Op; }
+ : BinarySymExpr(IntSymKind, op, t), LHS(lhs), RHS(rhs) {}
virtual void dumpToStream(raw_ostream &os) const;
@@ -416,7 +428,7 @@ public:
}
void Profile(llvm::FoldingSetNodeID& ID) {
- Profile(ID, LHS, Op, RHS, T);
+ Profile(ID, LHS, getOpcode(), RHS, getType());
}
// Implement isa<T> support.
@@ -425,26 +437,19 @@ public:
}
};
-/// SymSymExpr - Represents symbolic expression like 'x' + 'y'.
-class SymSymExpr : public SymExpr {
+/// \brief Represents a symbolic expression like 'x' + 'y'.
+class SymSymExpr : public BinarySymExpr {
const SymExpr *LHS;
- BinaryOperator::Opcode Op;
const SymExpr *RHS;
- QualType T;
public:
SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs,
QualType t)
- : SymExpr(SymSymKind), LHS(lhs), Op(op), RHS(rhs), T(t) {}
+ : BinarySymExpr(SymSymKind, op, t), LHS(lhs), RHS(rhs) {}
- BinaryOperator::Opcode getOpcode() const { return Op; }
const SymExpr *getLHS() const { return LHS; }
const SymExpr *getRHS() const { return RHS; }
- // FIXME: We probably need to make this out-of-line to avoid redundant
- // generation of virtual functions.
- QualType getType() const { return T; }
-
virtual void dumpToStream(raw_ostream &os) const;
static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
@@ -457,7 +462,7 @@ public:
}
void Profile(llvm::FoldingSetNodeID& ID) {
- Profile(ID, LHS, Op, RHS, T);
+ Profile(ID, LHS, getOpcode(), RHS, getType());
}
// Implement isa<T> support.
OpenPOWER on IntegriCloud