зеркало из https://github.com/microsoft/clang-1.git
Add faux-body support for dispatch_once().
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164348 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
4c919eb0c0
Коммит
cc85d217d3
|
@ -22,6 +22,113 @@ using namespace clang;
|
|||
|
||||
typedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D);
|
||||
|
||||
static bool isDispatchBlock(QualType Ty) {
|
||||
// Is it a block pointer?
|
||||
const BlockPointerType *BPT = Ty->getAs<BlockPointerType>();
|
||||
if (!BPT)
|
||||
return false;
|
||||
|
||||
// Check if the block pointer type takes no arguments and
|
||||
// returns void.
|
||||
const FunctionProtoType *FT =
|
||||
BPT->getPointeeType()->getAs<FunctionProtoType>();
|
||||
if (!FT || !FT->getResultType()->isVoidType() ||
|
||||
FT->getNumArgs() != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Create a fake body for dispatch_once.
|
||||
static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
|
||||
// Check if we have at least two parameters.
|
||||
if (D->param_size() != 2)
|
||||
return 0;
|
||||
|
||||
// Check if the first parameter is a pointer to integer type.
|
||||
const ParmVarDecl *Predicate = D->getParamDecl(0);
|
||||
QualType PredicateQPtrTy = Predicate->getType();
|
||||
const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>();
|
||||
if (!PredicatePtrTy)
|
||||
return 0;
|
||||
QualType PredicateTy = PredicatePtrTy->getPointeeType();
|
||||
if (!PredicateTy->isIntegerType())
|
||||
return 0;
|
||||
|
||||
// Check if the second parameter is the proper block type.
|
||||
const ParmVarDecl *Block = D->getParamDecl(1);
|
||||
QualType Ty = Block->getType();
|
||||
if (!isDispatchBlock(Ty))
|
||||
return 0;
|
||||
|
||||
// Everything checks out. Create a fakse body that checks the predicate,
|
||||
// sets it, and calls the block. Basically, an AST dump of:
|
||||
//
|
||||
// void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
|
||||
// if (!*predicate) {
|
||||
// *predicate = 1;
|
||||
// block();
|
||||
// }
|
||||
// }
|
||||
|
||||
// (1) Create the call.
|
||||
DeclRefExpr *DR = DeclRefExpr::CreateEmpty(C, false, false, false, false);
|
||||
DR->setDecl(const_cast<ParmVarDecl*>(Block));
|
||||
DR->setType(Ty);
|
||||
DR->setValueKind(VK_LValue);
|
||||
ImplicitCastExpr *ICE = ImplicitCastExpr::Create(C, Ty, CK_LValueToRValue,
|
||||
DR, 0, VK_RValue);
|
||||
CallExpr *CE = new (C) CallExpr(C, ICE, ArrayRef<Expr*>(), C.VoidTy,
|
||||
VK_RValue, SourceLocation());
|
||||
|
||||
// (2) Create the assignment to the predicate.
|
||||
IntegerLiteral *IL =
|
||||
IntegerLiteral::Create(C, llvm::APInt(C.getTypeSize(C.IntTy), (uint64_t) 1),
|
||||
C.IntTy, SourceLocation());
|
||||
ICE = ImplicitCastExpr::Create(C, PredicateTy, CK_IntegralCast, IL, 0,
|
||||
VK_RValue);
|
||||
DR = DeclRefExpr::CreateEmpty(C, false, false, false, false);
|
||||
DR->setDecl(const_cast<ParmVarDecl*>(Predicate));
|
||||
DR->setType(PredicateQPtrTy);
|
||||
DR->setValueKind(VK_LValue);
|
||||
ImplicitCastExpr *LValToRval =
|
||||
ImplicitCastExpr::Create(C, PredicateQPtrTy, CK_LValueToRValue, DR,
|
||||
0, VK_RValue);
|
||||
UnaryOperator *UO = new (C) UnaryOperator(LValToRval, UO_Deref, PredicateTy,
|
||||
VK_LValue, OK_Ordinary,
|
||||
SourceLocation());
|
||||
BinaryOperator *B = new (C) BinaryOperator(UO, ICE, BO_Assign,
|
||||
PredicateTy, VK_RValue,
|
||||
OK_Ordinary,
|
||||
SourceLocation());
|
||||
// (3) Create the compound statement.
|
||||
Stmt *Stmts[2];
|
||||
Stmts[0] = B;
|
||||
Stmts[1] = CE;
|
||||
CompoundStmt *CS = new (C) CompoundStmt(C, Stmts, 2, SourceLocation(),
|
||||
SourceLocation());
|
||||
|
||||
// (4) Create the 'if' condition.
|
||||
DR = DeclRefExpr::CreateEmpty(C, false, false, false, false);
|
||||
DR->setDecl(const_cast<ParmVarDecl*>(Predicate));
|
||||
DR->setType(PredicateQPtrTy);
|
||||
DR->setValueKind(VK_LValue);
|
||||
LValToRval = ImplicitCastExpr::Create(C, PredicateQPtrTy, CK_LValueToRValue,
|
||||
DR, 0, VK_RValue);
|
||||
UO = new (C) UnaryOperator(LValToRval, UO_Deref, PredicateTy,
|
||||
VK_LValue, OK_Ordinary,
|
||||
SourceLocation());
|
||||
LValToRval = ImplicitCastExpr::Create(C, PredicateTy, CK_LValueToRValue,
|
||||
UO, 0, VK_RValue);
|
||||
UO = new (C) UnaryOperator(LValToRval, UO_LNot, C.IntTy,
|
||||
VK_RValue, OK_Ordinary, SourceLocation());
|
||||
|
||||
// (5) Create the 'if' statement.
|
||||
IfStmt *If = new (C) IfStmt(C, SourceLocation(), 0, UO, CS);
|
||||
return If;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Create a fake body for dispatch_sync.
|
||||
static Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) {
|
||||
|
@ -32,16 +139,7 @@ static Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) {
|
|||
// Check if the second parameter is a block.
|
||||
const ParmVarDecl *PV = D->getParamDecl(1);
|
||||
QualType Ty = PV->getType();
|
||||
const BlockPointerType *BPT = Ty->getAs<BlockPointerType>();
|
||||
if (!BPT)
|
||||
return 0;
|
||||
|
||||
// Check if the block pointer type takes no arguments and
|
||||
// returns void.
|
||||
const FunctionProtoType *FT =
|
||||
BPT->getPointeeType()->getAs<FunctionProtoType>();
|
||||
if (!FT || !FT->getResultType()->isVoidType() ||
|
||||
FT->getNumArgs() != 0)
|
||||
if (!isDispatchBlock(Ty))
|
||||
return 0;
|
||||
|
||||
// Everything checks out. Create a fake body that just calls the block.
|
||||
|
@ -53,6 +151,7 @@ static Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) {
|
|||
//
|
||||
DeclRefExpr *DR = DeclRefExpr::CreateEmpty(C, false, false, false, false);
|
||||
DR->setDecl(const_cast<ParmVarDecl*>(PV));
|
||||
DR->setType(Ty);
|
||||
DR->setValueKind(VK_LValue);
|
||||
ImplicitCastExpr *ICE = ImplicitCastExpr::Create(C, Ty, CK_LValueToRValue,
|
||||
DR, 0, VK_RValue);
|
||||
|
@ -80,6 +179,7 @@ Stmt *BodyFarm::getBody(const FunctionDecl *D) {
|
|||
FunctionFarmer FF =
|
||||
llvm::StringSwitch<FunctionFarmer>(Name)
|
||||
.Case("dispatch_sync", create_dispatch_sync)
|
||||
.Case("dispatch_once", create_dispatch_once)
|
||||
.Default(NULL);
|
||||
|
||||
if (FF) {
|
||||
|
|
|
@ -181,6 +181,15 @@ void test_dispatch_sync(dispatch_queue_t queue, int *q) {
|
|||
});
|
||||
}
|
||||
|
||||
// Test inlining if dispatch_once.
|
||||
void test_inline_dispatch_once() {
|
||||
static dispatch_once_t pred;
|
||||
int *p = 0;
|
||||
dispatch_once(&pred, ^(void) {
|
||||
*p = 1; // expected-warning {{null}}
|
||||
});
|
||||
}
|
||||
|
||||
// CHECK: <key>diagnostics</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
|
@ -1585,4 +1594,307 @@ void test_dispatch_sync(dispatch_queue_t queue, int *q) {
|
|||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>path</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// 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>186</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>186</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>8</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>187</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>187</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: </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>187</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>3</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>187</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>187</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>8</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' initialized to a null pointer value</string>
|
||||
// CHECK-NEXT: <key>message</key>
|
||||
// CHECK-NEXT: <string>Variable 'p' initialized to 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>188</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>3</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>188</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>190</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: </array>
|
||||
// CHECK-NEXT: <key>depth</key><integer>0</integer>
|
||||
// CHECK-NEXT: <key>extended_message</key>
|
||||
// CHECK-NEXT: <string>Calling '_dispatch_once'</string>
|
||||
// CHECK-NEXT: <key>message</key>
|
||||
// CHECK-NEXT: <string>Calling '_dispatch_once'</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>162</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 'test_inline_dispatch_once'</string>
|
||||
// CHECK-NEXT: <key>message</key>
|
||||
// CHECK-NEXT: <string>Entered call from 'test_inline_dispatch_once'</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>162</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>162</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>164</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>164</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>15</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>164</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>3</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>164</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>164</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>33</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>Calling 'dispatch_once'</string>
|
||||
// CHECK-NEXT: <key>message</key>
|
||||
// CHECK-NEXT: <string>Calling 'dispatch_once'</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>38</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>2</integer>
|
||||
// CHECK-NEXT: <key>extended_message</key>
|
||||
// CHECK-NEXT: <string>Entered call from '_dispatch_once'</string>
|
||||
// CHECK-NEXT: <key>message</key>
|
||||
// CHECK-NEXT: <string>Entered call from '_dispatch_once'</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>164</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>3</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>164</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>164</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>33</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: <key>depth</key><integer>2</integer>
|
||||
// CHECK-NEXT: <key>extended_message</key>
|
||||
// CHECK-NEXT: <string>Calling anonymous block</string>
|
||||
// CHECK-NEXT: <key>message</key>
|
||||
// CHECK-NEXT: <string>Calling anonymous block</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>188</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>24</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <key>depth</key><integer>3</integer>
|
||||
// CHECK-NEXT: <key>extended_message</key>
|
||||
// CHECK-NEXT: <string>Entered call from 'dispatch_once'</string>
|
||||
// CHECK-NEXT: <key>message</key>
|
||||
// CHECK-NEXT: <string>Entered call from 'dispatch_once'</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>188</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>188</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>end</key>
|
||||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>189</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>4</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>189</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: </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>189</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>4</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>189</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>189</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: </array>
|
||||
// CHECK-NEXT: <key>depth</key><integer>3</integer>
|
||||
// CHECK-NEXT: <key>extended_message</key>
|
||||
// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'p')</string>
|
||||
// CHECK-NEXT: <key>message</key>
|
||||
// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'p')</string>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string>
|
||||
// CHECK-NEXT: <key>category</key><string>Logic error</string>
|
||||
// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string>
|
||||
// CHECK-NEXT: <key>location</key>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>189</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>4</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
|
|
Загрузка…
Ссылка в новой задаче