summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h')
-rw-r--r--contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h63
1 files changed, 49 insertions, 14 deletions
diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h
index 0dbaab0..cf7cf05 100644
--- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/contrib/llvm/tools/clang/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; }
};
OpenPOWER on IntegriCloud