r362026 - [analyzer] ConditionBRVisitor: MemberExpr support

Csaba Dabis via cfe-commits cfe-commits at lists.llvm.org
Wed May 29 13:29:02 PDT 2019


Author: charusso
Date: Wed May 29 13:29:02 2019
New Revision: 362026

URL: http://llvm.org/viewvc/llvm-project?rev=362026&view=rev
Log:
[analyzer] ConditionBRVisitor: MemberExpr support

Summary: -

Reviewers: NoQ, george.karpenkov

Reviewed By: NoQ

Subscribers: cfe-commits, xazax.hun, baloghadamsoftware, szepet, a.sidorin,
             mikhail.ramalho, Szelethus, donat.nagy, dkrupp

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58206

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
    cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
    cfe/trunk/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
    cfe/trunk/test/Analysis/diagnostics/Inputs/expected-plists/deref-track-symbolic-region.c.plist
    cfe/trunk/test/Analysis/diagnostics/deref-track-symbolic-region.c
    cfe/trunk/test/Analysis/diagnostics/dtors.cpp
    cfe/trunk/test/Analysis/inlining/Inputs/expected-plists/path-notes.cpp.plist
    cfe/trunk/test/Analysis/inlining/path-notes.cpp
    cfe/trunk/test/Analysis/null-deref-path-notes.cpp
    cfe/trunk/test/Analysis/osobject-retain-release.cpp
    cfe/trunk/test/Analysis/uninit-vals.m

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h?rev=362026&r1=362025&r2=362026&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h Wed May 29 13:29:02 2019
@@ -203,6 +203,11 @@ public:
                 bool TookTrue, bool IsAssuming);
 
   std::shared_ptr<PathDiagnosticPiece>
+  VisitTrueTest(const Expr *Cond, const MemberExpr *ME, BugReporterContext &BRC,
+                BugReport &R, const ExplodedNode *N, bool TookTrue,
+                bool IsAssuming);
+
+  std::shared_ptr<PathDiagnosticPiece>
   VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr,
                          BugReporterContext &BRC, BugReport &R,
                          const ExplodedNode *N, bool TookTrue);
@@ -225,7 +230,8 @@ public:
                     BugReporterContext &BRC,
                     BugReport &R,
                     const ExplodedNode *N,
-                    Optional<bool> &prunable);
+                    Optional<bool> &prunable,
+                    bool IsSameFieldName);
 
   static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece);
 };

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=362026&r1=362025&r2=362026&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Wed May 29 13:29:02 2019
@@ -1991,6 +1991,11 @@ ConditionBRVisitor::VisitTrueTest(const
                                    BRC, R, N, TookTrueTmp, IsAssuming))
           return P;
         break;
+      case Stmt::MemberExprClass:
+        if (auto P = VisitTrueTest(Cond, cast<MemberExpr>(CondTmp),
+                                   BRC, R, N, TookTrueTmp, IsAssuming))
+          return P;
+        break;
       case Stmt::UnaryOperatorClass: {
         const auto *UO = cast<UnaryOperator>(CondTmp);
         if (UO->getOpcode() == UO_LNot) {
@@ -2025,7 +2030,8 @@ bool ConditionBRVisitor::patternMatch(co
                                       BugReporterContext &BRC,
                                       BugReport &report,
                                       const ExplodedNode *N,
-                                      Optional<bool> &prunable) {
+                                      Optional<bool> &prunable,
+                                      bool IsSameFieldName) {
   const Expr *OriginalExpr = Ex;
   Ex = Ex->IgnoreParenCasts();
 
@@ -2091,6 +2097,17 @@ bool ConditionBRVisitor::patternMatch(co
     return false;
   }
 
+  if (const auto *ME = dyn_cast<MemberExpr>(Ex)) {
+    if (!IsSameFieldName)
+      Out << "field '" << ME->getMemberDecl()->getName() << '\'';
+    else
+      Out << '\''
+          << Lexer::getSourceText(
+                 CharSourceRange::getTokenRange(Ex->getSourceRange()),
+                 BRC.getSourceManager(), BRC.getASTContext().getLangOpts(), 0)
+          << '\'';
+  }
+
   return false;
 }
 
@@ -2100,13 +2117,23 @@ std::shared_ptr<PathDiagnosticPiece> Con
   bool shouldInvert = false;
   Optional<bool> shouldPrune;
 
+  // Check if the field name of the MemberExprs is ambiguous. Example:
+  // " 'a.d' is equal to 'h.d' " in 'test/Analysis/null-deref-path-notes.cpp'.
+  bool IsSameFieldName = false;
+  if (const auto *LhsME =
+          dyn_cast<MemberExpr>(BExpr->getLHS()->IgnoreParenCasts()))
+    if (const auto *RhsME =
+            dyn_cast<MemberExpr>(BExpr->getRHS()->IgnoreParenCasts()))
+      IsSameFieldName = LhsME->getMemberDecl()->getName() ==
+                        RhsME->getMemberDecl()->getName();
+
   SmallString<128> LhsString, RhsString;
   {
     llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
-    const bool isVarLHS = patternMatch(BExpr->getLHS(), BExpr, OutLHS,
-                                       BRC, R, N, shouldPrune);
-    const bool isVarRHS = patternMatch(BExpr->getRHS(), BExpr, OutRHS,
-                                       BRC, R, N, shouldPrune);
+    const bool isVarLHS = patternMatch(BExpr->getLHS(), BExpr, OutLHS, BRC, R,
+                                       N, shouldPrune, IsSameFieldName);
+    const bool isVarRHS = patternMatch(BExpr->getRHS(), BExpr, OutRHS, BRC, R,
+                                       N, shouldPrune, IsSameFieldName);
 
     shouldInvert = !isVarLHS && isVarRHS;
   }
@@ -2170,11 +2197,15 @@ std::shared_ptr<PathDiagnosticPiece> Con
   const LocationContext *LCtx = N->getLocationContext();
   PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
 
+  // Convert 'field ...' to 'Field ...' if it is a MemberExpr.
+  std::string Message = Out.str();
+  Message[0] = toupper(Message[0]);
+
   // If we know the value create a pop-up note.
   if (!IsAssuming)
-    return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Out.str());
+    return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Message);
 
-  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
+  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Message);
   if (shouldPrune.hasValue())
     event->setPrunable(shouldPrune.getValue());
   return event;
@@ -2246,6 +2277,30 @@ std::shared_ptr<PathDiagnosticPiece> Con
   return std::move(event);
 }
 
+std::shared_ptr<PathDiagnosticPiece> ConditionBRVisitor::VisitTrueTest(
+    const Expr *Cond, const MemberExpr *ME, BugReporterContext &BRC,
+    BugReport &report, const ExplodedNode *N, bool TookTrue, bool IsAssuming) {
+  SmallString<256> Buf;
+  llvm::raw_svector_ostream Out(Buf);
+
+  Out << (IsAssuming ? "Assuming field '" : "Field '")
+      << ME->getMemberDecl()->getName() << "' is ";
+
+  if (!printValue(ME, Out, N, TookTrue, IsAssuming))
+    return nullptr;
+
+  const LocationContext *LCtx = N->getLocationContext();
+  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
+  if (!Loc.isValid() || !Loc.asLocation().isValid())
+    return nullptr;
+
+  // If we know the value create a pop-up note.
+  if (!IsAssuming)
+    return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Out.str());
+
+  return std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
+}
+
 bool ConditionBRVisitor::printValue(const Expr *CondVarExpr, raw_ostream &Out,
                                     const ExplodedNode *N, bool TookTrue,
                                     bool IsAssuming) {

Modified: cfe/trunk/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/expected-plists/edges-new.mm.plist?rev=362026&r1=362025&r2=362026&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/Inputs/expected-plists/edges-new.mm.plist (original)
+++ cfe/trunk/test/Analysis/Inputs/expected-plists/edges-new.mm.plist Wed May 29 13:29:02 2019
@@ -22230,6 +22230,68 @@
         <key>end</key>
          <array>
           <dict>
+           <key>line</key><integer>587</integer>
+           <key>col</key><integer>11</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>587</integer>
+           <key>col</key><integer>11</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+       </dict>
+      </array>
+    </dict>
+    <dict>
+     <key>kind</key><string>pop-up</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>587</integer>
+      <key>col</key><integer>11</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>587</integer>
+         <key>col</key><integer>11</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>587</integer>
+         <key>col</key><integer>16</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>extended_message</key>
+     <string>Field 'b' is equal to 2</string>
+     <key>message</key>
+     <string>Field 'b' is equal to 2</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>control</string>
+     <key>edges</key>
+      <array>
+       <dict>
+        <key>start</key>
+         <array>
+          <dict>
+           <key>line</key><integer>587</integer>
+           <key>col</key><integer>11</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>587</integer>
+           <key>col</key><integer>11</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
            <key>line</key><integer>588</integer>
            <key>col</key><integer>9</integer>
            <key>file</key><integer>0</integer>

Modified: cfe/trunk/test/Analysis/diagnostics/Inputs/expected-plists/deref-track-symbolic-region.c.plist
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/Inputs/expected-plists/deref-track-symbolic-region.c.plist?rev=362026&r1=362025&r2=362026&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/diagnostics/Inputs/expected-plists/deref-track-symbolic-region.c.plist (original)
+++ cfe/trunk/test/Analysis/diagnostics/Inputs/expected-plists/deref-track-symbolic-region.c.plist Wed May 29 13:29:02 2019
@@ -165,9 +165,9 @@
      </array>
      <key>depth</key><integer>0</integer>
      <key>extended_message</key>
-     <string>Assuming pointer value is null</string>
+     <string>Assuming field 'x' is null</string>
      <key>message</key>
-     <string>Assuming pointer value is null</string>
+     <string>Assuming field 'x' is null</string>
     </dict>
     <dict>
      <key>kind</key><string>control</string>
@@ -454,9 +454,9 @@
      </array>
      <key>depth</key><integer>0</integer>
      <key>extended_message</key>
-     <string>Assuming pointer value is null</string>
+     <string>Assuming field 'x' is null</string>
      <key>message</key>
-     <string>Assuming pointer value is null</string>
+     <string>Assuming field 'x' is null</string>
     </dict>
     <dict>
      <key>kind</key><string>control</string>

Modified: cfe/trunk/test/Analysis/diagnostics/deref-track-symbolic-region.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/deref-track-symbolic-region.c?rev=362026&r1=362025&r2=362026&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/diagnostics/deref-track-symbolic-region.c (original)
+++ cfe/trunk/test/Analysis/diagnostics/deref-track-symbolic-region.c Wed May 29 13:29:02 2019
@@ -15,8 +15,8 @@ void test(struct S syz, int *pp) {
 
   struct S *ps = &syz;
   if (ps->x)
-    //expected-note at -1{{Taking false branch}}
-    //expected-note at -2{{Assuming pointer value is null}}
+    //expected-note at -1{{Assuming field 'x' is null}}
+    //expected-note at -2{{Taking false branch}}
 
     m++;
 
@@ -30,8 +30,8 @@ void testTrackConstraintBRVisitorIsTrack
 
   struct S *ps = &syz;
   if (ps->x)
-    //expected-note at -1{{Taking false branch}}
-    //expected-note at -2{{Assuming pointer value is null}}
+    //expected-note at -1{{Assuming field 'x' is null}}
+    //expected-note at -2{{Taking false branch}}
 
     m++;
   int *p = syz.x; //expected-note {{'p' initialized to a null pointer value}}

Modified: cfe/trunk/test/Analysis/diagnostics/dtors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/dtors.cpp?rev=362026&r1=362025&r2=362026&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/diagnostics/dtors.cpp (original)
+++ cfe/trunk/test/Analysis/diagnostics/dtors.cpp Wed May 29 13:29:02 2019
@@ -16,10 +16,11 @@ struct smart_ptr {
   S *s;
   smart_ptr(S *);
   S *get() {
-    return (x || 0) ? nullptr : s; // expected-note{{Left side of '||' is false}}
-                                   // expected-note at -1{{'?' condition is false}}
-                                   // expected-warning at -2{{Use of memory after it is freed}}
-                                   // expected-note at -3{{Use of memory after it is freed}}
+    return (x || 0) ? nullptr : s; // expected-note{{Field 'x' is 0}}
+                                   // expected-note at -1{{Left side of '||' is false}}
+                                   // expected-note at -2{{'?' condition is false}}
+                                   // expected-warning at -3{{Use of memory after it is freed}}
+                                   // expected-note at -4{{Use of memory after it is freed}}
   }
 };
 

Modified: cfe/trunk/test/Analysis/inlining/Inputs/expected-plists/path-notes.cpp.plist
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inlining/Inputs/expected-plists/path-notes.cpp.plist?rev=362026&r1=362025&r2=362026&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inlining/Inputs/expected-plists/path-notes.cpp.plist (original)
+++ cfe/trunk/test/Analysis/inlining/Inputs/expected-plists/path-notes.cpp.plist Wed May 29 13:29:02 2019
@@ -4271,9 +4271,9 @@
      </array>
      <key>depth</key><integer>0</integer>
      <key>extended_message</key>
-     <string>Assuming pointer value is null</string>
+     <string>Assuming field 'arr' is null</string>
      <key>message</key>
-     <string>Assuming pointer value is null</string>
+     <string>Assuming field 'arr' is null</string>
     </dict>
     <dict>
      <key>kind</key><string>control</string>

Modified: cfe/trunk/test/Analysis/inlining/path-notes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inlining/path-notes.cpp?rev=362026&r1=362025&r2=362026&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inlining/path-notes.cpp (original)
+++ cfe/trunk/test/Analysis/inlining/path-notes.cpp Wed May 29 13:29:02 2019
@@ -231,7 +231,7 @@ struct Owner {
 };
 
 void Owner::testGetDerefExprOnMemberExprWithADot() {
-	if (arr)  // expected-note {{Assuming pointer value is null}}
+	if (arr)  // expected-note {{Assuming field 'arr' is null}}
             // expected-note at -1 {{Taking false branch}}
 	  ;
 	arr[1].x = 1; //expected-warning {{Dereference of null pointer}}

Modified: cfe/trunk/test/Analysis/null-deref-path-notes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/null-deref-path-notes.cpp?rev=362026&r1=362025&r2=362026&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/null-deref-path-notes.cpp (original)
+++ cfe/trunk/test/Analysis/null-deref-path-notes.cpp Wed May 29 13:29:02 2019
@@ -19,7 +19,7 @@ void c::f(B &g, int &i) {
                 // expected-note at -1{{Array access (via field 'd') results in a null pointer dereference}}
   B h, a; // expected-note{{Value assigned to 'h.d'}}
   a.d == __null; // expected-note{{Assuming the condition is true}}
-  a.d != h.d; // expected-note{{Assuming pointer value is null}}
+  a.d != h.d; // expected-note{{Assuming 'a.d' is equal to 'h.d'}}
   f(h, b); // expected-note{{Calling 'c::f'}}
 }
 }

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=362026&r1=362025&r2=362026&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Wed May 29 13:29:02 2019
@@ -601,16 +601,18 @@ void test_smart_ptr_uaf() {
   {
     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 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'}}
     // expected-note at os_smart_ptr.h:71{{Reference count incremented. The object now has a +2 retain count}}
     // expected-note at os_smart_ptr.h:14{{Returning from 'smart_ptr::_retain'}}
   } // expected-note{{Calling '~smart_ptr'}}
+  // expected-note at os_smart_ptr.h:35{{Field 'pointer' is non-null}}
   // expected-note at os_smart_ptr.h:35{{Taking true branch}}
   // expected-note at os_smart_ptr.h:36{{Calling 'smart_ptr::_release'}}
   // expected-note at os_smart_ptr.h:76{{Reference count decremented. The object now has a +1 retain count}}
   // expected-note at os_smart_ptr.h:36{{Returning from 'smart_ptr::_release'}}
- // expected-note at -5{{Returning from '~smart_ptr'}}
+ // expected-note at -6{{Returning from '~smart_ptr'}}
   obj->release(); // expected-note{{Object released}}
   obj->release(); // expected-warning{{Reference-counted object is used after it is released}}
 // expected-note at -1{{Reference-counted object is used after it is released}}
@@ -621,16 +623,18 @@ 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 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'}}
     // expected-note at os_smart_ptr.h:71{{Reference count incremented. The object now has a +2 retain count}}
     // expected-note at os_smart_ptr.h:14{{Returning from 'smart_ptr::_retain'}}
   } // expected-note{{Calling '~smart_ptr'}}
+  // expected-note at os_smart_ptr.h:35{{Field 'pointer' is non-null}}
   // expected-note at os_smart_ptr.h:35{{Taking true branch}}
   // expected-note at os_smart_ptr.h:36{{Calling 'smart_ptr::_release'}}
   // expected-note at os_smart_ptr.h:76{{Reference count decremented. The object now has a +1 retain count}}
   // expected-note at os_smart_ptr.h:36{{Returning from 'smart_ptr::_release'}}
- // expected-note at -5{{Returning from '~smart_ptr'}}
+ // expected-note at -6{{Returning from '~smart_ptr'}}
 } // expected-warning{{Potential leak of an object stored into 'obj'}}
 // expected-note at -1{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}
 

Modified: cfe/trunk/test/Analysis/uninit-vals.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/uninit-vals.m?rev=362026&r1=362025&r2=362026&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/uninit-vals.m (original)
+++ cfe/trunk/test/Analysis/uninit-vals.m Wed May 29 13:29:02 2019
@@ -164,7 +164,7 @@ void PR14765_test() {
                                            // expected-note at -1{{TRUE}}
 
   testObj->origin = makePoint(0.0, 0.0);
-  if (testObj->size > 0) { ; } // expected-note{{Assuming the condition is false}}
+  if (testObj->size > 0) { ; } // expected-note{{Assuming field 'size' is <= 0}}
                                // expected-note at -1{{Taking false branch}}
 
   // FIXME: Assigning to 'testObj->origin' kills the default binding for the
@@ -219,13 +219,13 @@ void PR14765_test_int() {
                                                // expected-note at -1{{TRUE}}
 
   testObj->origin = makeIntPoint(1, 2);
-  if (testObj->size > 0) { ; } // expected-note{{Assuming the condition is false}}
+  if (testObj->size > 0) { ; } // expected-note{{Assuming field 'size' is <= 0}}
                                // expected-note at -1{{Taking false branch}}
-                               // expected-note at -2{{Assuming the condition is false}}
+                               // expected-note at -2{{Assuming field 'size' is <= 0}}
                                // expected-note at -3{{Taking false branch}}
-                               // expected-note at -4{{Assuming the condition is false}}
+                               // expected-note at -4{{Assuming field 'size' is <= 0}}
                                // expected-note at -5{{Taking false branch}}
-                               // expected-note at -6{{Assuming the condition is false}}
+                               // expected-note at -6{{Assuming field 'size' is <= 0}}
                                // expected-note at -7{{Taking false branch}}
 
   // FIXME: Assigning to 'testObj->origin' kills the default binding for the
@@ -321,9 +321,12 @@ void testSmallStructInLargerStruct() {
                                                // expected-note at -1{{TRUE}}
 
   testObj->origin = makeIntPoint2D(1, 2);
-  if (testObj->size > 0) { ; } // expected-note{{Taking false branch}}
+  if (testObj->size > 0) { ; } // expected-note{{Field 'size' is <= 0}}
                                // expected-note at -1{{Taking false branch}}
-                               // expected-note at -2{{Taking false branch}}
+                               // expected-note at -2{{Field 'size' is <= 0}}
+                               // expected-note at -3{{Taking false branch}}
+                               // expected-note at -4{{Field 'size' is <= 0}}
+                               // expected-note at -5{{Taking false branch}}
 
   clang_analyzer_eval(testObj->size == 0); // expected-warning{{TRUE}}
                                            // expected-note at -1{{TRUE}}




More information about the cfe-commits mailing list