]> granicus.if.org Git - clang/commitdiff
[analyzer] Suppress reports coming from std::__independent_bits_engine
authorAnna Zaks <ganna@apple.com>
Wed, 6 Jan 2016 00:32:52 +0000 (00:32 +0000)
committerAnna Zaks <ganna@apple.com>
Wed, 6 Jan 2016 00:32:52 +0000 (00:32 +0000)
The analyzer reports a shift by a negative value in the constructor. The bug can
be easily triggered by calling std::random_shuffle on a vector
(<rdar://problem/19658126>).

(The shift by a negative value is reported because __w0_ gets constrained to
63 by the conditions along the path:__w0_ < _WDt && __w0_ >= _WDt-1,
where _WDt is 64. In normal execution, __w0_ is not 63, it is 1 and there is
no overflow. The path is infeasible, but the analyzer does not know about that.)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@256886 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
test/Analysis/Inputs/system-header-simulator-cxx.h
test/Analysis/inlining/stl.cpp

index ec1310d91814caced30d2ed6f59605b76c772063..cf1e0a6a656cfa076865dbff381fbc23f213842f 100644 (file)
@@ -1542,6 +1542,16 @@ LikelyFalsePositiveSuppressionBRVisitor::getEndPath(BugReporterContext &BRC,
         }
       }
 
+      // The analyzer issues a false positive when the constructor of
+      // std::__independent_bits_engine from algorithms is used.
+      if (const CXXConstructorDecl *MD = dyn_cast<CXXConstructorDecl>(D)) {
+        const CXXRecordDecl *CD = MD->getParent();
+        if (CD->getName() == "__independent_bits_engine") {
+          BR.markInvalid(getTag(), nullptr);
+          return nullptr;
+        }
+      }
+
       // The analyzer issues a false positive on
       //   std::basic_string<uint8_t> v; v.push_back(1);
       // and
index 35869214ed7e8235212637740a6dde51e306e386..f9049c3ae9e72f89c9077d8e33cc0c9506eabebf 100644 (file)
@@ -198,6 +198,25 @@ namespace std {
       storage.assignExternal(new _CharT[4]);
     }
   };
+
+template<class _Engine, class _UIntType>
+class __independent_bits_engine {
+public:
+  // constructors and seeding functions
+  __independent_bits_engine(_Engine& __e, size_t __w);
+};
+
+template<class _Engine, class _UIntType>
+__independent_bits_engine<_Engine, _UIntType>
+    ::__independent_bits_engine(_Engine& __e, size_t __w)
+{
+  // Fake error trigger.
+  // No warning is expected as we are suppressing warning coming
+  // out of std::basic_string.
+  int z = 0;
+  z = 5/z;
+}
+
 }
 
 void* operator new(std::size_t, const std::nothrow_t&) throw();
index 711c30f1031dd21ca273c640188e8f31aea6ce2d..2a8520f7671857f0d58dd8760788520317a2b3f8 100644 (file)
@@ -47,3 +47,8 @@ void testBasicStringSuppression_assign(std::basic_string<char32_t> &v,
                                        const std::basic_string<char32_t> &v2) {
   v = v2;
 }
+
+class MyEngine;
+void testSupprerssion_independent_bits_engine(MyEngine& e) {
+  std::__independent_bits_engine<MyEngine, unsigned int> x(e, 64); // no-warning
+}