summaryrefslogtreecommitdiffstats
path: root/include/clang/StaticAnalyzer/Core
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/StaticAnalyzer/Core')
-rw-r--r--include/clang/StaticAnalyzer/Core/Analyses.def12
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h25
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h19
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugType.h11
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h25
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h56
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h63
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h64
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerRegistry.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h18
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h33
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h48
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h22
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h3
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h19
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h2
20 files changed, 264 insertions, 177 deletions
diff --git a/include/clang/StaticAnalyzer/Core/Analyses.def b/include/clang/StaticAnalyzer/Core/Analyses.def
index dc79450..3355f4b 100644
--- a/include/clang/StaticAnalyzer/Core/Analyses.def
+++ b/include/clang/StaticAnalyzer/Core/Analyses.def
@@ -24,14 +24,14 @@ ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", CreateR
ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager)
#ifndef ANALYSIS_DIAGNOSTICS
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)
#endif
-ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer, false)
-ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer, true)
-ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for mult-file bugs)", createPlistMultiFileDiagnosticConsumer, true)
-ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer, true)
-ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer, true)
+ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for mult-file bugs)", createPlistMultiFileDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer)
#ifndef ANALYSIS_PURGE
#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC)
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index fb35f51..618782e 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -52,7 +52,7 @@ NumConstraints
/// AnalysisDiagClients - Set of available diagnostic clients for rendering
/// analysis results.
enum AnalysisDiagClients {
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) PD_##NAME,
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
#include "clang/StaticAnalyzer/Core/Analyses.def"
NUM_ANALYSIS_DIAG_CLIENTS
};
@@ -201,6 +201,9 @@ private:
/// \sa mayInlineCXXContainerCtorsAndDtors
Optional<bool> InlineCXXContainerCtorsAndDtors;
+ /// \sa mayInlineCXXSharedPtrDtor
+ Optional<bool> InlineCXXSharedPtrDtor;
+
/// \sa mayInlineObjCMethod
Optional<bool> ObjCInliningMode;
@@ -223,6 +226,9 @@ private:
/// \sa shouldSuppressFromCXXStandardLibrary
Optional<bool> SuppressFromCXXStandardLibrary;
+ /// \sa reportIssuesInMainSourceFile
+ Optional<bool> ReportIssuesInMainSourceFile;
+
/// \sa getGraphTrimInterval
Optional<unsigned> GraphTrimInterval;
@@ -291,6 +297,16 @@ public:
/// accepts the values "true" and "false".
bool mayInlineCXXContainerCtorsAndDtors();
+ /// Returns whether or not the destructor of C++ 'shared_ptr' may be
+ /// considered for inlining.
+ ///
+ /// This covers std::shared_ptr, std::tr1::shared_ptr, and boost::shared_ptr,
+ /// and indeed any destructor named "~shared_ptr".
+ ///
+ /// This is controlled by the 'c++-shared_ptr-inlining' config option, which
+ /// accepts the values "true" and "false".
+ bool mayInlineCXXSharedPtrDtor();
+
/// Returns whether or not paths that go through null returns should be
/// suppressed.
///
@@ -326,6 +342,13 @@ public:
/// which accepts the values "true" and "false".
bool shouldSuppressFromCXXStandardLibrary();
+ /// Returns whether or not the diagnostic report should be always reported
+ /// in the main source file and not the headers.
+ ///
+ /// This is controlled by the 'report-in-main-source-file' config option,
+ /// which accepts the values "true" and "false".
+ bool shouldReportIssuesInMainSourceFile();
+
/// Returns whether irrelevant parts of a bug report path should be pruned
/// out of the final output.
///
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 5c560b2..9584b8b 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_GR_BUGREPORTER
#include "clang/Basic/SourceLocation.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
@@ -375,6 +376,7 @@ public:
virtual ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() = 0;
virtual ASTContext &getASTContext() = 0;
virtual SourceManager& getSourceManager() = 0;
+ virtual AnalyzerOptions& getAnalyzerOptions() = 0;
};
/// BugReporter is a utility class for generating PathDiagnostics for analysis.
@@ -442,6 +444,8 @@ public:
SourceManager& getSourceManager() { return D.getSourceManager(); }
+ AnalyzerOptions& getAnalyzerOptions() { return D.getAnalyzerOptions(); }
+
virtual bool generatePathDiagnostic(PathDiagnostic& pathDiagnostic,
PathDiagnosticConsumer &PC,
ArrayRef<BugReport *> &bugReports) {
@@ -462,20 +466,7 @@ public:
void EmitBasicReport(const Decl *DeclWithIssue,
StringRef BugName, StringRef BugCategory,
StringRef BugStr, PathDiagnosticLocation Loc,
- SourceRange* RangeBeg, unsigned NumRanges);
-
- void EmitBasicReport(const Decl *DeclWithIssue,
- StringRef BugName, StringRef BugCategory,
- StringRef BugStr, PathDiagnosticLocation Loc) {
- EmitBasicReport(DeclWithIssue, BugName, BugCategory, BugStr, Loc, 0, 0);
- }
-
- void EmitBasicReport(const Decl *DeclWithIssue,
- StringRef BugName, StringRef Category,
- StringRef BugStr, PathDiagnosticLocation Loc,
- SourceRange R) {
- EmitBasicReport(DeclWithIssue, BugName, Category, BugStr, Loc, &R, 1);
- }
+ ArrayRef<SourceRange> Ranges = None);
private:
llvm::StringMap<BugType *> StrBugTypes;
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
index 644aa31..49f9c83 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_ANALYSIS_BUGTYPE
#define LLVM_CLANG_ANALYSIS_BUGTYPE
+#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/FoldingSet.h"
#include <string>
@@ -31,10 +32,12 @@ private:
const std::string Name;
const std::string Category;
bool SuppressonSink;
+
+ virtual void anchor();
public:
BugType(StringRef name, StringRef cat)
: Name(name), Category(cat), SuppressonSink(false) {}
- virtual ~BugType();
+ virtual ~BugType() {}
// FIXME: Should these be made strings as well?
StringRef getName() const { return Name; }
@@ -50,14 +53,14 @@ public:
};
class BuiltinBug : public BugType {
- virtual void anchor();
const std::string desc;
+ virtual void anchor();
public:
BuiltinBug(const char *name, const char *description)
- : BugType(name, "Logic error"), desc(description) {}
+ : BugType(name, categories::LogicError), desc(description) {}
BuiltinBug(const char *name)
- : BugType(name, "Logic error"), desc(name) {}
+ : BugType(name, categories::LogicError), desc(name) {}
StringRef getDescription() const { return desc; }
};
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
new file mode 100644
index 0000000..3f0fe96
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
@@ -0,0 +1,25 @@
+//=--- CommonBugCategories.h - Provides common issue categories -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATIC_ANALYZER_BUG_CATEGORIES_H
+#define LLVM_CLANG_STATIC_ANALYZER_BUG_CATEGORIES_H
+
+// Common strings used for the "category" of many static analyzer issues.
+namespace clang {
+ namespace ento {
+ namespace categories {
+ extern const char * const CoreFoundationObjectiveC;
+ extern const char * const LogicError;
+ extern const char * const MemoryCoreFoundationObjectiveC;
+ extern const char * const UnixAPI;
+ }
+ }
+}
+#endif
+
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index a80b5a7..b0670da 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -38,6 +38,7 @@ class ParentMap;
class ProgramPoint;
class SourceManager;
class Stmt;
+class CallExpr;
namespace ento {
@@ -97,7 +98,6 @@ public:
enum PathGenerationScheme { None, Minimal, Extensive, AlternateExtensive };
virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
virtual bool supportsLogicalOpControlFlow() const { return false; }
- virtual bool supportsAllBlockEdges() const { return false; }
/// Return true if the PathDiagnosticConsumer supports individual
/// PathDiagnostics that span multiple files.
@@ -285,11 +285,13 @@ public:
void Profile(llvm::FoldingSetNodeID &ID) const;
+ void dump() 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.
+ /// \brief Retrieve the statement corresponding to the successor node.
static const Stmt *getNextStmt(const ExplodedNode *N);
};
@@ -331,6 +333,10 @@ private:
const std::string str;
const Kind kind;
const DisplayHint Hint;
+
+ /// \brief In the containing bug report, this piece is the last piece from
+ /// the main source file.
+ bool LastInMainSourceFile;
/// A constant string that can be used to tag the PathDiagnosticPiece,
/// typically with the identification of the creator. The actual pointer
@@ -389,6 +395,16 @@ public:
ArrayRef<SourceRange> getRanges() const { return ranges; }
virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+
+ void setAsLastInMainSourceFile() {
+ LastInMainSourceFile = true;
+ }
+
+ bool isLastInMainSourceFile() const {
+ return LastInMainSourceFile;
+ }
+
+ virtual void dump() const = 0;
};
@@ -403,6 +419,8 @@ public:
flattenTo(Result, Result, ShouldFlattenMacros);
return Result;
}
+
+ LLVM_ATTRIBUTE_USED void dump() const;
};
class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
@@ -421,7 +439,7 @@ public:
PathDiagnosticLocation getLocation() const { return Pos; }
virtual void flattenLocations() { Pos.flatten(); }
-
+
virtual void Profile(llvm::FoldingSetNodeID &ID) const;
static bool classof(const PathDiagnosticPiece *P) {
@@ -504,7 +522,7 @@ public:
}
bool hasCallStackHint() {
- return (CallStackHint != 0);
+ return CallStackHint.isValid();
}
/// Produce the hint for the given node. The node contains
@@ -515,6 +533,8 @@ public:
return "";
}
+ virtual void dump() const;
+
static inline bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == Event;
}
@@ -582,6 +602,8 @@ public:
static PathDiagnosticCallPiece *construct(PathPieces &pieces,
const Decl *caller);
+ virtual void dump() const;
+
virtual void Profile(llvm::FoldingSetNodeID &ID) const;
static inline bool classof(const PathDiagnosticPiece *P) {
@@ -649,7 +671,9 @@ public:
static inline bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == ControlFlow;
}
-
+
+ virtual void dump() const;
+
virtual void Profile(llvm::FoldingSetNodeID &ID) const;
};
@@ -673,7 +697,9 @@ public:
static inline bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == Macro;
}
-
+
+ virtual void dump() const;
+
virtual void Profile(llvm::FoldingSetNodeID &ID) const;
};
@@ -687,7 +713,10 @@ class PathDiagnostic : public llvm::FoldingSetNode {
std::string ShortDesc;
std::string Category;
std::deque<std::string> OtherDesc;
+
+ /// \brief Loc The location of the path diagnostic report.
PathDiagnosticLocation Loc;
+
PathPieces pathImpl;
SmallVector<PathPieces *, 3> pathStack;
@@ -735,12 +764,23 @@ public:
getActivePath().push_back(EndPiece);
}
+ void appendToDesc(StringRef S) {
+ if (!ShortDesc.empty())
+ ShortDesc.append(S);
+ VerboseDesc.append(S);
+ }
+
void resetPath() {
pathStack.clear();
pathImpl.clear();
Loc = PathDiagnosticLocation();
}
-
+
+ /// \brief If the last piece of the report point to the header file, resets
+ /// the location of the report to be the last location in the main source
+ /// file.
+ void resetDiagnosticLocationToMainFile();
+
StringRef getVerboseDescription() const { return VerboseDesc; }
StringRef getShortDescription() const {
return ShortDesc.empty() ? VerboseDesc : ShortDesc;
@@ -759,7 +799,7 @@ public:
void addMeta(StringRef s) { OtherDesc.push_back(s); }
PathDiagnosticLocation getLocation() const {
- assert(Loc.isValid() && "No end-of-path location set yet!");
+ assert(Loc.isValid() && "No report location set yet!");
return Loc;
}
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index 0dbaab0..cf7cf05 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -320,18 +320,35 @@ public:
class PointerEscape {
template <typename CHECKER>
static ProgramStateRef
- _checkPointerEscape(void *checker,
+ _checkPointerEscape(void *Checker,
ProgramStateRef State,
const InvalidatedSymbols &Escaped,
const CallEvent *Call,
PointerEscapeKind Kind,
- bool IsConst) {
- if (!IsConst)
- return ((const CHECKER *)checker)->checkPointerEscape(State,
+ RegionAndSymbolInvalidationTraits *ETraits) {
+
+ if (!ETraits)
+ return ((const CHECKER *)Checker)->checkPointerEscape(State,
Escaped,
Call,
Kind);
- return State;
+
+ InvalidatedSymbols RegularEscape;
+ for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
+ E = Escaped.end(); I != E; ++I)
+ if (!ETraits->hasTrait(*I,
+ RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
+ !ETraits->hasTrait(*I,
+ RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
+ RegularEscape.insert(*I);
+
+ if (RegularEscape.empty())
+ return State;
+
+ return ((const CHECKER *)Checker)->checkPointerEscape(State,
+ RegularEscape,
+ Call,
+ Kind);
}
public:
@@ -346,18 +363,32 @@ public:
class ConstPointerEscape {
template <typename CHECKER>
static ProgramStateRef
- _checkConstPointerEscape(void *checker,
+ _checkConstPointerEscape(void *Checker,
ProgramStateRef State,
const InvalidatedSymbols &Escaped,
const CallEvent *Call,
PointerEscapeKind Kind,
- bool IsConst) {
- if (IsConst)
- return ((const CHECKER *)checker)->checkConstPointerEscape(State,
- Escaped,
- Call,
- Kind);
- return State;
+ RegionAndSymbolInvalidationTraits *ETraits) {
+
+ if (!ETraits)
+ return State;
+
+ InvalidatedSymbols ConstEscape;
+ for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
+ E = Escaped.end(); I != E; ++I)
+ if (ETraits->hasTrait(*I,
+ RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
+ !ETraits->hasTrait(*I,
+ RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
+ ConstEscape.insert(*I);
+
+ if (ConstEscape.empty())
+ return State;
+
+ return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
+ ConstEscape,
+ Call,
+ Kind);
}
public:
@@ -502,10 +533,14 @@ struct ImplicitNullDerefEvent {
};
/// \brief A helper class which wraps a boolean value set to false by default.
+///
+/// This class should behave exactly like 'bool' except that it doesn't need to
+/// be explicitly initialized.
struct DefaultBool {
bool val;
DefaultBool() : val(false) {}
- operator bool() const { return val; }
+ /*implicit*/ operator bool&() { return val; }
+ /*implicit*/ operator const bool&() const { return val; }
DefaultBool &operator=(bool b) { val = b; return *this; }
};
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index b2411e6..8ad67c1 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -19,7 +19,6 @@
#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"
#include <vector>
@@ -366,14 +365,16 @@ public:
/// \param Escaped The list of escaped symbols.
/// \param Call The corresponding CallEvent, if the symbols escape as
/// parameters to the given call.
- /// \param IsConst Specifies if the pointer is const.
+ /// \param Kind The reason of pointer escape.
+ /// \param ITraits Information about invalidation for a particular
+ /// region/symbol.
/// \returns Checkers can modify the state by returning a new one.
ProgramStateRef
runCheckersForPointerEscape(ProgramStateRef State,
const InvalidatedSymbols &Escaped,
const CallEvent *Call,
PointerEscapeKind Kind,
- bool IsConst = false);
+ RegionAndSymbolInvalidationTraits *ITraits);
/// \brief Run checkers for handling assumptions on symbolic values.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
@@ -465,7 +466,7 @@ public:
const InvalidatedSymbols &Escaped,
const CallEvent *Call,
PointerEscapeKind Kind,
- bool IsConst)>
+ RegionAndSymbolInvalidationTraits *ITraits)>
CheckPointerEscapeFunc;
typedef CheckerFn<ProgramStateRef (ProgramStateRef,
@@ -581,35 +582,12 @@ private:
};
std::vector<StmtCheckerInfo> StmtCheckers;
- struct CachedStmtCheckersKey {
- unsigned StmtKind;
- bool IsPreVisit;
-
- CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { }
- CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit)
- : StmtKind(stmtKind), IsPreVisit(isPreVisit) { }
-
- static CachedStmtCheckersKey getSentinel() {
- return CachedStmtCheckersKey(~0U, 0);
- }
- unsigned getHashValue() const {
- llvm::FoldingSetNodeID ID;
- ID.AddInteger(StmtKind);
- ID.AddBoolean(IsPreVisit);
- return ID.ComputeHash();
- }
- bool operator==(const CachedStmtCheckersKey &RHS) const {
- return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit;
- }
- };
- friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>;
-
typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
- typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers>
- CachedStmtCheckersMapTy;
+ typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
CachedStmtCheckersMapTy CachedStmtCheckersMap;
- CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit);
+ const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
+ bool isPreVisit);
std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
@@ -659,30 +637,4 @@ private:
} // end clang namespace
-namespace llvm {
- /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key
- /// in DenseMap and DenseSets.
- template <>
- struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> {
- static inline clang::ento::CheckerManager::CachedStmtCheckersKey
- getEmptyKey() {
- return clang::ento::CheckerManager::CachedStmtCheckersKey();
- }
- static inline clang::ento::CheckerManager::CachedStmtCheckersKey
- getTombstoneKey() {
- return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel();
- }
-
- static unsigned
- getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) {
- return S.getHashValue();
- }
-
- static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS,
- clang::ento::CheckerManager::CachedStmtCheckersKey RHS) {
- return LHS == RHS;
- }
- };
-} // end namespace llvm
-
#endif
diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
index 4557aa4..ca68a74 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
@@ -54,10 +54,6 @@
//
// For a complete working example, see examples/analyzer-plugin.
-
-namespace clang {
-namespace ento {
-
#ifndef CLANG_ANALYZER_API_VERSION_STRING
// FIXME: The Clang version string is not particularly granular;
// the analyzer infrastructure can change a lot between releases.
@@ -67,6 +63,9 @@ namespace ento {
#define CLANG_ANALYZER_API_VERSION_STRING CLANG_VERSION_STRING
#endif
+namespace clang {
+namespace ento {
+
class CheckerOptInfo;
/// Manages a set of available checkers for running a static analysis.
diff --git a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
index b856de7..43e9166 100644
--- a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
+++ b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
@@ -27,18 +27,12 @@ namespace ento {
class PathDiagnosticConsumer;
typedef std::vector<PathDiagnosticConsumer*> PathDiagnosticConsumers;
-#define CREATE_CONSUMER(NAME)\
-void create ## NAME ## DiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,\
- PathDiagnosticConsumers &C,\
- const std::string& prefix,\
- const Preprocessor &PP);
-
-CREATE_CONSUMER(HTML)
-CREATE_CONSUMER(Plist)
-CREATE_CONSUMER(PlistMultiFile)
-CREATE_CONSUMER(TextPath)
-
-#undef CREATE_CONSUMER
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)\
+void CREATEFN(AnalyzerOptions &AnalyzerOpts,\
+ PathDiagnosticConsumers &C,\
+ const std::string &Prefix,\
+ const Preprocessor &PP);
+#include "clang/StaticAnalyzer/Core/Analyses.def"
} // end 'ento' namespace
} // end 'clang' namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index 458c896..d7d83ce 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -65,6 +65,10 @@ public:
StoreManagerCreator getStoreManagerCreator() {
return CreateStoreMgr;
}
+
+ AnalyzerOptions& getAnalyzerOptions() {
+ return options;
+ }
ConstraintManagerCreator getConstraintManagerCreator() {
return CreateConstraintMgr;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index f990b8d..cfaf085 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -228,11 +228,6 @@ public:
return false;
}
- /// \brief Returns true if this is a call to a variadic function or method.
- virtual bool isVariadic() const {
- return false;
- }
-
/// \brief Returns a source range for the entire call, suitable for
/// outputting in diagnostics.
virtual SourceRange getSourceRange() const {
@@ -341,6 +336,11 @@ public:
/// This will return a null QualType if the result type cannot be determined.
static QualType getDeclaredResultType(const Decl *D);
+ /// \brief Returns true if the given decl is known to be variadic.
+ ///
+ /// \p D must not be null.
+ static bool isVariadic(const Decl *D);
+
// Iterator access to formal parameters and their types.
private:
typedef std::const_mem_fun_t<QualType, ParmVarDecl> get_type_fun;
@@ -350,19 +350,13 @@ public:
/// Returns an iterator over the call's formal parameters.
///
- /// If UseDefinitionParams is set, this will return the parameter decls
- /// used in the callee's definition (suitable for inlining). Most of the
- /// time it is better to use the decl found by name lookup, which likely
- /// carries more annotations.
- ///
/// Remember that the number of formal parameters may not match the number
/// of arguments for all calls. However, the first parameter will always
/// correspond with the argument value returned by \c getArgSVal(0).
///
- /// If the call has no accessible declaration (or definition, if
- /// \p UseDefinitionParams is set), \c param_begin() will be equal to
- /// \c param_end().
- virtual param_iterator param_begin() const =0;
+ /// If the call has no accessible declaration, \c param_begin() will be equal
+ /// to \c param_end().
+ virtual param_iterator param_begin() const = 0;
/// \sa param_begin()
virtual param_iterator param_end() const = 0;
@@ -423,10 +417,6 @@ public:
return RuntimeDefinition();
}
- virtual bool isVariadic() const {
- return getDecl()->isVariadic();
- }
-
virtual bool argumentsMayEscape() const;
virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
@@ -527,10 +517,6 @@ public:
return RuntimeDefinition(getBlockDecl());
}
- virtual bool isVariadic() const {
- return getBlockDecl()->isVariadic();
- }
-
virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
BindingsTy &Bindings) const;
@@ -849,9 +835,6 @@ public:
virtual const Expr *getArgExpr(unsigned Index) const {
return getOriginExpr()->getArg(Index);
}
- virtual bool isVariadic() const {
- return getDecl()->isVariadic();
- }
bool isInstanceMessage() const {
return getOriginExpr()->isInstanceMessage();
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index edcfc8a..bf17cd8 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -184,7 +184,7 @@ public:
bool isSink() const { return Succs.getFlag(); }
- bool hasSinglePred() const {
+ bool hasSinglePred() const {
return (pred_size() == 1);
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 33e4431..d89dffe 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -203,6 +203,8 @@ public:
void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
ExplodedNode *Pred, ExplodedNodeSet &Dst);
+ void ProcessDeleteDtor(const CFGDeleteDtor D,
+ ExplodedNode *Pred, ExplodedNodeSet &Dst);
void ProcessBaseDtor(const CFGBaseDtor D,
ExplodedNode *Pred, ExplodedNodeSet &Dst);
void ProcessMemberDtor(const CFGMemberDtor D,
@@ -476,14 +478,14 @@ protected:
SVal Loc, SVal Val);
/// Call PointerEscape callback when a value escapes as a result of
/// region invalidation.
- /// \param[in] IsConst Specifies that the pointer is const.
+ /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
ProgramStateRef notifyCheckersOfPointerEscape(
ProgramStateRef State,
const InvalidatedSymbols *Invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call,
- bool IsConst);
+ RegionAndSymbolInvalidationTraits &ITraits);
public:
// FIXME: 'tag' should be removed, and a LocationContext should be used
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 9b4f77d..cc790c1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -635,12 +635,14 @@ class BlockDataRegion : public TypedRegion {
friend class MemRegionManager;
const BlockTextRegion *BC;
const LocationContext *LC; // Can be null */
+ unsigned BlockCount;
void *ReferencedVars;
void *OriginalVars;
BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
- const MemRegion *sreg)
+ unsigned count, const MemRegion *sreg)
: TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
+ BlockCount(count),
ReferencedVars(0), OriginalVars(0) {}
public:
@@ -692,7 +694,8 @@ public:
void Profile(llvm::FoldingSetNodeID& ID) const;
static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
- const LocationContext *, const MemRegion *);
+ const LocationContext *, unsigned,
+ const MemRegion *);
static bool classof(const MemRegion* R) {
return R->getKind() == BlockDataRegionKind;
@@ -1270,7 +1273,13 @@ public:
/// argument is allowed to be NULL for cases where we have no known
/// context.
const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
- const LocationContext *lc = NULL);
+ const LocationContext *lc,
+ unsigned blockCount);
+
+ /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
+ /// by static references. This differs from getCXXTempObjectRegion in the
+ /// super-region used.
+ const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
private:
template <typename RegionTy, typename A1>
@@ -1304,6 +1313,39 @@ private:
inline ASTContext &MemRegion::getContext() const {
return getMemRegionManager()->getContext();
}
+
+//===----------------------------------------------------------------------===//
+// Means for storing region/symbol handling traits.
+//===----------------------------------------------------------------------===//
+
+/// Information about invalidation for a particular region/symbol.
+class RegionAndSymbolInvalidationTraits {
+ typedef unsigned char StorageTypeForKinds;
+ llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
+ llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
+
+ typedef llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator
+ const_region_iterator;
+ typedef llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator
+ const_symbol_iterator;
+
+public:
+ /// \brief Describes different invalidation traits.
+ enum InvalidationKinds {
+ /// Tells that a region's contents is not changed.
+ TK_PreserveContents = 0x1,
+ /// Suppress pointer-escaping of a region.
+ TK_SuppressEscape = 0x2
+
+ // Do not forget to extend StorageTypeForKinds if number of traits exceed
+ // the number of bits StorageTypeForKinds can store.
+ };
+
+ void setTrait(SymbolRef Sym, InvalidationKinds IK);
+ void setTrait(const MemRegion *MR, InvalidationKinds IK);
+ bool hasTrait(SymbolRef Sym, InvalidationKinds IK);
+ bool hasTrait(const MemRegion *MR, InvalidationKinds IK);
+};
} // end GR namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 42ef1db..03739ed 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -232,22 +232,21 @@ public:
/// \param IS the set of invalidated symbols.
/// \param Call if non-null, the invalidated regions represent parameters to
/// the call and should be considered directly invalidated.
- /// \param ConstRegions the set of regions whose contents are accessible,
- /// even though the regions themselves should not be invalidated.
+ /// \param ITraits information about special handling for a particular
+ /// region/symbol.
ProgramStateRef
invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
unsigned BlockCount, const LocationContext *LCtx,
bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
const CallEvent *Call = 0,
- ArrayRef<const MemRegion *> ConstRegions =
- ArrayRef<const MemRegion *>()) const;
+ RegionAndSymbolInvalidationTraits *ITraits = 0) const;
ProgramStateRef
invalidateRegions(ArrayRef<SVal> Regions, const Expr *E,
unsigned BlockCount, const LocationContext *LCtx,
bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
const CallEvent *Call = 0,
- ArrayRef<SVal> ConstRegions = ArrayRef<SVal>()) const;
+ RegionAndSymbolInvalidationTraits *ITraits = 0) const;
/// enterStackFrame - Returns the state for entry to the given stack frame,
/// preserving the current state.
@@ -425,9 +424,9 @@ private:
const Expr *E, unsigned BlockCount,
const LocationContext *LCtx,
bool ResultsInSymbolEscape,
- InvalidatedSymbols &IS,
- const CallEvent *Call,
- ArrayRef<SVal> ConstValues) const;
+ InvalidatedSymbols *IS,
+ RegionAndSymbolInvalidationTraits *HTraits,
+ const CallEvent *Call) const;
};
//===----------------------------------------------------------------------===//
@@ -516,8 +515,8 @@ public:
public:
- SVal ArrayToPointer(Loc Array) {
- return StoreMgr->ArrayToPointer(Array);
+ SVal ArrayToPointer(Loc Array, QualType ElementTy) {
+ return StoreMgr->ArrayToPointer(Array, ElementTy);
}
// Methods that manipulate the GDM.
@@ -798,7 +797,7 @@ CB ProgramState::scanReachableSymbols(const MemRegion * const *beg,
/// A Utility class that allows to visit the reachable symbols using a custom
/// SymbolVisitor.
class ScanReachableSymbols {
- typedef llvm::DenseMap<const void*, unsigned> VisitedItems;
+ typedef llvm::DenseSet<const void*> VisitedItems;
VisitedItems visited;
ProgramStateRef state;
@@ -808,6 +807,7 @@ public:
ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v)
: state(st), visitor(v) {}
+ bool scan(nonloc::LazyCompoundVal val);
bool scan(nonloc::CompoundVal val);
bool scan(SVal val);
bool scan(const MemRegion *R);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index bbb5688..c5d0a92 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -200,7 +200,8 @@ public:
DefinedSVal getFunctionPointer(const FunctionDecl *func);
DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy,
- const LocationContext *locContext);
+ const LocationContext *locContext,
+ unsigned blockCount);
/// Returns the value of \p E, if it can be determined in a non-path-sensitive
/// manner.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 326e784..5a426ef 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -290,7 +290,7 @@ public:
static inline bool isLocType(QualType T) {
return T->isAnyPointerType() || T->isBlockPointerType() ||
- T->isReferenceType();
+ T->isReferenceType() || T->isNullPtrType();
}
private:
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index b219495..530dae5 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -111,7 +111,7 @@ public:
/// ArrayToPointer - Used by ExprEngine::VistCast to handle implicit
/// conversions between arrays and pointers.
- virtual SVal ArrayToPointer(Loc Array) = 0;
+ virtual SVal ArrayToPointer(Loc Array, QualType ElementTy) = 0;
/// Evaluates a chain of derived-to-base casts through the path specified in
/// \p Cast.
@@ -164,8 +164,6 @@ public:
/// the given regions. Optionally, invalidates non-static globals as well.
/// \param[in] store The initial store
/// \param[in] Values The values to invalidate.
- /// \param[in] ConstValues The values to invalidate; these are known to be
- /// const, so only regions accesible from them should be invalidated.
/// \param[in] E The current statement being evaluated. Used to conjure
/// symbols to mark the values of invalidated regions.
/// \param[in] Count The current block count. Used to conjure
@@ -174,13 +172,10 @@ public:
/// globals should get invalidated.
/// \param[in,out] IS A set to fill with any symbols that are no longer
/// accessible. Pass \c NULL if this information will not be used.
- /// \param[in,out] ConstIS A set to fill with any symbols corresponding to
- /// the ConstValues.
+ /// \param[in] ITraits Information about invalidation for a particular
+ /// region/symbol.
/// \param[in,out] InvalidatedTopLevel A vector to fill with regions
- //// explicitely being invalidated. Pass \c NULL if this
- /// information will not be used.
- /// \param[in,out] InvalidatedTopLevelConst A vector to fill with const
- //// regions explicitely being invalidated. Pass \c NULL if this
+ //// explicitly being invalidated. Pass \c NULL if this
/// information will not be used.
/// \param[in,out] Invalidated A vector to fill with any regions being
/// invalidated. This should include any regions explicitly invalidated
@@ -188,14 +183,12 @@ public:
/// information will not be used.
virtual StoreRef invalidateRegions(Store store,
ArrayRef<SVal> Values,
- ArrayRef<SVal> ConstValues,
const Expr *E, unsigned Count,
const LocationContext *LCtx,
const CallEvent *Call,
InvalidatedSymbols &IS,
- InvalidatedSymbols &ConstIS,
+ RegionAndSymbolInvalidationTraits &ITraits,
InvalidatedRegions *InvalidatedTopLevel,
- InvalidatedRegions *InvalidatedTopLevelConst,
InvalidatedRegions *Invalidated) = 0;
/// enterStackFrame - Let the StoreManager to do something when execution
@@ -231,7 +224,7 @@ public:
bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
SVal val);
- operator bool() { return First && Binding; }
+ LLVM_EXPLICIT operator bool() { return First && Binding; }
const MemRegion *getRegion() { return Binding; }
};
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index d410063..f653c70 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -134,7 +134,7 @@ public:
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
const CallEvent *Call,
- bool IsConst = false) = 0;
+ RegionAndSymbolInvalidationTraits &HTraits) = 0;
/// printState - Called by ProgramStateManager to print checker-specific data.
virtual void printState(raw_ostream &Out, ProgramStateRef State,
OpenPOWER on IntegriCloud