Index: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1596,12 +1596,6 @@ } } - // The analyzer issues a false positive on - // std::basic_string v; v.push_back(1); - // and - // std::u16string s; s += u'a'; - // because we cannot reason about the internal invariants of the - // datastructure. for (const LocationContext *LCtx = N->getLocationContext(); LCtx; LCtx = LCtx->getParent()) { const CXXMethodDecl *MD = dyn_cast(LCtx->getDecl()); @@ -1609,10 +1603,24 @@ continue; const CXXRecordDecl *CD = MD->getParent(); + // The analyzer issues a false positive on + // std::basic_string v; v.push_back(1); + // and + // std::u16string s; s += u'a'; + // because we cannot reason about the internal invariants of the + // datastructure. if (CD->getName() == "basic_string") { BR.markInvalid(getTag(), nullptr); return nullptr; } + + // The analyzer issues a false positive on + // std::shared_ptr p(new int(1)); p = nullptr; + // because it does not reason properly about temporary destructors. + if (CD->getName() == "shared_ptr") { + BR.markInvalid(getTag(), nullptr); + return nullptr; + } } } } Index: test/Analysis/Inputs/system-header-simulator-cxx.h =================================================================== --- test/Analysis/Inputs/system-header-simulator-cxx.h +++ test/Analysis/Inputs/system-header-simulator-cxx.h @@ -329,6 +329,36 @@ z = 5/z; } +#if __has_feature(cxx_decltype) +typedef decltype(nullptr) nullptr_t; + +template +class shared_ptr +{ +public: + constexpr shared_ptr(nullptr_t); + explicit shared_ptr(_Tp* __p); + + shared_ptr(shared_ptr&& __r) { } + + ~shared_ptr(); + + shared_ptr& operator=(shared_ptr&& __r) { + // Fake error trigger. + // No warning is expected as we are suppressing warning coming + // out of std::basic_string. + int z = 0; + z = 5/z; + } +}; + +template +inline +constexpr +shared_ptr<_Tp>::shared_ptr(nullptr_t) { +} + +#endif // __has_feature(cxx_decltype) } void* operator new(std::size_t, const std::nothrow_t&) throw(); Index: test/Analysis/inlining/stl.cpp =================================================================== --- test/Analysis/inlining/stl.cpp +++ test/Analysis/inlining/stl.cpp @@ -52,3 +52,9 @@ void testSupprerssion_independent_bits_engine(MyEngine& e) { std::__independent_bits_engine x(e, 64); // no-warning } + +void testSuppression_std_shared_pointer() { + std::shared_ptr p(new int(1)); + + p = nullptr; // no-warning +}