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