summaryrefslogtreecommitdiffstats
path: root/include/clang/StaticAnalyzer
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/StaticAnalyzer')
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h9
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h23
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h24
-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
-rw-r--r--include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h2
15 files changed, 142 insertions, 87 deletions
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 6dbdbbf..fb35f51 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -232,6 +232,7 @@ private:
/// \sa getMaxNodesPerTopLevelFunction
Optional<unsigned> MaxNodesPerTopLevelFunction;
+public:
/// Interprets an option's string value as a boolean.
///
/// Accepts the strings "true" and "false".
@@ -244,7 +245,6 @@ private:
/// Interprets an option's string value as an integer value.
int getOptionAsInteger(StringRef Name, int DefaultVal);
-public:
/// \brief Retrieves and sets the UserMode. This is a high-level option,
/// which is used to set other low-level options. It is not accessible
/// outside of AnalyzerOptions.
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 7a87e47..5c560b2 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -406,11 +406,6 @@ private:
/// A vector of BugReports for tracking the allocated pointers and cleanup.
std::vector<BugReportEquivClass *> EQClassesVector;
- /// A map from PathDiagnosticPiece to the LocationContext of the inlined
- /// function call it represents.
- llvm::DenseMap<const PathDiagnosticCallPiece*,
- const LocationContext*> LocationContextMap;
-
protected:
BugReporter(BugReporterData& d, Kind k) : BugTypes(F.getEmptySet()), kind(k),
D(d) {}
@@ -482,10 +477,6 @@ public:
EmitBasicReport(DeclWithIssue, BugName, Category, BugStr, Loc, &R, 1);
}
- void addCallPieceLocationContextPair(const PathDiagnosticCallPiece *C,
- const LocationContext *LC) {
- LocationContextMap[C] = LC;
- }
private:
llvm::StringMap<BugType *> StrBugTypes;
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
index 2e5f207..2e67180 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
@@ -134,10 +134,15 @@ class TrackConstraintBRVisitor
bool IsSatisfied;
bool IsZeroCheck;
+ /// We should start tracking from the last node along the path in which the
+ /// value is constrained.
+ bool IsTrackingTurnedOn;
+
public:
TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
: Constraint(constraint), Assumption(assumption), IsSatisfied(false),
- IsZeroCheck(!Assumption && Constraint.getAs<Loc>()) {}
+ IsZeroCheck(!Assumption && Constraint.getAs<Loc>()),
+ IsTrackingTurnedOn(false) {}
void Profile(llvm::FoldingSetNodeID &ID) const;
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index 3f0a1b1..a80b5a7 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include <deque>
+#include <list>
#include <iterator>
#include <string>
#include <vector>
@@ -93,7 +94,7 @@ public:
void HandlePathDiagnostic(PathDiagnostic *D);
- enum PathGenerationScheme { None, Minimal, Extensive };
+ enum PathGenerationScheme { None, Minimal, Extensive, AlternateExtensive };
virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
virtual bool supportsLogicalOpControlFlow() const { return false; }
virtual bool supportsAllBlockEdges() const { return false; }
@@ -283,6 +284,13 @@ public:
const SourceManager& getManager() const { assert(isValid()); return *SM; }
void Profile(llvm::FoldingSetNodeID &ID) const;
+
+ /// \brief Given an exploded node, retrieve the statement that should be used
+ /// for the diagnostic location.
+ static const Stmt *getStmt(const ExplodedNode *N);
+
+ /// \brief Retrieve the statement corresponding to the sucessor node.
+ static const Stmt *getNextStmt(const ExplodedNode *N);
};
class PathDiagnosticLocationPair {
@@ -296,6 +304,9 @@ public:
const PathDiagnosticLocation &getStart() const { return Start; }
const PathDiagnosticLocation &getEnd() const { return End; }
+ void setStart(const PathDiagnosticLocation &L) { Start = L; }
+ void setEnd(const PathDiagnosticLocation &L) { End = L; }
+
void flatten() {
Start.flatten();
End.flatten();
@@ -381,7 +392,7 @@ public:
};
-class PathPieces : public std::deque<IntrusiveRefCntPtr<PathDiagnosticPiece> > {
+class PathPieces : public std::list<IntrusiveRefCntPtr<PathDiagnosticPiece> > {
void flattenTo(PathPieces &Primary, PathPieces &Current,
bool ShouldFlattenMacros) const;
public:
@@ -608,6 +619,14 @@ public:
return LPairs[0].getEnd();
}
+ void setStartLocation(const PathDiagnosticLocation &L) {
+ LPairs[0].setStart(L);
+ }
+
+ void setEndLocation(const PathDiagnosticLocation &L) {
+ LPairs[0].setEnd(L);
+ }
+
void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); }
virtual PathDiagnosticLocation getLocation() const {
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 6f99fc1..b2411e6 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -17,6 +17,7 @@
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Basic/LangOptions.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -134,9 +135,13 @@ enum PointerEscapeKind {
class CheckerManager {
const LangOptions LangOpts;
-
+ AnalyzerOptionsRef AOptions;
public:
- CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { }
+ CheckerManager(const LangOptions &langOpts,
+ AnalyzerOptionsRef AOptions)
+ : LangOpts(langOpts),
+ AOptions(AOptions) {}
+
~CheckerManager();
bool hasPathSensitiveCheckers() const;
@@ -144,6 +149,7 @@ public:
void finishedCheckerRegistration();
const LangOptions &getLangOpts() const { return LangOpts; }
+ AnalyzerOptions &getAnalyzerOptions() { return *AOptions; }
typedef CheckerBase *CheckerRef;
typedef const void *CheckerTag;
@@ -170,6 +176,20 @@ public:
return checker;
}
+ template <typename CHECKER>
+ CHECKER *registerChecker(AnalyzerOptions &AOpts) {
+ CheckerTag tag = getTag<CHECKER>();
+ CheckerRef &ref = CheckerTags[tag];
+ if (ref)
+ return static_cast<CHECKER *>(ref); // already registered.
+
+ CHECKER *checker = new CHECKER(AOpts);
+ CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
+ CHECKER::_register(checker, *this);
+ ref = checker;
+ return checker;
+ }
+
//===----------------------------------------------------------------------===//
// Functions for running checkers for AST traversing..
//===----------------------------------------------------------------------===//
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.
diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
index 492edd4..1df8c09 100644
--- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
+++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
@@ -21,7 +21,7 @@ namespace clang {
namespace ento {
class CheckerManager;
-CheckerManager *createCheckerManager(const AnalyzerOptions &opts,
+CheckerManager *createCheckerManager(AnalyzerOptions &opts,
const LangOptions &langOpts,
ArrayRef<std::string> plugins,
DiagnosticsEngine &diags);
OpenPOWER on IntegriCloud