Thanks so much for the Valgrind output! I think I've fixed the issue in r164392, so I've re-enabled this setting in the analyzer. Let's see if that satisfies the build bots.
On Sep 21, 2012, at 5:08 AM, NAKAMURA Takumi <[email protected]> wrote: > Ted, I had to disable this in r164368, since r164364. > > In my investigation, valgrind blames this. > > $ valgrind --leak-check=full bin/clang -cc1 -analyzer-config > faux-bodies=true -triple x86_64-apple-darwin10 -analyze > -analyzer-checker=core -analyzer-store=region -fblocks -verify > clang/test/Analysis/blocks.m > > Valgrind log attached, HTH. > > ...Takumi > > > 2012/9/21 Ted Kremenek <[email protected]>: >> Author: kremenek >> Date: Thu Sep 20 19:52:24 2012 >> New Revision: 164348 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=164348&view=rev >> Log: >> Add faux-body support for dispatch_once(). >> >> Modified: >> cfe/trunk/lib/Analysis/BodyFarm.cpp >> cfe/trunk/test/Analysis/unix-fns.c >> >> Modified: cfe/trunk/lib/Analysis/BodyFarm.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BodyFarm.cpp?rev=164348&r1=164347&r2=164348&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Analysis/BodyFarm.cpp (original) >> +++ cfe/trunk/lib/Analysis/BodyFarm.cpp Thu Sep 20 19:52:24 2012 >> @@ -22,6 +22,113 @@ >> >> 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 @@ >> // 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 @@ >> // >> 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 @@ >> FunctionFarmer FF = >> llvm::StringSwitch<FunctionFarmer>(Name) >> .Case("dispatch_sync", create_dispatch_sync) >> + .Case("dispatch_once", create_dispatch_once) >> .Default(NULL); >> >> if (FF) { > <20120921.log> _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
