diff options
author | Anna Zaks <ganna@apple.com> | 2012-09-12 22:57:30 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-09-12 22:57:30 +0000 |
commit | 522fc21f3adc647817edc8017e6928a64c96899b (patch) | |
tree | 58cb3520520b25a193a6708523574a0b7913abc5 | |
parent | 1a7bcc41efb73d80fd45eb71494b073f388d333c (diff) |
[analyzer] Teach UndefOrNullArgVisitor to track parent regions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163748 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h | 3 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | 8 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/MemRegion.cpp | 20 | ||||
-rw-r--r-- | test/Analysis/diagnostics/undef-value-param.c | 1578 |
4 files changed, 1183 insertions, 426 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index df8fb43b00..e54b3f039d 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -140,6 +140,9 @@ public: const MemRegion *getBaseRegion() const; + /// Check if the region is a subregion of the given region. + bool isSubRegionOf(const MemRegion *PR) const; + const MemRegion *StripCasts(bool StripBaseCasts = true) const; bool hasGlobalsOrParametersStorage() const; diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 0d0006c5eb..be946842fc 100644 --- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -517,6 +517,8 @@ void bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, // However, if the rvalue is a symbolic region, we should track it as well. SVal RVal = state->getSVal(L->getRegion()); const MemRegion *RegionRVal = RVal.getAsRegion(); + report.addVisitor(new UndefOrNullArgVisitor(L->getRegion())); + if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) { report.markInteresting(RegionRVal); @@ -985,8 +987,8 @@ UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N, E = Call->param_end(); I != E; ++I, ++Idx) { const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion(); - // Are we tracking the argument? - if ( !ArgReg || ArgReg != R) + // Are we tracking the argument or its subregion? + if ( !ArgReg || (ArgReg != R && !R->isSubRegionOf(ArgReg->StripCasts()))) continue; // Check the function parameter type. @@ -1006,7 +1008,7 @@ UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N, // Mark the call site (LocationContext) as interesting if the value of the // argument is undefined or '0'/'NULL'. - SVal BoundVal = State->getSVal(ArgReg); + SVal BoundVal = State->getSVal(R); if (BoundVal.isUndef() || BoundVal.isZeroConstant()) { BR.markInteresting(CEnter->getCalleeContext()); return 0; diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp index b29327efcf..6d6bb20818 100644 --- a/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -990,6 +990,26 @@ const MemRegion *MemRegion::getBaseRegion() const { return R; } +bool MemRegion::isSubRegionOf(const MemRegion *PR) const { + const MemRegion *R = this; + while (true) { + switch (R->getKind()) { + case MemRegion::ElementRegionKind: + case MemRegion::FieldRegionKind: + case MemRegion::ObjCIvarRegionKind: + case MemRegion::CXXBaseObjectRegionKind: + R = cast<SubRegion>(R)->getSuperRegion(); + if (R == PR) + return true; + continue; + default: + break; + } + break; + } + return false; +} + //===----------------------------------------------------------------------===// // View handling. //===----------------------------------------------------------------------===// diff --git a/test/Analysis/diagnostics/undef-value-param.c b/test/Analysis/diagnostics/undef-value-param.c index 8eb61c94cf..88d87cfdce 100644 --- a/test/Analysis/diagnostics/undef-value-param.c +++ b/test/Analysis/diagnostics/undef-value-param.c @@ -26,426 +26,1158 @@ int use(int c) { //expected-note@-1{{The left operand of '+' is a garbage value}} } -//CHECK: <dict> -//CHECK: <key>files</key> -//CHECK: <array> -//CHECK: </array> -//CHECK: <key>diagnostics</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>path</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>kind</key><string>event</string> -//CHECK: <key>location</key> -//CHECK: <dict> -//CHECK: <key>line</key><integer>19</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <key>ranges</key> -//CHECK: <array> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>19</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>19</integer> -//CHECK: <key>col</key><integer>10</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </array> -//CHECK: <key>depth</key><integer>0</integer> -//CHECK: <key>extended_message</key> -//CHECK: <string>Variable 'xx' declared without an initial value</string> -//CHECK: <key>message</key> -//CHECK: <string>Variable 'xx' declared without an initial value</string> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>control</string> -//CHECK: <key>edges</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>start</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>19</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>19</integer> -//CHECK: <key>col</key><integer>7</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: <key>end</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>21</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>21</integer> -//CHECK: <key>col</key><integer>7</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>event</string> -//CHECK: <key>location</key> -//CHECK: <dict> -//CHECK: <key>line</key><integer>21</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <key>ranges</key> -//CHECK: <array> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>21</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>21</integer> -//CHECK: <key>col</key><integer>14</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </array> -//CHECK: <key>depth</key><integer>0</integer> -//CHECK: <key>extended_message</key> -//CHECK: <string>Calling 'foo'</string> -//CHECK: <key>message</key> -//CHECK: <string>Calling 'foo'</string> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>event</string> -//CHECK: <key>location</key> -//CHECK: <dict> -//CHECK: <key>line</key><integer>10</integer> -//CHECK: <key>col</key><integer>1</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <key>depth</key><integer>1</integer> -//CHECK: <key>extended_message</key> -//CHECK: <string>Entered call from 'use'</string> -//CHECK: <key>message</key> -//CHECK: <string>Entered call from 'use'</string> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>control</string> -//CHECK: <key>edges</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>start</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>10</integer> -//CHECK: <key>col</key><integer>1</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>10</integer> -//CHECK: <key>col</key><integer>4</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: <key>end</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>11</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>11</integer> -//CHECK: <key>col</key><integer>6</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>control</string> -//CHECK: <key>edges</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>start</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>11</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>11</integer> -//CHECK: <key>col</key><integer>6</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: <key>end</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>11</integer> -//CHECK: <key>col</key><integer>9</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>11</integer> -//CHECK: <key>col</key><integer>9</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>event</string> -//CHECK: <key>location</key> -//CHECK: <dict> -//CHECK: <key>line</key><integer>11</integer> -//CHECK: <key>col</key><integer>9</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <key>ranges</key> -//CHECK: <array> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>11</integer> -//CHECK: <key>col</key><integer>9</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>11</integer> -//CHECK: <key>col</key><integer>9</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </array> -//CHECK: <key>depth</key><integer>1</integer> -//CHECK: <key>extended_message</key> -//CHECK: <string>Assuming 'c' is not equal to 0</string> -//CHECK: <key>message</key> -//CHECK: <string>Assuming 'c' is not equal to 0</string> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>control</string> -//CHECK: <key>edges</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>start</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>11</integer> -//CHECK: <key>col</key><integer>9</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>11</integer> -//CHECK: <key>col</key><integer>9</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: <key>end</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>14</integer> -//CHECK: <key>col</key><integer>9</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>14</integer> -//CHECK: <key>col</key><integer>14</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>event</string> -//CHECK: <key>location</key> -//CHECK: <dict> -//CHECK: <key>line</key><integer>21</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <key>ranges</key> -//CHECK: <array> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>21</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>21</integer> -//CHECK: <key>col</key><integer>14</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </array> -//CHECK: <key>depth</key><integer>1</integer> -//CHECK: <key>extended_message</key> -//CHECK: <string>Returning from 'foo'</string> -//CHECK: <key>message</key> -//CHECK: <string>Returning from 'foo'</string> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>control</string> -//CHECK: <key>edges</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>start</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>21</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>21</integer> -//CHECK: <key>col</key><integer>7</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: <key>end</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>24</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>24</integer> -//CHECK: <key>col</key><integer>18</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>control</string> -//CHECK: <key>edges</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>start</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>24</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>24</integer> -//CHECK: <key>col</key><integer>18</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: <key>end</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>25</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>25</integer> -//CHECK: <key>col</key><integer>10</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>control</string> -//CHECK: <key>edges</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>start</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>25</integer> -//CHECK: <key>col</key><integer>5</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>25</integer> -//CHECK: <key>col</key><integer>10</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: <key>end</key> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>25</integer> -//CHECK: <key>col</key><integer>12</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>25</integer> -//CHECK: <key>col</key><integer>13</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>kind</key><string>event</string> -//CHECK: <key>location</key> -//CHECK: <dict> -//CHECK: <key>line</key><integer>25</integer> -//CHECK: <key>col</key><integer>12</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <key>ranges</key> -//CHECK: <array> -//CHECK: <array> -//CHECK: <dict> -//CHECK: <key>line</key><integer>25</integer> -//CHECK: <key>col</key><integer>12</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: <dict> -//CHECK: <key>line</key><integer>25</integer> -//CHECK: <key>col</key><integer>13</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </array> -//CHECK: <key>depth</key><integer>0</integer> -//CHECK: <key>extended_message</key> -//CHECK: <string>The left operand of '+' is a garbage value</string> -//CHECK: <key>message</key> -//CHECK: <string>The left operand of '+' is a garbage value</string> -//CHECK: </dict> -//CHECK: </array> -//CHECK: <key>description</key><string>The left operand of '+' is a garbage value</string> -//CHECK: <key>category</key><string>Logic error</string> -//CHECK: <key>type</key><string>Result of operation is garbage or undefined</string> -//CHECK: <key>issue_context_kind</key><string>function</string> -//CHECK: <key>issue_context</key><string>use</string> -//CHECK: <key>issue_hash</key><integer>7</integer> -//CHECK: <key>location</key> -//CHECK: <dict> -//CHECK: <key>line</key><integer>25</integer> -//CHECK: <key>col</key><integer>12</integer> -//CHECK: <key>file</key><integer>0</integer> -//CHECK: </dict> -//CHECK: </dict> -//CHECK: </array> -//CHECK: </dict> -//CHECK: </plist> +void initArray(int x, double XYZ[3]) { + if (x <= 0) //expected-note {{Taking true branch}} + //expected-note@-1 {{Assuming 'x' is <= 0}} + return; + XYZ[0] = 1; + XYZ[1] = 1; + XYZ[2] = 1; +} +int testPassingParentRegionArray(int x) { + double XYZ[3]; + initArray(x, XYZ); //expected-note {{Calling 'initArray'}} + //expected-note@-1 {{Returning from 'initArray'}} + return 1 * XYZ[1]; //expected-warning {{The right operand of '*' is a garbage value}} + //expected-note@-1 {{The right operand of '*' is a garbage value}} +} + +double *getValidPtr(); +struct WithFields { + double *f1; +}; +void initStruct(int x, struct WithFields *X) { + if (x <= 0) //expected-note {{Taking true branch}} + //expected-note@-1 {{Assuming 'x' is <= 0}} + + return; + X->f1 = getValidPtr(); +} +double testPassingParentRegionStruct(int x) { + struct WithFields st; + st.f1 = 0; + initStruct(x, &st); //expected-note {{Calling 'initStruct'}} + //expected-note@-1 {{Returning from 'initStruct'}} + return (*st.f1); //expected-warning {{Dereference of null pointer}} + //expected-note@-1{{Dereference of null pointer (loaded from field 'f1')}} +} + +// CHECK: <key>diagnostics</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>10</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Variable 'xx' declared without an initial value</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Variable 'xx' declared without an initial value</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>19</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>21</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>21</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>21</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>21</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>21</integer> +// CHECK-NEXT: <key>col</key><integer>14</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling 'foo'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling 'foo'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Entered call from 'use'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'use'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>10</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>5</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>11</integer> +// CHECK-NEXT: <key>col</key><integer>9</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Assuming 'c' is not equal to 0</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Assuming 'c' is not equal to 0</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> |