[clang] e273918 - [analyzer] Track leaking object through stores

Valeriy Savchenko via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 28 08:38:17 PDT 2021


Author: Valeriy Savchenko
Date: 2021-04-28T18:37:38+03:00
New Revision: e273918038a7aa300cb8e6afebd9714bf647eed0

URL: https://github.com/llvm/llvm-project/commit/e273918038a7aa300cb8e6afebd9714bf647eed0
DIFF: https://github.com/llvm/llvm-project/commit/e273918038a7aa300cb8e6afebd9714bf647eed0.diff

LOG: [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

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
    clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
    clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
    clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
    clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
    clang/test/Analysis/osobject-retain-release.cpp
    clang/test/Analysis/retain-release-path-notes.m

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index 48b5f8d9ba7c9..eaa1e35f62bef 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -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 @@ class VarBindingsCollector : public StoreManager::BindingsHandler {
       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,

diff  --git a/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist b/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
index 0665e976efe9d..62cd52b7aa822 100644
--- a/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
+++ b/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
@@ -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>'garply' initialized here</string>
+     <key>message</key>
+     <string>'garply' initialized here</string>
+    </dict>
     <dict>
      <key>kind</key><string>control</string>
      <key>edges</key>

diff  --git a/clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist b/clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
index 185525c3a8473..3b0ce877b76e6 100644
--- a/clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
+++ b/clang/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
@@ -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 'self'</string>
+     <key>message</key>
+     <string>Value assigned to 'self'</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 'self')</string>
+     <key>message</key>
+     <string>Returning pointer (loaded from 'self')</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>'Original' initialized here</string>
+     <key>message</key>
+     <string>'Original' 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>'New' initialized here</string>
+     <key>message</key>
+     <string>'New' 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 'self'</string>
+     <key>message</key>
+     <string>Value assigned to 'self'</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 'self')</string>
+     <key>message</key>
+     <string>Returning pointer (loaded from 'self')</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,138 @@
         <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>350</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>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>'Original' initialized here</string>
+     <key>message</key>
+     <string>'Original' 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>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>4</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</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>
+       </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>'Intermediate' initialized here</string>
+     <key>message</key>
+     <string>'Intermediate' 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>347</integer>
+           <key>line</key><integer>356</integer>
            <key>col</key><integer>4</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -5590,6 +5924,35 @@
        </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>'New' initialized here</string>
+     <key>message</key>
+     <string>'New' initialized here</string>
+    </dict>
     <dict>
      <key>kind</key><string>control</string>
      <key>edges</key>
@@ -5598,12 +5961,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>347</integer>
+           <key>line</key><integer>356</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>356</integer>
            <key>col</key><integer>4</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -5611,12 +5974,12 @@
         <key>end</key>
          <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>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 'self'</string>
+     <key>message</key>
+     <string>Value assigned to 'self'</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 'self')</string>
+     <key>message</key>
+     <string>Returning pointer (loaded from 'self')</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>'Original' initialized here</string>
+     <key>message</key>
+     <string>'Original' 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>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 'New'</string>
+     <key>message</key>
+     <string>Value assigned to 'New'</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>376</integer>
+           <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>

diff  --git a/clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist b/clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
index 5ccca4cea9afe..61d96c6be0607 100644
--- a/clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
+++ b/clang/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
@@ -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>'second' initialized here</string>
+     <key>message</key>
+     <string>'second' 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>'alias' initialized here</string>
+     <key>message</key>
+     <string>'alias' initialized here</string>
+    </dict>
     <dict>
      <key>kind</key><string>control</string>
      <key>edges</key>

diff  --git a/clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist b/clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
index 56d93bd43f9a1..44da78abb1916 100644
--- a/clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
+++ b/clang/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
@@ -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>'second' initialized here</string>
+     <key>message</key>
+     <string>'second' 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>'alias' initialized here</string>
+     <key>message</key>
+     <string>'alias' initialized here</string>
+    </dict>
     <dict>
      <key>kind</key><string>control</string>
      <key>edges</key>

diff  --git a/clang/test/Analysis/osobject-retain-release.cpp b/clang/test/Analysis/osobject-retain-release.cpp
index 3b566976ae0f6..38d5968a0b28f 100644
--- a/clang/test/Analysis/osobject-retain-release.cpp
+++ b/clang/test/Analysis/osobject-retain-release.cpp
@@ -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 at -1{{Potential leak of an object}}
-    // expected-note at -2{{Object leaked}}
-    // expected-note at -3{{Assuming dynamic cast returns null due to type mismatch}}
+                                                                      // expected-warning at -1{{Potential leak of an object}}
+                                                                      // expected-note at -2{{Object leaked}}
+                                                                      // expected-note at -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 at -1 {{Taking true branch}}
+    originalPtr = OSObject::generateObject(42);
+    (void)newPtr;
+  }
+  originalPtr->release(); // expected-warning {{Potential leak of an object stored into 'newPtr'}}
+                          // expected-note at -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 at -1 {{'newPtr' is non-null}}
+                                                        // expected-note at -2 {{Taking true branch}}
+    originalPtr = OSObject::generateObject(42);
+    (void)newPtr;
+  }
+  originalPtr->release(); // expected-warning {{Potential leak of an object stored into 'newPtr'}}
+                          // expected-note at -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 at -1 {{'newPtr' is non-null}}
+                                                         // expected-note at -2 {{Taking true branch}}
+    intermediate = OSObject::generateObject(42);
+    (void)newPtr;
+  }
+  intermediate->release(); // expected-warning {{Potential leak of an object stored into 'newPtr'}}
+                           // expected-note at -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 at -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 at -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 at -1{{Returning from constructor for 'smart_ptr<OSObject>'}}
+                        // expected-note at -2 {{'p' initialized here}}
     // expected-note at os_smart_ptr.h:13{{Field 'pointer' is non-null}}
     // expected-note at os_smart_ptr.h:13{{Taking true branch}}
     // expected-note at os_smart_ptr.h:14{{Calling 'smart_ptr::_retain'}}

diff  --git a/clang/test/Analysis/retain-release-path-notes.m b/clang/test/Analysis/retain-release-path-notes.m
index e8ce8b474f41d..9bf3b74add218 100644
--- a/clang/test/Analysis/retain-release-path-notes.m
+++ b/clang/test/Analysis/retain-release-path-notes.m
@@ -335,8 +335,11 @@ @interface LeakReassignmentTests : MyObj
 @implementation LeakReassignmentTests
 +(void)testLeakAliasSimple {
   id Original = [[MyObj alloc] initY]; // expected-note {{Calling 'initY'}}
-                                       // expected-note at -1 {{Returning from 'initY'}}
-  id New = Original;
+                                       // expected-note at 215 {{Value assigned to 'self'}}
+                                       // expected-note at 216 {{Returning pointer (loaded from 'self')}}
+                                       // expected-note at -3 {{Returning from 'initY'}}
+                                       // expected-note at -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 @@ +(void)testLeakAliasSimple {
 
 +(void)testLeakAliasChain {
   id Original = [[MyObj alloc] initY]; // expected-note {{Calling 'initY'}}
-                                       // expected-note at -1 {{Returning from 'initY'}}
-  id Intermediate = Original;
-  id New = Intermediate;
+                                       // expected-note at 215 {{Value assigned to 'self'}}
+                                       // expected-note at 216 {{Returning pointer (loaded from 'self')}}
+                                       // expected-note at -3 {{Returning from 'initY'}}
+                                       // expected-note at -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)calculate {
 
 +(void)testLeakAliasDeathInExpr {
   id Original = [[MyObj alloc] initY]; // expected-note {{Calling 'initY'}}
-                                       // expected-note at -1 {{Returning from 'initY'}}
-  id New = Original;
+                                       // expected-note at 215 {{Value assigned to 'self'}}
+                                       // expected-note at 216 {{Returning pointer (loaded from 'self')}}
+                                       // expected-note at -3 {{Returning from 'initY'}}
+                                       // expected-note at -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'}}


        


More information about the cfe-commits mailing list