// Output the bug hash for issue unique-ing. Currently, it's just an
// offset from the beginning of the function.
if (const Stmt *Body = DeclWithIssue->getBody()) {
- FullSourceLoc Loc(SM->getExpansionLoc(D->getLocation().asLocation()),
- *SM);
- FullSourceLoc FunLoc(SM->getExpansionLoc(Body->getLocStart()), *SM);
- o << " <key>issue_hash</key><string>"
- << Loc.getExpansionLineNumber() - FunLoc.getExpansionLineNumber();
- // Augment the hash with the bug uniqueing location. For example,
- // this ensures that two leaks reported on the same line will have
- // different issue_hashes.
+ // If the bug uniqueing location exists, use it for the hash.
+ // For example, this ensures that two leaks reported on the same line
+ // will have different issue_hashes and that the hash will identify
+ // the leak location even after code is added between the allocation
+ // site and the end of scope (leak report location).
PathDiagnosticLocation UPDLoc = D->getUniqueingLoc();
if (UPDLoc.isValid()) {
FullSourceLoc UL(SM->getExpansionLoc(UPDLoc.asLocation()),
*SM);
FullSourceLoc UFunL(SM->getExpansionLoc(
D->getUniqueingDecl()->getBody()->getLocStart()), *SM);
- o << "_"
- << UL.getExpansionLineNumber() - UFunL.getExpansionLineNumber();
+ o << " <key>issue_hash</key><string>"
+ << UL.getExpansionLineNumber() - UFunL.getExpansionLineNumber()
+ << "</string>\n";
+
+ // Otherwise, use the location on which the bug is reported.
+ } else {
+ FullSourceLoc L(SM->getExpansionLoc(D->getLocation().asLocation()),
+ *SM);
+ FullSourceLoc FunL(SM->getExpansionLoc(Body->getLocStart()), *SM);
+ o << " <key>issue_hash</key><string>"
+ << L.getExpansionLineNumber() - FunL.getExpansionLineNumber()
+ << "</string>\n";
}
- o << "</string>\n";
+
}
}
}
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>diagnosticTest</string>
-// CHECK-NEXT: <key>issue_hash</key><string>5_2</string>
+// CHECK-NEXT: <key>issue_hash</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>15</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>myArrayAllocation</string>
-// CHECK-NEXT: <key>issue_hash</key><string>4_2</string>
+// CHECK-NEXT: <key>issue_hash</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>22</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>reallocDiagnostics</string>
-// CHECK-NEXT: <key>issue_hash</key><string>5_1</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>29</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>test_wrapper</string>
-// CHECK-NEXT: <key>issue_hash</key><string>3_1</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>46</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>reallocIntra</string>
-// CHECK-NEXT: <key>issue_hash</key><string>3_1</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>77</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>use_ret</string>
-// CHECK-NEXT: <key>issue_hash</key><string>3_2</string>
+// CHECK-NEXT: <key>issue_hash</key><string>2</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>LeakedSymbol</string>
-// CHECK-NEXT: <key>issue_hash</key><string>8_3</string>
+// CHECK-NEXT: <key>issue_hash</key><string>3</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>98</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>function_with_leak1</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2_1</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>104</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>function_with_leak2</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2_1</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>112</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>function_with_leak3</string>
-// CHECK-NEXT: <key>issue_hash</key><string>3_1</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>121</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>function_with_leak4</string>
-// CHECK-NEXT: <key>issue_hash</key><string>5_1</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>132</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>function_with_leak5</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2_1</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>143</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>function_with_leak6</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2_1</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>154</integer>
// CHECK-NEXT: <key>type</key><string>Memory leak</string>
// CHECK-NEXT: <key>issue_context_kind</key><string>function</string>
// CHECK-NEXT: <key>issue_context</key><string>use_function_with_leak7</string>
-// CHECK-NEXT: <key>issue_hash</key><string>2_1</string>
+// CHECK-NEXT: <key>issue_hash</key><string>1</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>170</integer>