[analyzer] Track leaking object through stores

Since we can report memory leaks on one variable, while the originally
allocated object was stored into another one, we should explain
how did it get there.

rdar://76645710

Differential Revision: https://reviews.llvm.org/D100852
This commit is contained in:
Valeriy Savchenko 2021-04-20 17:08:55 +03:00
parent 61ae2db2d7
commit e273918038
7 changed files with 805 additions and 79 deletions

View File

@ -616,7 +616,7 @@ static Optional<std::string> describeRegion(const MemRegion *MR) {
return None;
}
using Bindings = llvm::SmallVector<const MemRegion *, 4>;
using Bindings = llvm::SmallVector<std::pair<const MemRegion *, SVal>, 4>;
class VarBindingsCollector : public StoreManager::BindingsHandler {
SymbolRef Sym;
@ -633,7 +633,7 @@ public:
return true;
if (isa<NonParamVarRegion>(R))
Result.push_back(R);
Result.emplace_back(R, Val);
return true;
}
@ -968,11 +968,28 @@ void RefLeakReport::findBindingToReport(CheckerContext &Ctx,
// `AllocFirstBinding` to be one of them. In situations like this,
// it would still be the easiest case to explain to our users.
if (!AllVarBindings.empty() &&
llvm::count(AllVarBindings, AllocFirstBinding) == 0)
llvm::count_if(AllVarBindings,
[this](const std::pair<const MemRegion *, SVal> Binding) {
return Binding.first == AllocFirstBinding;
}) == 0) {
// Let's pick one of them at random (if there is something to pick from).
AllocBindingToReport = AllVarBindings[0];
else
AllocBindingToReport = AllVarBindings[0].first;
// Because 'AllocBindingToReport' is not the the same as
// 'AllocFirstBinding', we need to explain how the leaking object
// got from one to another.
//
// NOTE: We use the actual SVal stored in AllocBindingToReport here because
// FindLastStoreBRVisitor compares SVal's and it can get trickier for
// something like derived regions if we want to construct SVal from
// Sym. Instead, we take the value that is definitely stored in that
// region, thus guaranteeing that FindLastStoreBRVisitor will work.
addVisitor(std::make_unique<FindLastStoreBRVisitor>(
AllVarBindings[0].second.castAs<KnownSVal>(), AllocBindingToReport,
false, bugreporter::TrackingKind::Thorough));
} else {
AllocBindingToReport = AllocFirstBinding;
}
}
RefLeakReport::RefLeakReport(const RefCountBug &D, const LangOptions &LOpts,

View File

@ -21827,6 +21827,35 @@
</dict>
</array>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>566</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>566</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>566</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>&apos;garply&apos; initialized here</string>
<key>message</key>
<string>&apos;garply&apos; initialized here</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>

View File

@ -5155,6 +5155,35 @@
<key>message</key>
<string>Method returns an instance of MyObj with a +1 retain count</string>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>215</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>215</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>215</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>1</integer>
<key>extended_message</key>
<string>Value assigned to &apos;self&apos;</string>
<key>message</key>
<string>Value assigned to &apos;self&apos;</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
@ -5189,6 +5218,35 @@
</dict>
</array>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>216</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>216</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>216</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>1</integer>
<key>extended_message</key>
<string>Returning pointer (loaded from &apos;self&apos;)</string>
<key>message</key>
<string>Returning pointer (loaded from &apos;self&apos;)</string>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
@ -5252,6 +5310,35 @@
</dict>
</array>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>337</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>337</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>337</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>&apos;Original&apos; initialized here</string>
<key>message</key>
<string>&apos;Original&apos; initialized here</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
@ -5279,7 +5366,7 @@
</dict>
<dict>
<key>line</key><integer>342</integer>
<key>col</key><integer>3</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
@ -5304,6 +5391,69 @@
</dict>
<dict>
<key>line</key><integer>342</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>&apos;New&apos; initialized here</string>
<key>message</key>
<string>&apos;New&apos; initialized here</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
<array>
<dict>
<key>start</key>
<array>
<dict>
<key>line</key><integer>342</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>342</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<key>end</key>
<array>
<dict>
<key>line</key><integer>345</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>345</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</dict>
</array>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>345</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>345</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>345</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5327,7 +5477,7 @@
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
<key>line</key><integer>342</integer>
<key>line</key><integer>345</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5343,10 +5493,10 @@
<integer>221</integer>
<integer>336</integer>
<integer>337</integer>
<integer>339</integer>
<integer>340</integer>
<integer>341</integer>
<integer>342</integer>
<integer>343</integer>
<integer>344</integer>
<integer>345</integer>
</array>
</dict>
</dict>
@ -5361,12 +5511,12 @@
<key>start</key>
<array>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5374,12 +5524,12 @@
<key>end</key>
<array>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5391,7 +5541,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5399,12 +5549,12 @@
<array>
<array>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5493,6 +5643,35 @@
<key>message</key>
<string>Method returns an instance of MyObj with a +1 retain count</string>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>215</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>215</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>215</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>1</integer>
<key>extended_message</key>
<string>Value assigned to &apos;self&apos;</string>
<key>message</key>
<string>Value assigned to &apos;self&apos;</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
@ -5531,7 +5710,36 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>216</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>216</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>216</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>1</integer>
<key>extended_message</key>
<string>Returning pointer (loaded from &apos;self&apos;)</string>
<key>message</key>
<string>Returning pointer (loaded from &apos;self&apos;)</string>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>350</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5539,12 +5747,12 @@
<array>
<array>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5564,12 +5772,12 @@
<key>start</key>
<array>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5577,12 +5785,12 @@
<key>end</key>
<array>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5590,6 +5798,35 @@
</dict>
</array>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>350</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>350</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>350</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>&apos;Original&apos; initialized here</string>
<key>message</key>
<string>&apos;Original&apos; initialized here</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
@ -5598,12 +5835,12 @@
<key>start</key>
<array>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>347</integer>
<key>line</key><integer>350</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5611,12 +5848,138 @@
<key>end</key>
<array>
<dict>
<key>line</key><integer>353</integer>
<key>line</key><integer>355</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>353</integer>
<key>line</key><integer>355</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</dict>
</array>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>355</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>355</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>355</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>&apos;Intermediate&apos; initialized here</string>
<key>message</key>
<string>&apos;Intermediate&apos; initialized here</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
<array>
<dict>
<key>start</key>
<array>
<dict>
<key>line</key><integer>355</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>355</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<key>end</key>
<array>
<dict>
<key>line</key><integer>356</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>356</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</dict>
</array>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>356</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>356</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>356</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>&apos;New&apos; initialized here</string>
<key>message</key>
<string>&apos;New&apos; initialized here</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
<array>
<dict>
<key>start</key>
<array>
<dict>
<key>line</key><integer>356</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>356</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<key>end</key>
<array>
<dict>
<key>line</key><integer>359</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>359</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5628,7 +5991,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>353</integer>
<key>line</key><integer>359</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5636,12 +5999,12 @@
<array>
<array>
<dict>
<key>line</key><integer>353</integer>
<key>line</key><integer>359</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>353</integer>
<key>line</key><integer>359</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5665,7 +6028,7 @@
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
<key>line</key><integer>353</integer>
<key>line</key><integer>359</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5679,13 +6042,13 @@
<integer>219</integer>
<integer>220</integer>
<integer>221</integer>
<integer>346</integer>
<integer>347</integer>
<integer>349</integer>
<integer>350</integer>
<integer>351</integer>
<integer>352</integer>
<integer>353</integer>
<integer>355</integer>
<integer>356</integer>
<integer>357</integer>
<integer>358</integer>
<integer>359</integer>
</array>
</dict>
</dict>
@ -5700,12 +6063,12 @@
<key>start</key>
<array>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5713,12 +6076,12 @@
<key>end</key>
<array>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5730,7 +6093,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5738,12 +6101,12 @@
<array>
<array>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5832,6 +6195,35 @@
<key>message</key>
<string>Method returns an instance of MyObj with a +1 retain count</string>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>215</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>215</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>215</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>1</integer>
<key>extended_message</key>
<string>Value assigned to &apos;self&apos;</string>
<key>message</key>
<string>Value assigned to &apos;self&apos;</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
@ -5870,7 +6262,36 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>216</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>216</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>216</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>1</integer>
<key>extended_message</key>
<string>Returning pointer (loaded from &apos;self&apos;)</string>
<key>message</key>
<string>Returning pointer (loaded from &apos;self&apos;)</string>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>377</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5878,12 +6299,12 @@
<array>
<array>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5903,12 +6324,12 @@
<key>start</key>
<array>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5916,12 +6337,12 @@
<key>end</key>
<array>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5929,6 +6350,35 @@
</dict>
</array>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>377</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>377</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>377</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>&apos;Original&apos; initialized here</string>
<key>message</key>
<string>&apos;Original&apos; initialized here</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
@ -5937,12 +6387,12 @@
<key>start</key>
<array>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>371</integer>
<key>line</key><integer>377</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5950,12 +6400,75 @@
<key>end</key>
<array>
<dict>
<key>line</key><integer>376</integer>
<key>line</key><integer>383</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>376</integer>
<key>line</key><integer>383</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</dict>
</array>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>383</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>383</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>383</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>Value assigned to &apos;New&apos;</string>
<key>message</key>
<string>Value assigned to &apos;New&apos;</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
<array>
<dict>
<key>start</key>
<array>
<dict>
<key>line</key><integer>383</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>383</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<key>end</key>
<array>
<dict>
<key>line</key><integer>386</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>386</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5967,7 +6480,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>376</integer>
<key>line</key><integer>386</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@ -5975,12 +6488,12 @@
<array>
<array>
<dict>
<key>line</key><integer>376</integer>
<key>line</key><integer>386</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>376</integer>
<key>line</key><integer>386</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@ -6004,7 +6517,7 @@
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
<key>line</key><integer>376</integer>
<key>line</key><integer>386</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@ -6018,21 +6531,22 @@
<integer>219</integer>
<integer>220</integer>
<integer>221</integer>
<integer>357</integer>
<integer>358</integer>
<integer>359</integer>
<integer>360</integer>
<integer>363</integer>
<integer>364</integer>
<integer>365</integer>
<integer>366</integer>
<integer>367</integer>
<integer>369</integer>
<integer>370</integer>
<integer>371</integer>
<integer>372</integer>
<integer>373</integer>
<integer>374</integer>
<integer>375</integer>
<integer>376</integer>
<integer>377</integer>
<integer>382</integer>
<integer>383</integer>
<integer>384</integer>
<integer>385</integer>
<integer>386</integer>
</array>
</dict>
</dict>

View File

@ -25288,6 +25288,35 @@
<key>message</key>
<string>Object autoreleased</string>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>2286</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>2286</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>2286</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>&apos;second&apos; initialized here</string>
<key>message</key>
<string>&apos;second&apos; initialized here</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
@ -25546,6 +25575,35 @@
<key>message</key>
<string>Object autoreleased</string>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>2306</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>2306</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>2306</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>&apos;alias&apos; initialized here</string>
<key>message</key>
<string>&apos;alias&apos; initialized here</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>

View File

@ -25357,6 +25357,35 @@
<key>message</key>
<string>Object autoreleased</string>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>2286</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>2286</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>2286</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>&apos;second&apos; initialized here</string>
<key>message</key>
<string>&apos;second&apos; initialized here</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
@ -25615,6 +25644,35 @@
<key>message</key>
<string>Object autoreleased</string>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>2306</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>2306</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>2306</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>&apos;alias&apos; initialized here</string>
<key>message</key>
<string>&apos;alias&apos; initialized here</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>

View File

@ -526,19 +526,58 @@ void check_dynamic_cast_null_branch(OSObject *obj) {
void check_dynamic_cast_null_check() {
OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1)); // expected-note{{Call to method 'OSObject::generateObject' returns an OSObject}}
// expected-warning@-1{{Potential leak of an object}}
// expected-note@-2{{Object leaked}}
// expected-note@-3{{Assuming dynamic cast returns null due to type mismatch}}
// expected-warning@-1{{Potential leak of an object}}
// expected-note@-2{{Object leaked}}
// expected-note@-3{{Assuming dynamic cast returns null due to type mismatch}}
if (!arr)
return;
arr->release();
}
void check_dynamic_cast_alias() {
OSObject *originalPtr = OSObject::generateObject(1); // expected-note {{Call to method 'OSObject::generateObject' returns an OSObject}}
OSArray *newPtr = OSDynamicCast(OSArray, originalPtr); // expected-note {{'newPtr' initialized here}}
if (newPtr) { // expected-note {{'newPtr' is non-null}}
// expected-note@-1 {{Taking true branch}}
originalPtr = OSObject::generateObject(42);
(void)newPtr;
}
originalPtr->release(); // expected-warning {{Potential leak of an object stored into 'newPtr'}}
// expected-note@-1 {{Object leaked: object allocated and stored into 'newPtr' is not referenced later in this execution path and has a retain count of +1}}
}
void check_dynamic_cast_alias_cond() {
OSObject *originalPtr = OSObject::generateObject(1); // expected-note {{Call to method 'OSObject::generateObject' returns an OSObject}}
OSArray *newPtr = 0;
if ((newPtr = OSDynamicCast(OSArray, originalPtr))) { // expected-note {{Value assigned to 'newPtr'}}
// expected-note@-1 {{'newPtr' is non-null}}
// expected-note@-2 {{Taking true branch}}
originalPtr = OSObject::generateObject(42);
(void)newPtr;
}
originalPtr->release(); // expected-warning {{Potential leak of an object stored into 'newPtr'}}
// expected-note@-1 {{Object leaked: object allocated and stored into 'newPtr' is not referenced later in this execution path and has a retain count of +1}}
}
void check_dynamic_cast_alias_intermediate() {
OSObject *originalPtr = OSObject::generateObject(1); // expected-note {{Call to method 'OSObject::generateObject' returns an OSObject of type 'OSObject' with a +1 retain count}}
OSObject *intermediate = originalPtr; // TODO: add note here as well
OSArray *newPtr = 0;
if ((newPtr = OSDynamicCast(OSArray, intermediate))) { // expected-note {{Value assigned to 'newPtr'}}
// expected-note@-1 {{'newPtr' is non-null}}
// expected-note@-2 {{Taking true branch}}
intermediate = OSObject::generateObject(42);
(void)newPtr;
}
intermediate->release(); // expected-warning {{Potential leak of an object stored into 'newPtr'}}
// expected-note@-1 {{Object leaked: object allocated and stored into 'newPtr' is not referenced later in this execution path and has a retain count of +1}}
}
void use_after_release() {
OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type 'OSArray' with a +1 retain count}}
arr->release(); // expected-note{{Object released}}
arr->getCount(); // expected-warning{{Reference-counted object is used after it is released}}
// expected-note@-1{{Reference-counted object is used after it is released}}
arr->release(); // expected-note{{Object released}}
arr->getCount(); // expected-warning{{Reference-counted object is used after it is released}}
// expected-note@-1{{Reference-counted object is used after it is released}}
}
void potential_leak() {
@ -642,6 +681,7 @@ void test_smart_ptr_leak() {
{
OSObjectPtr p(obj); // expected-note{{Calling constructor for 'smart_ptr<OSObject>'}}
// expected-note@-1{{Returning from constructor for 'smart_ptr<OSObject>'}}
// expected-note@-2 {{'p' initialized here}}
// expected-note@os_smart_ptr.h:13{{Field 'pointer' is non-null}}
// expected-note@os_smart_ptr.h:13{{Taking true branch}}
// expected-note@os_smart_ptr.h:14{{Calling 'smart_ptr::_retain'}}

View File

@ -335,8 +335,11 @@ int seed();
@implementation LeakReassignmentTests
+(void)testLeakAliasSimple {
id Original = [[MyObj alloc] initY]; // expected-note {{Calling 'initY'}}
// expected-note@-1 {{Returning from 'initY'}}
id New = Original;
// expected-note@215 {{Value assigned to 'self'}}
// expected-note@216 {{Returning pointer (loaded from 'self')}}
// expected-note@-3 {{Returning from 'initY'}}
// expected-note@-4 {{'Original' initialized here}}
id New = Original; // expected-note {{'New' initialized here}}
Original = [[MyObj alloc] initZ];
(void)New;
[Original release]; // expected-warning {{Potential leak of an object stored into 'New'}}
@ -345,9 +348,12 @@ int seed();
+(void)testLeakAliasChain {
id Original = [[MyObj alloc] initY]; // expected-note {{Calling 'initY'}}
// expected-note@-1 {{Returning from 'initY'}}
id Intermediate = Original;
id New = Intermediate;
// expected-note@215 {{Value assigned to 'self'}}
// expected-note@216 {{Returning pointer (loaded from 'self')}}
// expected-note@-3 {{Returning from 'initY'}}
// expected-note@-4 {{'Original' initialized here}}
id Intermediate = Original; // expected-note {{'Intermediate' initialized here}}
id New = Intermediate; // expected-note {{'New' initialized here}}
Original = [[MyObj alloc] initZ];
(void)New;
[Original release]; // expected-warning {{Potential leak of an object stored into 'New'}}
@ -369,8 +375,12 @@ int seed();
+(void)testLeakAliasDeathInExpr {
id Original = [[MyObj alloc] initY]; // expected-note {{Calling 'initY'}}
// expected-note@-1 {{Returning from 'initY'}}
id New = Original;
// expected-note@215 {{Value assigned to 'self'}}
// expected-note@216 {{Returning pointer (loaded from 'self')}}
// expected-note@-3 {{Returning from 'initY'}}
// expected-note@-4 {{'Original' initialized here}}
id New = 0;
New = Original; // expected-note {{Value assigned to 'New'}}
Original = [[MyObj alloc] initZ];
[self log:New with:[self calculate]];
[Original release]; // expected-warning {{Potential leak of an object stored into 'New'}}