Index: lib/StaticAnalyzer/Core/IssueHash.cpp =================================================================== --- lib/StaticAnalyzer/Core/IssueHash.cpp +++ lib/StaticAnalyzer/Core/IssueHash.cpp @@ -33,6 +33,13 @@ 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(" "); Index: test/Analysis/bug_hash_test.cpp =================================================================== --- test/Analysis/bug_hash_test.cpp +++ test/Analysis/bug_hash_test.cpp @@ -71,15 +71,13 @@ 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 @@ 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; Index: test/Analysis/edges-new.mm =================================================================== --- test/Analysis/edges-new.mm +++ test/Analysis/edges-new.mm @@ -20288,7 +20288,7 @@ // 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: