diff options
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | 31 | ||||
| -rw-r--r-- | clang/test/Analysis/Inputs/system-header-simulator-cxx.h | 17 | ||||
| -rw-r--r-- | clang/test/Analysis/inlining/stl.cpp | 6 | 
3 files changed, 46 insertions, 8 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index ffc8f09dcb8..70354fe21c3 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1521,18 +1521,33 @@ LikelyFalsePositiveSuppressionBRVisitor::getEndPath(BugReporterContext &BRC,                                                      BugReport &BR) {    // Here we suppress false positives coming from system headers. This list is    // based on known issues. - -  // Skip reports within the 'std' namespace. Although these can sometimes be -  // the user's fault, we currently don't report them very well, and -  // Note that this will not help for any other data structure libraries, like -  // TR1, Boost, or llvm/ADT.    ExprEngine &Eng = BRC.getBugReporter().getEngine();    AnalyzerOptions &Options = Eng.getAnalysisManager().options; -  if (Options.shouldSuppressFromCXXStandardLibrary()) { -    const LocationContext *LCtx = N->getLocationContext(); -    if (isInStdNamespace(LCtx->getDecl())) { +  const Decl *D = N->getLocationContext()->getDecl(); + +  if (isInStdNamespace(D)) { +    // Skip reports within the 'std' namespace. Although these can sometimes be +    // the user's fault, we currently don't report them very well, and +    // Note that this will not help for any other data structure libraries, like +    // TR1, Boost, or llvm/ADT. +    if (Options.shouldSuppressFromCXXStandardLibrary()) {        BR.markInvalid(getTag(), 0);        return 0; + +    } else { +      // If the the complete 'std' suppression is not enabled, suppress reports +      // from the 'std' namespace that are known to produce false positives. + +      // The analyzer issues a false use-after-free when std::list::pop_front +      // or std::list::pop_back are called multiple times because we cannot +      // reason about the internal invariants of the datastructure. +      const DeclContext *DC = +        D->getDeclContext()->getEnclosingNamespaceContext(); +      const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC); +      if (ND && ND->getName() == "list") { +          BR.markInvalid(getTag(), 0); +          return 0; +      }      }    } diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h index 6e434a04b23..049d6be91b4 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -86,6 +86,23 @@ namespace std {    struct forward_iterator_tag : public input_iterator_tag { };    struct bidirectional_iterator_tag : public forward_iterator_tag { };    struct random_access_iterator_tag : public bidirectional_iterator_tag { }; + +  template <class _Tp> +  class allocator {}; + +  template <class _Tp, class _Alloc> +  class __list_imp +  {}; + +  template <class _Tp, class _Alloc = allocator<_Tp> > +  class list +  : private __list_imp<_Tp, _Alloc> +  { +  public: +    void pop_front(); +    bool empty() const; +  }; +  }  void* operator new(std::size_t, const std::nothrow_t&) throw(); diff --git a/clang/test/Analysis/inlining/stl.cpp b/clang/test/Analysis/inlining/stl.cpp index 6053daaf3a2..7f3bcdab5ec 100644 --- a/clang/test/Analysis/inlining/stl.cpp +++ b/clang/test/Analysis/inlining/stl.cpp @@ -27,3 +27,9 @@ void testException(std::exception e) {    // expected-warning@-4 {{UNKNOWN}}  #endif  } + +void testList_pop_front(std::list<int> list) { +  while(!list.empty()) +    list.pop_front();  // no-warning +} +  | 

