}
};
+class reverse_children {
+ llvm::SmallVector<Stmt *, 12> childrenBuf;
+ ArrayRef<Stmt*> children;
+public:
+ reverse_children(Stmt *S);
+
+ typedef ArrayRef<Stmt*>::reverse_iterator iterator;
+ iterator begin() const { return children.rbegin(); }
+ iterator end() const { return children.rend(); }
+};
+
+
+reverse_children::reverse_children(Stmt *S) {
+ if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
+ children = CE->getRawSubExprs();
+ return;
+ }
+ switch (S->getStmtClass()) {
+ case Stmt::InitListExprClass: {
+ InitListExpr *IE = cast<InitListExpr>(S);
+ children = llvm::makeArrayRef(reinterpret_cast<Stmt**>(IE->getInits()),
+ IE->getNumInits());
+ return;
+ }
+ default:
+ break;
+ }
+
+ // Default case for all other statements.
+ for (Stmt::child_range I = S->children(); I; ++I) {
+ childrenBuf.push_back(*I);
+ }
+
+ // This needs to be done *after* childrenBuf has been populated.
+ children = childrenBuf;
+}
+
/// CFGBuilder - This class implements CFG construction from an AST.
/// The builder is stateful: an instance of the builder should be used to only
/// construct a single CFG.
}
/// VisitChildren - Visit the children of a Stmt.
-CFGBlock *CFGBuilder::VisitChildren(Stmt *Terminator) {
- CFGBlock *lastBlock = Block;
- for (Stmt::child_range I = Terminator->children(); I; ++I)
- if (Stmt *child = *I)
- if (CFGBlock *b = Visit(child))
- lastBlock = b;
+CFGBlock *CFGBuilder::VisitChildren(Stmt *S) {
+ CFGBlock *B = Block;
- return lastBlock;
+ // Visit the children in their reverse order so that they appear in
+ // left-to-right (natural) order in the CFG.
+ reverse_children RChildren(S);
+ for (reverse_children::iterator I = RChildren.begin(), E = RChildren.end();
+ I != E; ++I) {
+ if (Stmt *Child = *I)
+ if (CFGBlock *R = Visit(Child))
+ B = R;
+ }
+ return B;
}
CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A,
CFGBlock *CFGBuilder::VisitChildrenForTemporaryDtors(Stmt *E) {
// When visiting children for destructors we want to visit them in reverse
- // order. Because there's no reverse iterator for children must to reverse
- // them in helper vector.
- typedef SmallVector<Stmt *, 4> ChildrenVect;
- ChildrenVect ChildrenRev;
- for (Stmt::child_range I = E->children(); I; ++I) {
- if (*I) ChildrenRev.push_back(*I);
- }
-
+ // order that they will appear in the CFG. Because the CFG is built
+ // bottom-up, this means we visit them in their natural order, which
+ // reverses them in the CFG.
CFGBlock *B = Block;
- for (ChildrenVect::reverse_iterator I = ChildrenRev.rbegin(),
- L = ChildrenRev.rend(); I != L; ++I) {
- if (CFGBlock *R = VisitForTemporaryDtors(*I))
- B = R;
+ for (Stmt::child_range I = E->children(); I; ++I) {
+ if (Stmt *Child = *I)
+ if (CFGBlock *R = VisitForTemporaryDtors(Child))
+ B = R;
}
return B;
}
llvm::raw_svector_ostream os(sbuf);
if (const PostStmt *PS = StoreSite->getLocationAs<PostStmt>()) {
- if (const DeclStmt *DS = PS->getStmtAs<DeclStmt>()) {
-
- if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
- os << "Variable '" << *VR->getDecl() << "' ";
+ const Stmt *S = PS->getStmt();
+ const char *action = 0;
+ const DeclStmt *DS = dyn_cast<DeclStmt>(S);
+ const VarRegion *VR = dyn_cast<VarRegion>(R);
+
+ if (DS) {
+ action = "initialized to ";
+ } else if (isa<BlockExpr>(S)) {
+ action = "captured by block as ";
+ if (VR) {
+ // See if we can get the BlockVarRegion.
+ ProgramStateRef State = StoreSite->getState();
+ SVal V = State->getSVal(S, PS->getLocationContext());
+ if (const BlockDataRegion *BDR =
+ dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
+ if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
+ V = State->getSVal(OriginalR);
+ BR.addVisitor(new FindLastStoreBRVisitor(V, OriginalR));
+ }
+ }
}
- else
- return NULL;
+ }
+
+ if (action) {
+ if (!R)
+ return 0;
+
+ os << "Variable '" << *VR->getDecl() << "' ";
if (isa<loc::ConcreteInt>(V)) {
bool b = false;
if (R->isBoundable()) {
if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
if (TR->getValueType()->isObjCObjectPointerType()) {
- os << "initialized to nil";
+ os << action << "nil";
b = true;
}
}
}
if (!b)
- os << "initialized to a null pointer value";
+ os << action << "a null pointer value";
}
else if (isa<nonloc::ConcreteInt>(V)) {
- os << "initialized to " << cast<nonloc::ConcreteInt>(V).getValue();
+ os << action << cast<nonloc::ConcreteInt>(V).getValue();
}
- else if (V.isUndef()) {
- if (isa<VarRegion>(R)) {
- const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
- if (VD->getInit())
- os << "initialized to a garbage value";
- else
- os << "declared without an initial value";
+ else if (DS) {
+ if (V.isUndef()) {
+ if (isa<VarRegion>(R)) {
+ const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
+ if (VD->getInit())
+ os << "initialized to a garbage value";
+ else
+ os << "declared without an initial value";
+ }
+ }
+ else {
+ os << "initialized here";
}
- }
- else {
- os << "initialized here";
}
}
} else if (isa<CallEnter>(StoreSite->getLocation())) {
// CHECK: 14: int a = int(A().operator int()) + int(B().operator int());
// CHECK: 15: ~B() (Temporary object destructor)
// CHECK: 16: ~A() (Temporary object destructor)
-// CHECK: 17: A() (CXXConstructExpr, class A)
-// CHECK: 18: [B1.17] (BindTemporary)
-// CHECK: 19: [B1.18].operator int
-// CHECK: 20: [B1.19]()
-// CHECK: 21: [B1.20] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK: 22: int([B1.21]) (CXXFunctionalCastExpr, NoOp, int)
-// CHECK: 23: B() (CXXConstructExpr, class B)
-// CHECK: 24: [B1.23] (BindTemporary)
-// CHECK: 25: [B1.24].operator int
-// CHECK: 26: [B1.25]()
-// CHECK: 27: [B1.26] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK: 28: int([B1.27]) (CXXFunctionalCastExpr, NoOp, int)
-// CHECK: 29: [B1.22] + [B1.28]
-// CHECK: 30: foo
-// CHECK: 31: [B1.30] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(int))
-// CHECK: 32: [B1.31]([B1.29])
+// CHECK: 17: foo
+// CHECK: 18: [B1.17] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(int))
+// CHECK: 19: A() (CXXConstructExpr, class A)
+// CHECK: 20: [B1.19] (BindTemporary)
+// CHECK: 21: [B1.20].operator int
+// CHECK: 22: [B1.21]()
+// CHECK: 23: [B1.22] (ImplicitCastExpr, UserDefinedConversion, int)
+// CHECK: 24: int([B1.23]) (CXXFunctionalCastExpr, NoOp, int)
+// CHECK: 25: B() (CXXConstructExpr, class B)
+// CHECK: 26: [B1.25] (BindTemporary)
+// CHECK: 27: [B1.26].operator int
+// CHECK: 28: [B1.27]()
+// CHECK: 29: [B1.28] (ImplicitCastExpr, UserDefinedConversion, int)
+// CHECK: 30: int([B1.29]) (CXXFunctionalCastExpr, NoOp, int)
+// CHECK: 31: [B1.24] + [B1.30]
+// CHECK: 32: [B1.18]([B1.31])
// CHECK: 33: ~B() (Temporary object destructor)
// CHECK: 34: ~A() (Temporary object destructor)
// CHECK: 35: int b;
// CHECK: Preds (1): B3
// CHECK: Succs (1): B1
// CHECK: [B3]
-// CHECK: 1: [B5.6] && [B4.5]
-// CHECK: 2: foo
-// CHECK: 3: [B3.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool))
-// CHECK: 4: [B3.3]([B3.1])
-// CHECK: T: [B5.6] && ...
+// CHECK: 1: [B5.8] && [B4.5]
+// CHECK: 2: [B5.3]([B3.1])
+// CHECK: T: [B5.8] && ...
// CHECK: Preds (2): B4 B5
// CHECK: Succs (2): B2 B1
// CHECK: [B4]
// CHECK: Succs (1): B3
// CHECK: [B5]
// CHECK: 1: ~A() (Temporary object destructor)
-// CHECK: 2: A() (CXXConstructExpr, class A)
-// CHECK: 3: [B5.2] (BindTemporary)
-// CHECK: 4: [B5.3].operator _Bool
-// CHECK: 5: [B5.4]()
-// CHECK: 6: [B5.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B5.6] && ...
+// CHECK: 2: foo
+// CHECK: 3: [B5.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool))
+// CHECK: 4: A() (CXXConstructExpr, class A)
+// CHECK: 5: [B5.4] (BindTemporary)
+// CHECK: 6: [B5.5].operator _Bool
+// CHECK: 7: [B5.6]()
+// CHECK: 8: [B5.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B5.8] && ...
// CHECK: Preds (2): B6 B7
// CHECK: Succs (2): B4 B3
// CHECK: [B6]
// CHECK: Preds (1): B3
// CHECK: Succs (1): B1
// CHECK: [B3]
-// CHECK: 1: [B5.6] || [B4.5]
-// CHECK: 2: foo
-// CHECK: 3: [B3.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool))
-// CHECK: 4: [B3.3]([B3.1])
-// CHECK: T: [B5.6] || ...
+// CHECK: 1: [B5.8] || [B4.5]
+// CHECK: 2: [B5.3]([B3.1])
+// CHECK: T: [B5.8] || ...
// CHECK: Preds (2): B4 B5
// CHECK: Succs (2): B1 B2
// CHECK: [B4]
// CHECK: Succs (1): B3
// CHECK: [B5]
// CHECK: 1: ~A() (Temporary object destructor)
-// CHECK: 2: A() (CXXConstructExpr, class A)
-// CHECK: 3: [B5.2] (BindTemporary)
-// CHECK: 4: [B5.3].operator _Bool
-// CHECK: 5: [B5.4]()
-// CHECK: 6: [B5.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B5.6] || ...
+// CHECK: 2: foo
+// CHECK: 3: [B5.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool))
+// CHECK: 4: A() (CXXConstructExpr, class A)
+// CHECK: 5: [B5.4] (BindTemporary)
+// CHECK: 6: [B5.5].operator _Bool
+// CHECK: 7: [B5.6]()
+// CHECK: 8: [B5.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B5.8] || ...
// CHECK: Preds (2): B6 B7
// CHECK: Succs (2): B3 B4
// CHECK: [B6]
// CHECK: Preds (2): B2 B3
// CHECK: Succs (1): B0
// CHECK: [B2]
-// CHECK: 1: 0
-// CHECK: 2: foo
-// CHECK: 3: [B2.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(int))
-// CHECK: 4: [B2.3]([B2.1])
+// CHECK: 1: foo
+// CHECK: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(int))
+// CHECK: 3: 0
+// CHECK: 4: [B2.2]([B2.3])
// CHECK: Preds (1): B4
// CHECK: Succs (1): B1
// CHECK: [B3]
-// CHECK: 1: 0
-// CHECK: 2: foo
-// CHECK: 3: [B3.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(int))
-// CHECK: 4: [B3.3]([B3.1])
+// CHECK: 1: foo
+// CHECK: 2: [B3.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(int))
+// CHECK: 3: 0
+// CHECK: 4: [B3.2]([B3.3])
// CHECK: Preds (1): B4
// CHECK: Succs (1): B1
// CHECK: [B4]
// CHECK: Preds (1): B4
// CHECK: Succs (1): B1
// CHECK: [B4]
-// CHECK: 1: [B7.6] ? [B5.6] : [B6.15]
+// CHECK: 1: [B7.8] ? [B5.6] : [B6.15]
// CHECK: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 3: [B4.2]
-// CHECK: 4: foo
-// CHECK: 5: [B4.4] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
-// CHECK: 6: [B4.5]([B4.3])
-// CHECK: T: [B7.6] ? ... : ...
+// CHECK: 4: [B7.3]([B4.3])
+// CHECK: T: [B7.8] ? ... : ...
// CHECK: Preds (2): B5 B6
// CHECK: Succs (2): B2 B3
// CHECK: [B5]
// CHECK: Succs (1): B4
// CHECK: [B7]
// CHECK: 1: ~B() (Temporary object destructor)
-// CHECK: 2: B() (CXXConstructExpr, class B)
-// CHECK: 3: [B7.2] (BindTemporary)
-// CHECK: 4: [B7.3].operator _Bool
-// CHECK: 5: [B7.4]()
-// CHECK: 6: [B7.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B7.6] ? ... : ...
+// CHECK: 2: foo
+// CHECK: 3: [B7.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
+// CHECK: 4: B() (CXXConstructExpr, class B)
+// CHECK: 5: [B7.4] (BindTemporary)
+// CHECK: 6: [B7.5].operator _Bool
+// CHECK: 7: [B7.6]()
+// CHECK: 8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B7.8] ? ... : ...
// CHECK: Preds (2): B8 B9
// CHECK: Succs (2): B5 B6
// CHECK: [B8]
// CHECK: Preds (1): B4
// CHECK: Succs (1): B1
// CHECK: [B4]
-// CHECK: 1: [B7.3] ?: [B6.6]
+// CHECK: 1: [B7.5] ?: [B6.6]
// CHECK: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 3: [B4.2]
-// CHECK: 4: foo
-// CHECK: 5: [B4.4] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
-// CHECK: 6: [B4.5]([B4.3])
-// CHECK: T: [B7.6] ? ... : ...
+// CHECK: 4: [B7.3]([B4.3])
+// CHECK: T: [B7.8] ? ... : ...
// CHECK: Preds (2): B5 B6
// CHECK: Succs (2): B2 B3
// CHECK: [B5]
-// CHECK: 1: [B7.3] (ImplicitCastExpr, NoOp, const class A)
+// CHECK: 1: [B7.5] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 2: [B5.1]
// CHECK: 3: [B5.2] (CXXConstructExpr, class A)
// CHECK: 4: [B5.3] (BindTemporary)
// CHECK: Succs (1): B4
// CHECK: [B7]
// CHECK: 1: ~A() (Temporary object destructor)
-// CHECK: 2: A() (CXXConstructExpr, class A)
-// CHECK: 3: [B7.2] (BindTemporary)
-// CHECK: 4: [B7.3].operator _Bool
-// CHECK: 5: [B7.4]()
-// CHECK: 6: [B7.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
-// CHECK: T: [B7.6] ? ... : ...
+// CHECK: 2: foo
+// CHECK: 3: [B7.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
+// CHECK: 4: A() (CXXConstructExpr, class A)
+// CHECK: 5: [B7.4] (BindTemporary)
+// CHECK: 6: [B7.5].operator _Bool
+// CHECK: 7: [B7.6]()
+// CHECK: 8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK: T: [B7.8] ? ... : ...
// CHECK: Preds (2): B9 B8
// CHECK: Succs (2): B5 B6
// CHECK: [B8]
// CHECK: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 4: [B1.3]
// CHECK: 5: const A &a = A();
-// CHECK: 6: A() (CXXConstructExpr, class A)
-// CHECK: 7: [B1.6] (BindTemporary)
-// CHECK: 8: [B1.7] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 9: [B1.8]
-// CHECK: 10: foo
-// CHECK: 11: [B1.10] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
-// CHECK: 12: [B1.11]([B1.9])
+// CHECK: 6: foo
+// CHECK: 7: [B1.6] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
+// CHECK: 8: A() (CXXConstructExpr, class A)
+// CHECK: 9: [B1.8] (BindTemporary)
+// CHECK: 10: [B1.9] (ImplicitCastExpr, NoOp, const class A)
+// CHECK: 11: [B1.10]
+// CHECK: 12: [B1.7]([B1.11])
// CHECK: 13: ~A() (Temporary object destructor)
// CHECK: 14: int b;
// CHECK: 15: [B1.5].~A() (Implicit destructor)
// CHECK: 5: [B1.4] (ImplicitCastExpr, NoOp, const class A)
// CHECK: 6: [B1.5]
// CHECK: 7: const A &a = A::make();
-// CHECK: 8: A::make
-// CHECK: 9: [B1.8] (ImplicitCastExpr, FunctionToPointerDecay, class A (*)(void))
-// CHECK: 10: [B1.9]()
-// CHECK: 11: [B1.10] (BindTemporary)
-// CHECK: 12: [B1.11] (ImplicitCastExpr, NoOp, const class A)
-// CHECK: 13: [B1.12]
-// CHECK: 14: foo
-// CHECK: 15: [B1.14] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
-// CHECK: 16: [B1.15]([B1.13])
+// CHECK: 8: foo
+// CHECK: 9: [B1.8] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
+// CHECK: 10: A::make
+// CHECK: 11: [B1.10] (ImplicitCastExpr, FunctionToPointerDecay, class A (*)(void))
+// CHECK: 12: [B1.11]()
+// CHECK: 13: [B1.12] (BindTemporary)
+// CHECK: 14: [B1.13] (ImplicitCastExpr, NoOp, const class A)
+// CHECK: 15: [B1.14]
+// CHECK: 16: [B1.9]([B1.15])
// CHECK: 17: ~A() (Temporary object destructor)
// CHECK: 18: int b;
// CHECK: 19: [B1.7].~A() (Implicit destructor)
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>190</integer>
-// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>190</integer>
-// CHECK-NEXT: <key>col</key><integer>15</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>190</integer>
+// CHECK-NEXT: <key>col</key><integer>24</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>190</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>194</integer>
+// CHECK-NEXT: <key>col</key><integer>3</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 'p' captured by block as a null pointer value</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Variable 'p' captured by block as a null pointer value</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>190</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <string>Variable 'p' initialized to a null pointer 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>200</integer>
+// CHECK-NEXT: <key>col</key><integer>3</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>200</integer>
+// CHECK-NEXT: <key>col</key><integer>5</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>201</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>201</integer>
+// CHECK-NEXT: <key>col</key><integer>24</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>201</integer>
+// CHECK-NEXT: <key>col</key><integer>24</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>201</integer>
+// CHECK-NEXT: <key>col</key><integer>24</integer>
+// CHECK-NEXT: <key>file</key><integer>0</integer>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
+// CHECK-NEXT: <key>line</key><integer>203</integer>
+// CHECK-NEXT: <key>col</key><integer>3</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 'p' captured by block as a null pointer value</string>
+// CHECK-NEXT: <key>message</key>
+// CHECK-NEXT: <string>Variable 'p' captured by block as a null pointer value</string>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>