]> granicus.if.org Git - clang/commitdiff
[analyzer] Use the signature of the primary template for issue hash calculation
authorGabor Horvath <xazax.hun@gmail.com>
Mon, 30 Oct 2017 12:16:07 +0000 (12:16 +0000)
committerGabor Horvath <xazax.hun@gmail.com>
Mon, 30 Oct 2017 12:16:07 +0000 (12:16 +0000)
Now when a template is instantiated more times and there is a bug found in the
instantiations the issue hash will be different for each instantiation even if
every other property of the bug (path, message, location) is the same.

This patch aims to resolve this issue. Note that explicit specializations still
generate different hashes but that is intended.

Differential Revision: https://reviews.llvm.org/D38728

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

lib/StaticAnalyzer/Core/IssueHash.cpp
test/Analysis/bug_hash_test.cpp
test/Analysis/edges-new.mm

index abdea88b1db6f6df4a641b02006168fe939350df..274ebe7a941bce693a3277e68c30499fafe58179 100644 (file)
@@ -33,6 +33,13 @@ static std::string GetSignature(const FunctionDecl *Target) {
     return "";
   std::string Signature;
 
+  // When a flow sensitive bug happens in templated code we should not generate
+  // distinct hash value for every instantiation. Use the signature from the
+  // primary template.
+  if (const FunctionDecl *InstantiatedFrom =
+          Target->getTemplateInstantiationPattern())
+    Target = InstantiatedFrom;
+
   if (!isa<CXXConstructorDecl>(Target) && !isa<CXXDestructorDecl>(Target) &&
       !isa<CXXConversionDecl>(Target))
     Signature.append(Target->getReturnType().getAsString()).append(" ");
index f1fbb59a6a46a9ad23104cf19a9772f8e516f647..f397d181e665697023e7bdba8e1c21544166eb3f 100644 (file)
@@ -71,15 +71,13 @@ void testLambda() {
 
 template <typename T>
 void f(T) {
-  clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void f(double)$27$clang_analyzer_hashDump(5);$Category}}
-                               // expected-warning@-1{{debug.ExprInspection$void f(int)$27$clang_analyzer_hashDump(5);$Category}}
+  clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void f(T)$27$clang_analyzer_hashDump(5);$Category}}
 }
 
 template <typename T>
 struct TX {
   void f(T) {
-    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TX<double>::f(double)$29$clang_analyzer_hashDump(5);$Category}}
-                                 // expected-warning@-1{{debug.ExprInspection$void TX<int>::f(int)$29$clang_analyzer_hashDump(5);$Category}}
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TX::f(T)$29$clang_analyzer_hashDump(5);$Category}}
   }
 };
 
@@ -99,11 +97,17 @@ template <typename T>
 struct TTX {
   template<typename S>
   void f(T, S) {
-    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TTX<int>::f(int, int)$29$clang_analyzer_hashDump(5);$Category}}
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TTX::f(T, S)$29$clang_analyzer_hashDump(5);$Category}}
   }
 };
 
 void g() {
+  // TX<int> and TX<double> is instantiated from the same code with the same
+  // source locations. The same error happining in both of the instantiations
+  // should share the common hash. This means we should not include the
+  // template argument for these types in the function signature.
+  // Note that, we still want the hash to be different for explicit
+  // specializations.
   TX<int> x;
   TX<double> y;
   TX<long> xl;
index 47a125ab0901f897a7d5ec653e1fe46f0d8d875e..f310f1bfa12eaa88365a81d3e9e62e259bec7a43 100644 (file)
@@ -20288,7 +20288,7 @@ namespace rdar14960554 {
 // CHECK-NEXT:    <key>type</key><string>Bad deallocator</string>
 // CHECK-NEXT:    <key>check_name</key><string>unix.MismatchedDeallocator</string>
 // CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>d9dbbf68db41ab74e2158f4b131abe34</string>
+// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>046c88d1c91ff46d6506dff5ff880756</string>
 // CHECK-NEXT:   <key>issue_hash_function_offset</key><string>0</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>