[cfe-commits] r164348 - in /cfe/trunk: lib/Analysis/BodyFarm.cpp test/Analysis/unix-fns.c

Ted Kremenek kremenek at apple.com
Fri Sep 21 10:58:00 PDT 2012


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 <geek4civic at gmail.com> 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 <kremenek at apple.com>:
>> 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>




More information about the cfe-commits mailing list