Home | History | Annotate | Line # | Download | only in Analysis
      1 //== BodyFarm.cpp  - Factory for conjuring up fake bodies ----------*- C++ -*-//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // BodyFarm is a factory for creating faux implementations for functions/methods
     10 // for analysis purposes.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "clang/Analysis/BodyFarm.h"
     15 #include "clang/AST/ASTContext.h"
     16 #include "clang/AST/CXXInheritance.h"
     17 #include "clang/AST/Decl.h"
     18 #include "clang/AST/Expr.h"
     19 #include "clang/AST/ExprCXX.h"
     20 #include "clang/AST/ExprObjC.h"
     21 #include "clang/AST/NestedNameSpecifier.h"
     22 #include "clang/Analysis/CodeInjector.h"
     23 #include "clang/Basic/OperatorKinds.h"
     24 #include "llvm/ADT/StringSwitch.h"
     25 #include "llvm/Support/Debug.h"
     26 
     27 #define DEBUG_TYPE "body-farm"
     28 
     29 using namespace clang;
     30 
     31 //===----------------------------------------------------------------------===//
     32 // Helper creation functions for constructing faux ASTs.
     33 //===----------------------------------------------------------------------===//
     34 
     35 static bool isDispatchBlock(QualType Ty) {
     36   // Is it a block pointer?
     37   const BlockPointerType *BPT = Ty->getAs<BlockPointerType>();
     38   if (!BPT)
     39     return false;
     40 
     41   // Check if the block pointer type takes no arguments and
     42   // returns void.
     43   const FunctionProtoType *FT =
     44   BPT->getPointeeType()->getAs<FunctionProtoType>();
     45   return FT && FT->getReturnType()->isVoidType() && FT->getNumParams() == 0;
     46 }
     47 
     48 namespace {
     49 class ASTMaker {
     50 public:
     51   ASTMaker(ASTContext &C) : C(C) {}
     52 
     53   /// Create a new BinaryOperator representing a simple assignment.
     54   BinaryOperator *makeAssignment(const Expr *LHS, const Expr *RHS, QualType Ty);
     55 
     56   /// Create a new BinaryOperator representing a comparison.
     57   BinaryOperator *makeComparison(const Expr *LHS, const Expr *RHS,
     58                                  BinaryOperator::Opcode Op);
     59 
     60   /// Create a new compound stmt using the provided statements.
     61   CompoundStmt *makeCompound(ArrayRef<Stmt*>);
     62 
     63   /// Create a new DeclRefExpr for the referenced variable.
     64   DeclRefExpr *makeDeclRefExpr(const VarDecl *D,
     65                                bool RefersToEnclosingVariableOrCapture = false);
     66 
     67   /// Create a new UnaryOperator representing a dereference.
     68   UnaryOperator *makeDereference(const Expr *Arg, QualType Ty);
     69 
     70   /// Create an implicit cast for an integer conversion.
     71   Expr *makeIntegralCast(const Expr *Arg, QualType Ty);
     72 
     73   /// Create an implicit cast to a builtin boolean type.
     74   ImplicitCastExpr *makeIntegralCastToBoolean(const Expr *Arg);
     75 
     76   /// Create an implicit cast for lvalue-to-rvaluate conversions.
     77   ImplicitCastExpr *makeLvalueToRvalue(const Expr *Arg, QualType Ty);
     78 
     79   /// Make RValue out of variable declaration, creating a temporary
     80   /// DeclRefExpr in the process.
     81   ImplicitCastExpr *
     82   makeLvalueToRvalue(const VarDecl *Decl,
     83                      bool RefersToEnclosingVariableOrCapture = false);
     84 
     85   /// Create an implicit cast of the given type.
     86   ImplicitCastExpr *makeImplicitCast(const Expr *Arg, QualType Ty,
     87                                      CastKind CK = CK_LValueToRValue);
     88 
     89   /// Create an Objective-C bool literal.
     90   ObjCBoolLiteralExpr *makeObjCBool(bool Val);
     91 
     92   /// Create an Objective-C ivar reference.
     93   ObjCIvarRefExpr *makeObjCIvarRef(const Expr *Base, const ObjCIvarDecl *IVar);
     94 
     95   /// Create a Return statement.
     96   ReturnStmt *makeReturn(const Expr *RetVal);
     97 
     98   /// Create an integer literal expression of the given type.
     99   IntegerLiteral *makeIntegerLiteral(uint64_t Value, QualType Ty);
    100 
    101   /// Create a member expression.
    102   MemberExpr *makeMemberExpression(Expr *base, ValueDecl *MemberDecl,
    103                                    bool IsArrow = false,
    104                                    ExprValueKind ValueKind = VK_LValue);
    105 
    106   /// Returns a *first* member field of a record declaration with a given name.
    107   /// \return an nullptr if no member with such a name exists.
    108   ValueDecl *findMemberField(const RecordDecl *RD, StringRef Name);
    109 
    110 private:
    111   ASTContext &C;
    112 };
    113 }
    114 
    115 BinaryOperator *ASTMaker::makeAssignment(const Expr *LHS, const Expr *RHS,
    116                                          QualType Ty) {
    117   return BinaryOperator::Create(
    118       C, const_cast<Expr *>(LHS), const_cast<Expr *>(RHS), BO_Assign, Ty,
    119       VK_RValue, OK_Ordinary, SourceLocation(), FPOptionsOverride());
    120 }
    121 
    122 BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS,
    123                                          BinaryOperator::Opcode Op) {
    124   assert(BinaryOperator::isLogicalOp(Op) ||
    125          BinaryOperator::isComparisonOp(Op));
    126   return BinaryOperator::Create(
    127       C, const_cast<Expr *>(LHS), const_cast<Expr *>(RHS), Op,
    128       C.getLogicalOperationType(), VK_RValue, OK_Ordinary, SourceLocation(),
    129       FPOptionsOverride());
    130 }
    131 
    132 CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
    133   return CompoundStmt::Create(C, Stmts, SourceLocation(), SourceLocation());
    134 }
    135 
    136 DeclRefExpr *ASTMaker::makeDeclRefExpr(
    137     const VarDecl *D,
    138     bool RefersToEnclosingVariableOrCapture) {
    139   QualType Type = D->getType().getNonReferenceType();
    140 
    141   DeclRefExpr *DR = DeclRefExpr::Create(
    142       C, NestedNameSpecifierLoc(), SourceLocation(), const_cast<VarDecl *>(D),
    143       RefersToEnclosingVariableOrCapture, SourceLocation(), Type, VK_LValue);
    144   return DR;
    145 }
    146 
    147 UnaryOperator *ASTMaker::makeDereference(const Expr *Arg, QualType Ty) {
    148   return UnaryOperator::Create(C, const_cast<Expr *>(Arg), UO_Deref, Ty,
    149                                VK_LValue, OK_Ordinary, SourceLocation(),
    150                                /*CanOverflow*/ false, FPOptionsOverride());
    151 }
    152 
    153 ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) {
    154   return makeImplicitCast(Arg, Ty, CK_LValueToRValue);
    155 }
    156 
    157 ImplicitCastExpr *
    158 ASTMaker::makeLvalueToRvalue(const VarDecl *Arg,
    159                              bool RefersToEnclosingVariableOrCapture) {
    160   QualType Type = Arg->getType().getNonReferenceType();
    161   return makeLvalueToRvalue(makeDeclRefExpr(Arg,
    162                                             RefersToEnclosingVariableOrCapture),
    163                             Type);
    164 }
    165 
    166 ImplicitCastExpr *ASTMaker::makeImplicitCast(const Expr *Arg, QualType Ty,
    167                                              CastKind CK) {
    168   return ImplicitCastExpr::Create(C, Ty,
    169                                   /* CastKind=*/CK,
    170                                   /* Expr=*/const_cast<Expr *>(Arg),
    171                                   /* CXXCastPath=*/nullptr,
    172                                   /* ExprValueKind=*/VK_RValue,
    173                                   /* FPFeatures */ FPOptionsOverride());
    174 }
    175 
    176 Expr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
    177   if (Arg->getType() == Ty)
    178     return const_cast<Expr*>(Arg);
    179   return makeImplicitCast(Arg, Ty, CK_IntegralCast);
    180 }
    181 
    182 ImplicitCastExpr *ASTMaker::makeIntegralCastToBoolean(const Expr *Arg) {
    183   return makeImplicitCast(Arg, C.BoolTy, CK_IntegralToBoolean);
    184 }
    185 
    186 ObjCBoolLiteralExpr *ASTMaker::makeObjCBool(bool Val) {
    187   QualType Ty = C.getBOOLDecl() ? C.getBOOLType() : C.ObjCBuiltinBoolTy;
    188   return new (C) ObjCBoolLiteralExpr(Val, Ty, SourceLocation());
    189 }
    190 
    191 ObjCIvarRefExpr *ASTMaker::makeObjCIvarRef(const Expr *Base,
    192                                            const ObjCIvarDecl *IVar) {
    193   return new (C) ObjCIvarRefExpr(const_cast<ObjCIvarDecl*>(IVar),
    194                                  IVar->getType(), SourceLocation(),
    195                                  SourceLocation(), const_cast<Expr*>(Base),
    196                                  /*arrow=*/true, /*free=*/false);
    197 }
    198 
    199 ReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) {
    200   return ReturnStmt::Create(C, SourceLocation(), const_cast<Expr *>(RetVal),
    201                             /* NRVOCandidate=*/nullptr);
    202 }
    203 
    204 IntegerLiteral *ASTMaker::makeIntegerLiteral(uint64_t Value, QualType Ty) {
    205   llvm::APInt APValue = llvm::APInt(C.getTypeSize(Ty), Value);
    206   return IntegerLiteral::Create(C, APValue, Ty, SourceLocation());
    207 }
    208 
    209 MemberExpr *ASTMaker::makeMemberExpression(Expr *base, ValueDecl *MemberDecl,
    210                                            bool IsArrow,
    211                                            ExprValueKind ValueKind) {
    212 
    213   DeclAccessPair FoundDecl = DeclAccessPair::make(MemberDecl, AS_public);
    214   return MemberExpr::Create(
    215       C, base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(),
    216       SourceLocation(), MemberDecl, FoundDecl,
    217       DeclarationNameInfo(MemberDecl->getDeclName(), SourceLocation()),
    218       /* TemplateArgumentListInfo=*/ nullptr, MemberDecl->getType(), ValueKind,
    219       OK_Ordinary, NOUR_None);
    220 }
    221 
    222 ValueDecl *ASTMaker::findMemberField(const RecordDecl *RD, StringRef Name) {
    223 
    224   CXXBasePaths Paths(
    225       /* FindAmbiguities=*/false,
    226       /* RecordPaths=*/false,
    227       /* DetectVirtual=*/ false);
    228   const IdentifierInfo &II = C.Idents.get(Name);
    229   DeclarationName DeclName = C.DeclarationNames.getIdentifier(&II);
    230 
    231   DeclContextLookupResult Decls = RD->lookup(DeclName);
    232   for (NamedDecl *FoundDecl : Decls)
    233     if (!FoundDecl->getDeclContext()->isFunctionOrMethod())
    234       return cast<ValueDecl>(FoundDecl);
    235 
    236   return nullptr;
    237 }
    238 
    239 //===----------------------------------------------------------------------===//
    240 // Creation functions for faux ASTs.
    241 //===----------------------------------------------------------------------===//
    242 
    243 typedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D);
    244 
    245 static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M,
    246                                                const ParmVarDecl *Callback,
    247                                                ArrayRef<Expr *> CallArgs) {
    248 
    249   QualType Ty = Callback->getType();
    250   DeclRefExpr *Call = M.makeDeclRefExpr(Callback);
    251   Expr *SubExpr;
    252   if (Ty->isRValueReferenceType()) {
    253     SubExpr = M.makeImplicitCast(
    254         Call, Ty.getNonReferenceType(), CK_LValueToRValue);
    255   } else if (Ty->isLValueReferenceType() &&
    256              Call->getType()->isFunctionType()) {
    257     Ty = C.getPointerType(Ty.getNonReferenceType());
    258     SubExpr = M.makeImplicitCast(Call, Ty, CK_FunctionToPointerDecay);
    259   } else if (Ty->isLValueReferenceType()
    260              && Call->getType()->isPointerType()
    261              && Call->getType()->getPointeeType()->isFunctionType()){
    262     SubExpr = Call;
    263   } else {
    264     llvm_unreachable("Unexpected state");
    265   }
    266 
    267   return CallExpr::Create(C, SubExpr, CallArgs, C.VoidTy, VK_RValue,
    268                           SourceLocation(), FPOptionsOverride());
    269 }
    270 
    271 static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
    272                                               const ParmVarDecl *Callback,
    273                                               CXXRecordDecl *CallbackDecl,
    274                                               ArrayRef<Expr *> CallArgs) {
    275   assert(CallbackDecl != nullptr);
    276   assert(CallbackDecl->isLambda());
    277   FunctionDecl *callOperatorDecl = CallbackDecl->getLambdaCallOperator();
    278   assert(callOperatorDecl != nullptr);
    279 
    280   DeclRefExpr *callOperatorDeclRef =
    281       DeclRefExpr::Create(/* Ctx =*/ C,
    282                           /* QualifierLoc =*/ NestedNameSpecifierLoc(),
    283                           /* TemplateKWLoc =*/ SourceLocation(),
    284                           const_cast<FunctionDecl *>(callOperatorDecl),
    285                           /* RefersToEnclosingVariableOrCapture=*/ false,
    286                           /* NameLoc =*/ SourceLocation(),
    287                           /* T =*/ callOperatorDecl->getType(),
    288                           /* VK =*/ VK_LValue);
    289 
    290   return CXXOperatorCallExpr::Create(
    291       /*AstContext=*/C, OO_Call, callOperatorDeclRef,
    292       /*Args=*/CallArgs,
    293       /*QualType=*/C.VoidTy,
    294       /*ExprValueType=*/VK_RValue,
    295       /*SourceLocation=*/SourceLocation(),
    296       /*FPFeatures=*/FPOptionsOverride());
    297 }
    298 
    299 /// Create a fake body for std::call_once.
    300 /// Emulates the following function body:
    301 ///
    302 /// \code
    303 /// typedef struct once_flag_s {
    304 ///   unsigned long __state = 0;
    305 /// } once_flag;
    306 /// template<class Callable>
    307 /// void call_once(once_flag& o, Callable func) {
    308 ///   if (!o.__state) {
    309 ///     func();
    310 ///   }
    311 ///   o.__state = 1;
    312 /// }
    313 /// \endcode
    314 static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) {
    315   LLVM_DEBUG(llvm::dbgs() << "Generating body for call_once\n");
    316 
    317   // We need at least two parameters.
    318   if (D->param_size() < 2)
    319     return nullptr;
    320 
    321   ASTMaker M(C);
    322 
    323   const ParmVarDecl *Flag = D->getParamDecl(0);
    324   const ParmVarDecl *Callback = D->getParamDecl(1);
    325 
    326   if (!Callback->getType()->isReferenceType()) {
    327     llvm::dbgs() << "libcxx03 std::call_once implementation, skipping.\n";
    328     return nullptr;
    329   }
    330   if (!Flag->getType()->isReferenceType()) {
    331     llvm::dbgs() << "unknown std::call_once implementation, skipping.\n";
    332     return nullptr;
    333   }
    334 
    335   QualType CallbackType = Callback->getType().getNonReferenceType();
    336 
    337   // Nullable pointer, non-null iff function is a CXXRecordDecl.
    338   CXXRecordDecl *CallbackRecordDecl = CallbackType->getAsCXXRecordDecl();
    339   QualType FlagType = Flag->getType().getNonReferenceType();
    340   auto *FlagRecordDecl = FlagType->getAsRecordDecl();
    341 
    342   if (!FlagRecordDecl) {
    343     LLVM_DEBUG(llvm::dbgs() << "Flag field is not a record: "
    344                             << "unknown std::call_once implementation, "
    345                             << "ignoring the call.\n");
    346     return nullptr;
    347   }
    348 
    349   // We initially assume libc++ implementation of call_once,
    350   // where the once_flag struct has a field `__state_`.
    351   ValueDecl *FlagFieldDecl = M.findMemberField(FlagRecordDecl, "__state_");
    352 
    353   // Otherwise, try libstdc++ implementation, with a field
    354   // `_M_once`
    355   if (!FlagFieldDecl) {
    356     FlagFieldDecl = M.findMemberField(FlagRecordDecl, "_M_once");
    357   }
    358 
    359   if (!FlagFieldDecl) {
    360     LLVM_DEBUG(llvm::dbgs() << "No field _M_once or __state_ found on "
    361                             << "std::once_flag struct: unknown std::call_once "
    362                             << "implementation, ignoring the call.");
    363     return nullptr;
    364   }
    365 
    366   bool isLambdaCall = CallbackRecordDecl && CallbackRecordDecl->isLambda();
    367   if (CallbackRecordDecl && !isLambdaCall) {
    368     LLVM_DEBUG(llvm::dbgs()
    369                << "Not supported: synthesizing body for functors when "
    370                << "body farming std::call_once, ignoring the call.");
    371     return nullptr;
    372   }
    373 
    374   SmallVector<Expr *, 5> CallArgs;
    375   const FunctionProtoType *CallbackFunctionType;
    376   if (isLambdaCall) {
    377 
    378     // Lambda requires callback itself inserted as a first parameter.
    379     CallArgs.push_back(
    380         M.makeDeclRefExpr(Callback,
    381                           /* RefersToEnclosingVariableOrCapture=*/ true));
    382     CallbackFunctionType = CallbackRecordDecl->getLambdaCallOperator()
    383                                ->getType()
    384                                ->getAs<FunctionProtoType>();
    385   } else if (!CallbackType->getPointeeType().isNull()) {
    386     CallbackFunctionType =
    387         CallbackType->getPointeeType()->getAs<FunctionProtoType>();
    388   } else {
    389     CallbackFunctionType = CallbackType->getAs<FunctionProtoType>();
    390   }
    391 
    392   if (!CallbackFunctionType)
    393     return nullptr;
    394 
    395   // First two arguments are used for the flag and for the callback.
    396   if (D->getNumParams() != CallbackFunctionType->getNumParams() + 2) {
    397     LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
    398                             << "params passed to std::call_once, "
    399                             << "ignoring the call\n");
    400     return nullptr;
    401   }
    402 
    403   // All arguments past first two ones are passed to the callback,
    404   // and we turn lvalues into rvalues if the argument is not passed by
    405   // reference.
    406   for (unsigned int ParamIdx = 2; ParamIdx < D->getNumParams(); ParamIdx++) {
    407     const ParmVarDecl *PDecl = D->getParamDecl(ParamIdx);
    408     assert(PDecl);
    409     if (CallbackFunctionType->getParamType(ParamIdx - 2)
    410                 .getNonReferenceType()
    411                 .getCanonicalType() !=
    412             PDecl->getType().getNonReferenceType().getCanonicalType()) {
    413       LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
    414                               << "params passed to std::call_once, "
    415                               << "ignoring the call\n");
    416       return nullptr;
    417     }
    418     Expr *ParamExpr = M.makeDeclRefExpr(PDecl);
    419     if (!CallbackFunctionType->getParamType(ParamIdx - 2)->isReferenceType()) {
    420       QualType PTy = PDecl->getType().getNonReferenceType();
    421       ParamExpr = M.makeLvalueToRvalue(ParamExpr, PTy);
    422     }
    423     CallArgs.push_back(ParamExpr);
    424   }
    425 
    426   CallExpr *CallbackCall;
    427   if (isLambdaCall) {
    428 
    429     CallbackCall = create_call_once_lambda_call(C, M, Callback,
    430                                                 CallbackRecordDecl, CallArgs);
    431   } else {
    432 
    433     // Function pointer case.
    434     CallbackCall = create_call_once_funcptr_call(C, M, Callback, CallArgs);
    435   }
    436 
    437   DeclRefExpr *FlagDecl =
    438       M.makeDeclRefExpr(Flag,
    439                         /* RefersToEnclosingVariableOrCapture=*/true);
    440 
    441 
    442   MemberExpr *Deref = M.makeMemberExpression(FlagDecl, FlagFieldDecl);
    443   assert(Deref->isLValue());
    444   QualType DerefType = Deref->getType();
    445 
    446   // Negation predicate.
    447   UnaryOperator *FlagCheck = UnaryOperator::Create(
    448       C,
    449       /* input=*/
    450       M.makeImplicitCast(M.makeLvalueToRvalue(Deref, DerefType), DerefType,
    451                          CK_IntegralToBoolean),
    452       /* opc=*/UO_LNot,
    453       /* QualType=*/C.IntTy,
    454       /* ExprValueKind=*/VK_RValue,
    455       /* ExprObjectKind=*/OK_Ordinary, SourceLocation(),
    456       /* CanOverflow*/ false, FPOptionsOverride());
    457 
    458   // Create assignment.
    459   BinaryOperator *FlagAssignment = M.makeAssignment(
    460       Deref, M.makeIntegralCast(M.makeIntegerLiteral(1, C.IntTy), DerefType),
    461       DerefType);
    462 
    463   auto *Out =
    464       IfStmt::Create(C, SourceLocation(),
    465                      /* IsConstexpr=*/false,
    466                      /* Init=*/nullptr,
    467                      /* Var=*/nullptr,
    468                      /* Cond=*/FlagCheck,
    469                      /* LPL=*/SourceLocation(),
    470                      /* RPL=*/SourceLocation(),
    471                      /* Then=*/M.makeCompound({CallbackCall, FlagAssignment}));
    472 
    473   return Out;
    474 }
    475 
    476 /// Create a fake body for dispatch_once.
    477 static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
    478   // Check if we have at least two parameters.
    479   if (D->param_size() != 2)
    480     return nullptr;
    481 
    482   // Check if the first parameter is a pointer to integer type.
    483   const ParmVarDecl *Predicate = D->getParamDecl(0);
    484   QualType PredicateQPtrTy = Predicate->getType();
    485   const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>();
    486   if (!PredicatePtrTy)
    487     return nullptr;
    488   QualType PredicateTy = PredicatePtrTy->getPointeeType();
    489   if (!PredicateTy->isIntegerType())
    490     return nullptr;
    491 
    492   // Check if the second parameter is the proper block type.
    493   const ParmVarDecl *Block = D->getParamDecl(1);
    494   QualType Ty = Block->getType();
    495   if (!isDispatchBlock(Ty))
    496     return nullptr;
    497 
    498   // Everything checks out.  Create a fakse body that checks the predicate,
    499   // sets it, and calls the block.  Basically, an AST dump of:
    500   //
    501   // void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
    502   //  if (*predicate != ~0l) {
    503   //    *predicate = ~0l;
    504   //    block();
    505   //  }
    506   // }
    507 
    508   ASTMaker M(C);
    509 
    510   // (1) Create the call.
    511   CallExpr *CE = CallExpr::Create(
    512       /*ASTContext=*/C,
    513       /*StmtClass=*/M.makeLvalueToRvalue(/*Expr=*/Block),
    514       /*Args=*/None,
    515       /*QualType=*/C.VoidTy,
    516       /*ExprValueType=*/VK_RValue,
    517       /*SourceLocation=*/SourceLocation(), FPOptionsOverride());
    518 
    519   // (2) Create the assignment to the predicate.
    520   Expr *DoneValue =
    521       UnaryOperator::Create(C, M.makeIntegerLiteral(0, C.LongTy), UO_Not,
    522                             C.LongTy, VK_RValue, OK_Ordinary, SourceLocation(),
    523                             /*CanOverflow*/ false, FPOptionsOverride());
    524 
    525   BinaryOperator *B =
    526     M.makeAssignment(
    527        M.makeDereference(
    528           M.makeLvalueToRvalue(
    529             M.makeDeclRefExpr(Predicate), PredicateQPtrTy),
    530             PredicateTy),
    531        M.makeIntegralCast(DoneValue, PredicateTy),
    532        PredicateTy);
    533 
    534   // (3) Create the compound statement.
    535   Stmt *Stmts[] = { B, CE };
    536   CompoundStmt *CS = M.makeCompound(Stmts);
    537 
    538   // (4) Create the 'if' condition.
    539   ImplicitCastExpr *LValToRval =
    540     M.makeLvalueToRvalue(
    541       M.makeDereference(
    542         M.makeLvalueToRvalue(
    543           M.makeDeclRefExpr(Predicate),
    544           PredicateQPtrTy),
    545         PredicateTy),
    546     PredicateTy);
    547 
    548   Expr *GuardCondition = M.makeComparison(LValToRval, DoneValue, BO_NE);
    549   // (5) Create the 'if' statement.
    550   auto *If = IfStmt::Create(C, SourceLocation(),
    551                             /* IsConstexpr=*/false,
    552                             /* Init=*/nullptr,
    553                             /* Var=*/nullptr,
    554                             /* Cond=*/GuardCondition,
    555                             /* LPL=*/SourceLocation(),
    556                             /* RPL=*/SourceLocation(),
    557                             /* Then=*/CS);
    558   return If;
    559 }
    560 
    561 /// Create a fake body for dispatch_sync.
    562 static Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) {
    563   // Check if we have at least two parameters.
    564   if (D->param_size() != 2)
    565     return nullptr;
    566 
    567   // Check if the second parameter is a block.
    568   const ParmVarDecl *PV = D->getParamDecl(1);
    569   QualType Ty = PV->getType();
    570   if (!isDispatchBlock(Ty))
    571     return nullptr;
    572 
    573   // Everything checks out.  Create a fake body that just calls the block.
    574   // This is basically just an AST dump of:
    575   //
    576   // void dispatch_sync(dispatch_queue_t queue, void (^block)(void)) {
    577   //   block();
    578   // }
    579   //
    580   ASTMaker M(C);
    581   DeclRefExpr *DR = M.makeDeclRefExpr(PV);
    582   ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
    583   CallExpr *CE = CallExpr::Create(C, ICE, None, C.VoidTy, VK_RValue,
    584                                   SourceLocation(), FPOptionsOverride());
    585   return CE;
    586 }
    587 
    588 static Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D)
    589 {
    590   // There are exactly 3 arguments.
    591   if (D->param_size() != 3)
    592     return nullptr;
    593 
    594   // Signature:
    595   // _Bool OSAtomicCompareAndSwapPtr(void *__oldValue,
    596   //                                 void *__newValue,
    597   //                                 void * volatile *__theValue)
    598   // Generate body:
    599   //   if (oldValue == *theValue) {
    600   //    *theValue = newValue;
    601   //    return YES;
    602   //   }
    603   //   else return NO;
    604 
    605   QualType ResultTy = D->getReturnType();
    606   bool isBoolean = ResultTy->isBooleanType();
    607   if (!isBoolean && !ResultTy->isIntegralType(C))
    608     return nullptr;
    609 
    610   const ParmVarDecl *OldValue = D->getParamDecl(0);
    611   QualType OldValueTy = OldValue->getType();
    612 
    613   const ParmVarDecl *NewValue = D->getParamDecl(1);
    614   QualType NewValueTy = NewValue->getType();
    615 
    616   assert(OldValueTy == NewValueTy);
    617 
    618   const ParmVarDecl *TheValue = D->getParamDecl(2);
    619   QualType TheValueTy = TheValue->getType();
    620   const PointerType *PT = TheValueTy->getAs<PointerType>();
    621   if (!PT)
    622     return nullptr;
    623   QualType PointeeTy = PT->getPointeeType();
    624 
    625   ASTMaker M(C);
    626   // Construct the comparison.
    627   Expr *Comparison =
    628     M.makeComparison(
    629       M.makeLvalueToRvalue(M.makeDeclRefExpr(OldValue), OldValueTy),
    630       M.makeLvalueToRvalue(
    631         M.makeDereference(
    632           M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
    633           PointeeTy),
    634         PointeeTy),
    635       BO_EQ);
    636 
    637   // Construct the body of the IfStmt.
    638   Stmt *Stmts[2];
    639   Stmts[0] =
    640     M.makeAssignment(
    641       M.makeDereference(
    642         M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
    643         PointeeTy),
    644       M.makeLvalueToRvalue(M.makeDeclRefExpr(NewValue), NewValueTy),
    645       NewValueTy);
    646 
    647   Expr *BoolVal = M.makeObjCBool(true);
    648   Expr *RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
    649                            : M.makeIntegralCast(BoolVal, ResultTy);
    650   Stmts[1] = M.makeReturn(RetVal);
    651   CompoundStmt *Body = M.makeCompound(Stmts);
    652 
    653   // Construct the else clause.
    654   BoolVal = M.makeObjCBool(false);
    655   RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
    656                      : M.makeIntegralCast(BoolVal, ResultTy);
    657   Stmt *Else = M.makeReturn(RetVal);
    658 
    659   /// Construct the If.
    660   auto *If =
    661       IfStmt::Create(C, SourceLocation(),
    662                      /* IsConstexpr=*/false,
    663                      /* Init=*/nullptr,
    664                      /* Var=*/nullptr, Comparison,
    665                      /* LPL=*/SourceLocation(),
    666                      /* RPL=*/SourceLocation(), Body, SourceLocation(), Else);
    667 
    668   return If;
    669 }
    670 
    671 Stmt *BodyFarm::getBody(const FunctionDecl *D) {
    672   Optional<Stmt *> &Val = Bodies[D];
    673   if (Val.hasValue())
    674     return Val.getValue();
    675 
    676   Val = nullptr;
    677 
    678   if (D->getIdentifier() == nullptr)
    679     return nullptr;
    680 
    681   StringRef Name = D->getName();
    682   if (Name.empty())
    683     return nullptr;
    684 
    685   FunctionFarmer FF;
    686 
    687   if (Name.startswith("OSAtomicCompareAndSwap") ||
    688       Name.startswith("objc_atomicCompareAndSwap")) {
    689     FF = create_OSAtomicCompareAndSwap;
    690   } else if (Name == "call_once" && D->getDeclContext()->isStdNamespace()) {
    691     FF = create_call_once;
    692   } else {
    693     FF = llvm::StringSwitch<FunctionFarmer>(Name)
    694           .Case("dispatch_sync", create_dispatch_sync)
    695           .Case("dispatch_once", create_dispatch_once)
    696           .Default(nullptr);
    697   }
    698 
    699   if (FF) { Val = FF(C, D); }
    700   else if (Injector) { Val = Injector->getBody(D); }
    701   return Val.getValue();
    702 }
    703 
    704 static const ObjCIvarDecl *findBackingIvar(const ObjCPropertyDecl *Prop) {
    705   const ObjCIvarDecl *IVar = Prop->getPropertyIvarDecl();
    706 
    707   if (IVar)
    708     return IVar;
    709 
    710   // When a readonly property is shadowed in a class extensions with a
    711   // a readwrite property, the instance variable belongs to the shadowing
    712   // property rather than the shadowed property. If there is no instance
    713   // variable on a readonly property, check to see whether the property is
    714   // shadowed and if so try to get the instance variable from shadowing
    715   // property.
    716   if (!Prop->isReadOnly())
    717     return nullptr;
    718 
    719   auto *Container = cast<ObjCContainerDecl>(Prop->getDeclContext());
    720   const ObjCInterfaceDecl *PrimaryInterface = nullptr;
    721   if (auto *InterfaceDecl = dyn_cast<ObjCInterfaceDecl>(Container)) {
    722     PrimaryInterface = InterfaceDecl;
    723   } else if (auto *CategoryDecl = dyn_cast<ObjCCategoryDecl>(Container)) {
    724     PrimaryInterface = CategoryDecl->getClassInterface();
    725   } else if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container)) {
    726     PrimaryInterface = ImplDecl->getClassInterface();
    727   } else {
    728     return nullptr;
    729   }
    730 
    731   // FindPropertyVisibleInPrimaryClass() looks first in class extensions, so it
    732   // is guaranteed to find the shadowing property, if it exists, rather than
    733   // the shadowed property.
    734   auto *ShadowingProp = PrimaryInterface->FindPropertyVisibleInPrimaryClass(
    735       Prop->getIdentifier(), Prop->getQueryKind());
    736   if (ShadowingProp && ShadowingProp != Prop) {
    737     IVar = ShadowingProp->getPropertyIvarDecl();
    738   }
    739 
    740   return IVar;
    741 }
    742 
    743 static Stmt *createObjCPropertyGetter(ASTContext &Ctx,
    744                                       const ObjCMethodDecl *MD) {
    745   // First, find the backing ivar.
    746   const ObjCIvarDecl *IVar = nullptr;
    747   const ObjCPropertyDecl *Prop = nullptr;
    748 
    749   // Property accessor stubs sometimes do not correspond to any property decl
    750   // in the current interface (but in a superclass). They still have a
    751   // corresponding property impl decl in this case.
    752   if (MD->isSynthesizedAccessorStub()) {
    753     const ObjCInterfaceDecl *IntD = MD->getClassInterface();
    754     const ObjCImplementationDecl *ImpD = IntD->getImplementation();
    755     for (const auto *PI : ImpD->property_impls()) {
    756       if (const ObjCPropertyDecl *Candidate = PI->getPropertyDecl()) {
    757         if (Candidate->getGetterName() == MD->getSelector()) {
    758           Prop = Candidate;
    759           IVar = Prop->getPropertyIvarDecl();
    760         }
    761       }
    762     }
    763   }
    764 
    765   if (!IVar) {
    766     Prop = MD->findPropertyDecl();
    767     IVar = findBackingIvar(Prop);
    768   }
    769 
    770   if (!IVar || !Prop)
    771     return nullptr;
    772 
    773   // Ignore weak variables, which have special behavior.
    774   if (Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak)
    775     return nullptr;
    776 
    777   // Look to see if Sema has synthesized a body for us. This happens in
    778   // Objective-C++ because the return value may be a C++ class type with a
    779   // non-trivial copy constructor. We can only do this if we can find the
    780   // @synthesize for this property, though (or if we know it's been auto-
    781   // synthesized).
    782   const ObjCImplementationDecl *ImplDecl =
    783       IVar->getContainingInterface()->getImplementation();
    784   if (ImplDecl) {
    785     for (const auto *I : ImplDecl->property_impls()) {
    786       if (I->getPropertyDecl() != Prop)
    787         continue;
    788 
    789       if (I->getGetterCXXConstructor()) {
    790         ASTMaker M(Ctx);
    791         return M.makeReturn(I->getGetterCXXConstructor());
    792       }
    793     }
    794   }
    795 
    796   // Sanity check that the property is the same type as the ivar, or a
    797   // reference to it, and that it is either an object pointer or trivially
    798   // copyable.
    799   if (!Ctx.hasSameUnqualifiedType(IVar->getType(),
    800                                   Prop->getType().getNonReferenceType()))
    801     return nullptr;
    802   if (!IVar->getType()->isObjCLifetimeType() &&
    803       !IVar->getType().isTriviallyCopyableType(Ctx))
    804     return nullptr;
    805 
    806   // Generate our body:
    807   //   return self->_ivar;
    808   ASTMaker M(Ctx);
    809 
    810   const VarDecl *selfVar = MD->getSelfDecl();
    811   if (!selfVar)
    812     return nullptr;
    813 
    814   Expr *loadedIVar = M.makeObjCIvarRef(
    815       M.makeLvalueToRvalue(M.makeDeclRefExpr(selfVar), selfVar->getType()),
    816       IVar);
    817 
    818   if (!MD->getReturnType()->isReferenceType())
    819     loadedIVar = M.makeLvalueToRvalue(loadedIVar, IVar->getType());
    820 
    821   return M.makeReturn(loadedIVar);
    822 }
    823 
    824 Stmt *BodyFarm::getBody(const ObjCMethodDecl *D) {
    825   // We currently only know how to synthesize property accessors.
    826   if (!D->isPropertyAccessor())
    827     return nullptr;
    828 
    829   D = D->getCanonicalDecl();
    830 
    831   // We should not try to synthesize explicitly redefined accessors.
    832   // We do not know for sure how they behave.
    833   if (!D->isImplicit())
    834     return nullptr;
    835 
    836   Optional<Stmt *> &Val = Bodies[D];
    837   if (Val.hasValue())
    838     return Val.getValue();
    839   Val = nullptr;
    840 
    841   // For now, we only synthesize getters.
    842   // Synthesizing setters would cause false negatives in the
    843   // RetainCountChecker because the method body would bind the parameter
    844   // to an instance variable, causing it to escape. This would prevent
    845   // warning in the following common scenario:
    846   //
    847   //  id foo = [[NSObject alloc] init];
    848   //  self.foo = foo; // We should warn that foo leaks here.
    849   //
    850   if (D->param_size() != 0)
    851     return nullptr;
    852 
    853   // If the property was defined in an extension, search the extensions for
    854   // overrides.
    855   const ObjCInterfaceDecl *OID = D->getClassInterface();
    856   if (dyn_cast<ObjCInterfaceDecl>(D->getParent()) != OID)
    857     for (auto *Ext : OID->known_extensions()) {
    858       auto *OMD = Ext->getInstanceMethod(D->getSelector());
    859       if (OMD && !OMD->isImplicit())
    860         return nullptr;
    861     }
    862 
    863   Val = createObjCPropertyGetter(C, D);
    864 
    865   return Val.getValue();
    866 }
    867