From 1157fbd7d668f9579b5a633dd245657bb940076b Mon Sep 17 00:00:00 2001 From: Gabor Horvath Date: Mon, 30 Oct 2017 12:16:07 +0000 Subject: [PATCH] [analyzer] Use the signature of the primary template for issue hash calculation 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 | 7 +++++++ test/Analysis/bug_hash_test.cpp | 14 +++++++++----- test/Analysis/edges-new.mm | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/StaticAnalyzer/Core/IssueHash.cpp b/lib/StaticAnalyzer/Core/IssueHash.cpp index abdea88b1d..274ebe7a94 100644 --- a/lib/StaticAnalyzer/Core/IssueHash.cpp +++ b/lib/StaticAnalyzer/Core/IssueHash.cpp @@ -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(Target) && !isa(Target) && !isa(Target)) Signature.append(Target->getReturnType().getAsString()).append(" "); diff --git a/test/Analysis/bug_hash_test.cpp b/test/Analysis/bug_hash_test.cpp index f1fbb59a6a..f397d181e6 100644 --- a/test/Analysis/bug_hash_test.cpp +++ b/test/Analysis/bug_hash_test.cpp @@ -71,15 +71,13 @@ void testLambda() { template 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 struct TX { void f(T) { - clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TX::f(double)$29$clang_analyzer_hashDump(5);$Category}} - // expected-warning@-1{{debug.ExprInspection$void TX::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 struct TTX { template void f(T, S) { - clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TTX::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 and TX 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 x; TX y; TX xl; diff --git a/test/Analysis/edges-new.mm b/test/Analysis/edges-new.mm index 47a125ab09..f310f1bfa1 100644 --- a/test/Analysis/edges-new.mm +++ b/test/Analysis/edges-new.mm @@ -20288,7 +20288,7 @@ namespace rdar14960554 { // CHECK-NEXT: typeBad deallocator // CHECK-NEXT: check_nameunix.MismatchedDeallocator // CHECK-NEXT: -// CHECK-NEXT: issue_hash_content_of_line_in_contextd9dbbf68db41ab74e2158f4b131abe34 +// CHECK-NEXT: issue_hash_content_of_line_in_context046c88d1c91ff46d6506dff5ff880756 // CHECK-NEXT: issue_hash_function_offset0 // CHECK-NEXT: location // CHECK-NEXT: -- 2.40.0