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
29using namespace clang;
30
31//===----------------------------------------------------------------------===//
32// Helper creation functions for constructing faux ASTs.
33//===----------------------------------------------------------------------===//
34
35static 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
48namespace {
49class ASTMaker {
50public:
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
110private:
111  ASTContext &C;
112};
113}
114
115BinaryOperator *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
122BinaryOperator *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
132CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
133  return CompoundStmt::Create(C, Stmts, SourceLocation(), SourceLocation());
134}
135
136DeclRefExpr *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
147UnaryOperator *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
153ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) {
154  return makeImplicitCast(Arg, Ty, CK_LValueToRValue);
155}
156
157ImplicitCastExpr *
158ASTMaker::makeLvalueToRvalue(const VarDecl *Arg,
159                             bool RefersToEnclosingVariableOrCapture) {
160  QualType Type = Arg->getType().getNonReferenceType();
161  return makeLvalueToRvalue(makeDeclRefExpr(Arg,
162                                            RefersToEnclosingVariableOrCapture),
163                            Type);
164}
165
166ImplicitCastExpr *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}
174
175Expr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
176  if (Arg->getType() == Ty)
177    return const_cast<Expr*>(Arg);
178
179  return ImplicitCastExpr::Create(C, Ty, CK_IntegralCast,
180                                  const_cast<Expr*>(Arg), nullptr, VK_RValue);
181}
182
183ImplicitCastExpr *ASTMaker::makeIntegralCastToBoolean(const Expr *Arg) {
184  return ImplicitCastExpr::Create(C, C.BoolTy, CK_IntegralToBoolean,
185                                  const_cast<Expr*>(Arg), nullptr, VK_RValue);
186}
187
188ObjCBoolLiteralExpr *ASTMaker::makeObjCBool(bool Val) {
189  QualType Ty = C.getBOOLDecl() ? C.getBOOLType() : C.ObjCBuiltinBoolTy;
190  return new (C) ObjCBoolLiteralExpr(Val, Ty, SourceLocation());
191}
192
193ObjCIvarRefExpr *ASTMaker::makeObjCIvarRef(const Expr *Base,
194                                           const ObjCIvarDecl *IVar) {
195  return new (C) ObjCIvarRefExpr(const_cast<ObjCIvarDecl*>(IVar),
196                                 IVar->getType(), SourceLocation(),
197                                 SourceLocation(), const_cast<Expr*>(Base),
198                                 /*arrow=*/true, /*free=*/false);
199}
200
201ReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) {
202  return ReturnStmt::Create(C, SourceLocation(), const_cast<Expr *>(RetVal),
203                            /* NRVOCandidate=*/nullptr);
204}
205
206IntegerLiteral *ASTMaker::makeIntegerLiteral(uint64_t Value, QualType Ty) {
207  llvm::APInt APValue = llvm::APInt(C.getTypeSize(Ty), Value);
208  return IntegerLiteral::Create(C, APValue, Ty, SourceLocation());
209}
210
211MemberExpr *ASTMaker::makeMemberExpression(Expr *base, ValueDecl *MemberDecl,
212                                           bool IsArrow,
213                                           ExprValueKind ValueKind) {
214
215  DeclAccessPair FoundDecl = DeclAccessPair::make(MemberDecl, AS_public);
216  return MemberExpr::Create(
217      C, base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(),
218      SourceLocation(), MemberDecl, FoundDecl,
219      DeclarationNameInfo(MemberDecl->getDeclName(), SourceLocation()),
220      /* TemplateArgumentListInfo=*/ nullptr, MemberDecl->getType(), ValueKind,
221      OK_Ordinary, NOUR_None);
222}
223
224ValueDecl *ASTMaker::findMemberField(const RecordDecl *RD, StringRef Name) {
225
226  CXXBasePaths Paths(
227      /* FindAmbiguities=*/false,
228      /* RecordPaths=*/false,
229      /* DetectVirtual=*/ false);
230  const IdentifierInfo &II = C.Idents.get(Name);
231  DeclarationName DeclName = C.DeclarationNames.getIdentifier(&II);
232
233  DeclContextLookupResult Decls = RD->lookup(DeclName);
234  for (NamedDecl *FoundDecl : Decls)
235    if (!FoundDecl->getDeclContext()->isFunctionOrMethod())
236      return cast<ValueDecl>(FoundDecl);
237
238  return nullptr;
239}
240
241//===----------------------------------------------------------------------===//
242// Creation functions for faux ASTs.
243//===----------------------------------------------------------------------===//
244
245typedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D);
246
247static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M,
248                                               const ParmVarDecl *Callback,
249                                               ArrayRef<Expr *> CallArgs) {
250
251  QualType Ty = Callback->getType();
252  DeclRefExpr *Call = M.makeDeclRefExpr(Callback);
253  Expr *SubExpr;
254  if (Ty->isRValueReferenceType()) {
255    SubExpr = M.makeImplicitCast(
256        Call, Ty.getNonReferenceType(), CK_LValueToRValue);
257  } else if (Ty->isLValueReferenceType() &&
258             Call->getType()->isFunctionType()) {
259    Ty = C.getPointerType(Ty.getNonReferenceType());
260    SubExpr = M.makeImplicitCast(Call, Ty, CK_FunctionToPointerDecay);
261  } else if (Ty->isLValueReferenceType()
262             && Call->getType()->isPointerType()
263             && Call->getType()->getPointeeType()->isFunctionType()){
264    SubExpr = Call;
265  } else {
266    llvm_unreachable("Unexpected state");
267  }
268
269  return CallExpr::Create(C, SubExpr, CallArgs, C.VoidTy, VK_RValue,
270                          SourceLocation());
271}
272
273static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
274                                              const ParmVarDecl *Callback,
275                                              CXXRecordDecl *CallbackDecl,
276                                              ArrayRef<Expr *> CallArgs) {
277  assert(CallbackDecl != nullptr);
278  assert(CallbackDecl->isLambda());
279  FunctionDecl *callOperatorDecl = CallbackDecl->getLambdaCallOperator();
280  assert(callOperatorDecl != nullptr);
281
282  DeclRefExpr *callOperatorDeclRef =
283      DeclRefExpr::Create(/* Ctx =*/ C,
284                          /* QualifierLoc =*/ NestedNameSpecifierLoc(),
285                          /* TemplateKWLoc =*/ SourceLocation(),
286                          const_cast<FunctionDecl *>(callOperatorDecl),
287                          /* RefersToEnclosingVariableOrCapture=*/ false,
288                          /* NameLoc =*/ SourceLocation(),
289                          /* T =*/ callOperatorDecl->getType(),
290                          /* VK =*/ VK_LValue);
291
292  return CXXOperatorCallExpr::Create(
293      /*AstContext=*/C, OO_Call, callOperatorDeclRef,
294      /*Args=*/CallArgs,
295      /*QualType=*/C.VoidTy,
296      /*ExprValueType=*/VK_RValue,
297      /*SourceLocation=*/SourceLocation(),
298      /*FPFeatures=*/FPOptionsOverride());
299}
300
301/// Create a fake body for std::call_once.
302/// Emulates the following function body:
303///
304/// \code
305/// typedef struct once_flag_s {
306///   unsigned long __state = 0;
307/// } once_flag;
308/// template<class Callable>
309/// void call_once(once_flag& o, Callable func) {
310///   if (!o.__state) {
311///     func();
312///   }
313///   o.__state = 1;
314/// }
315/// \endcode
316static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) {
317  LLVM_DEBUG(llvm::dbgs() << "Generating body for call_once\n");
318
319  // We need at least two parameters.
320  if (D->param_size() < 2)
321    return nullptr;
322
323  ASTMaker M(C);
324
325  const ParmVarDecl *Flag = D->getParamDecl(0);
326  const ParmVarDecl *Callback = D->getParamDecl(1);
327
328  if (!Callback->getType()->isReferenceType()) {
329    llvm::dbgs() << "libcxx03 std::call_once implementation, skipping.\n";
330    return nullptr;
331  }
332  if (!Flag->getType()->isReferenceType()) {
333    llvm::dbgs() << "unknown std::call_once implementation, skipping.\n";
334    return nullptr;
335  }
336
337  QualType CallbackType = Callback->getType().getNonReferenceType();
338
339  // Nullable pointer, non-null iff function is a CXXRecordDecl.
340  CXXRecordDecl *CallbackRecordDecl = CallbackType->getAsCXXRecordDecl();
341  QualType FlagType = Flag->getType().getNonReferenceType();
342  auto *FlagRecordDecl = FlagType->getAsRecordDecl();
343
344  if (!FlagRecordDecl) {
345    LLVM_DEBUG(llvm::dbgs() << "Flag field is not a record: "
346                            << "unknown std::call_once implementation, "
347                            << "ignoring the call.\n");
348    return nullptr;
349  }
350
351  // We initially assume libc++ implementation of call_once,
352  // where the once_flag struct has a field `__state_`.
353  ValueDecl *FlagFieldDecl = M.findMemberField(FlagRecordDecl, "__state_");
354
355  // Otherwise, try libstdc++ implementation, with a field
356  // `_M_once`
357  if (!FlagFieldDecl) {
358    FlagFieldDecl = M.findMemberField(FlagRecordDecl, "_M_once");
359  }
360
361  if (!FlagFieldDecl) {
362    LLVM_DEBUG(llvm::dbgs() << "No field _M_once or __state_ found on "
363                            << "std::once_flag struct: unknown std::call_once "
364                            << "implementation, ignoring the call.");
365    return nullptr;
366  }
367
368  bool isLambdaCall = CallbackRecordDecl && CallbackRecordDecl->isLambda();
369  if (CallbackRecordDecl && !isLambdaCall) {
370    LLVM_DEBUG(llvm::dbgs()
371               << "Not supported: synthesizing body for functors when "
372               << "body farming std::call_once, ignoring the call.");
373    return nullptr;
374  }
375
376  SmallVector<Expr *, 5> CallArgs;
377  const FunctionProtoType *CallbackFunctionType;
378  if (isLambdaCall) {
379
380    // Lambda requires callback itself inserted as a first parameter.
381    CallArgs.push_back(
382        M.makeDeclRefExpr(Callback,
383                          /* RefersToEnclosingVariableOrCapture=*/ true));
384    CallbackFunctionType = CallbackRecordDecl->getLambdaCallOperator()
385                               ->getType()
386                               ->getAs<FunctionProtoType>();
387  } else if (!CallbackType->getPointeeType().isNull()) {
388    CallbackFunctionType =
389        CallbackType->getPointeeType()->getAs<FunctionProtoType>();
390  } else {
391    CallbackFunctionType = CallbackType->getAs<FunctionProtoType>();
392  }
393
394  if (!CallbackFunctionType)
395    return nullptr;
396
397  // First two arguments are used for the flag and for the callback.
398  if (D->getNumParams() != CallbackFunctionType->getNumParams() + 2) {
399    LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
400                            << "params passed to std::call_once, "
401                            << "ignoring the call\n");
402    return nullptr;
403  }
404
405  // All arguments past first two ones are passed to the callback,
406  // and we turn lvalues into rvalues if the argument is not passed by
407  // reference.
408  for (unsigned int ParamIdx = 2; ParamIdx < D->getNumParams(); ParamIdx++) {
409    const ParmVarDecl *PDecl = D->getParamDecl(ParamIdx);
410    assert(PDecl);
411    if (CallbackFunctionType->getParamType(ParamIdx - 2)
412                .getNonReferenceType()
413                .getCanonicalType() !=
414            PDecl->getType().getNonReferenceType().getCanonicalType()) {
415      LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
416                              << "params passed to std::call_once, "
417                              << "ignoring the call\n");
418      return nullptr;
419    }
420    Expr *ParamExpr = M.makeDeclRefExpr(PDecl);
421    if (!CallbackFunctionType->getParamType(ParamIdx - 2)->isReferenceType()) {
422      QualType PTy = PDecl->getType().getNonReferenceType();
423      ParamExpr = M.makeLvalueToRvalue(ParamExpr, PTy);
424    }
425    CallArgs.push_back(ParamExpr);
426  }
427
428  CallExpr *CallbackCall;
429  if (isLambdaCall) {
430
431    CallbackCall = create_call_once_lambda_call(C, M, Callback,
432                                                CallbackRecordDecl, CallArgs);
433  } else {
434
435    // Function pointer case.
436    CallbackCall = create_call_once_funcptr_call(C, M, Callback, CallArgs);
437  }
438
439  DeclRefExpr *FlagDecl =
440      M.makeDeclRefExpr(Flag,
441                        /* RefersToEnclosingVariableOrCapture=*/true);
442
443
444  MemberExpr *Deref = M.makeMemberExpression(FlagDecl, FlagFieldDecl);
445  assert(Deref->isLValue());
446  QualType DerefType = Deref->getType();
447
448  // Negation predicate.
449  UnaryOperator *FlagCheck = UnaryOperator::Create(
450      C,
451      /* input=*/
452      M.makeImplicitCast(M.makeLvalueToRvalue(Deref, DerefType), DerefType,
453                         CK_IntegralToBoolean),
454      /* opc=*/UO_LNot,
455      /* QualType=*/C.IntTy,
456      /* ExprValueKind=*/VK_RValue,
457      /* ExprObjectKind=*/OK_Ordinary, SourceLocation(),
458      /* CanOverflow*/ false, FPOptionsOverride());
459
460  // Create assignment.
461  BinaryOperator *FlagAssignment = M.makeAssignment(
462      Deref, M.makeIntegralCast(M.makeIntegerLiteral(1, C.IntTy), DerefType),
463      DerefType);
464
465  auto *Out =
466      IfStmt::Create(C, SourceLocation(),
467                     /* IsConstexpr=*/false,
468                     /* Init=*/nullptr,
469                     /* Var=*/nullptr,
470                     /* Cond=*/FlagCheck,
471                     /* Then=*/M.makeCompound({CallbackCall, FlagAssignment}));
472
473  return Out;
474}
475
476/// Create a fake body for dispatch_once.
477static 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());
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                            /* Then=*/CS);
556  return If;
557}
558
559/// Create a fake body for dispatch_sync.
560static Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) {
561  // Check if we have at least two parameters.
562  if (D->param_size() != 2)
563    return nullptr;
564
565  // Check if the second parameter is a block.
566  const ParmVarDecl *PV = D->getParamDecl(1);
567  QualType Ty = PV->getType();
568  if (!isDispatchBlock(Ty))
569    return nullptr;
570
571  // Everything checks out.  Create a fake body that just calls the block.
572  // This is basically just an AST dump of:
573  //
574  // void dispatch_sync(dispatch_queue_t queue, void (^block)(void)) {
575  //   block();
576  // }
577  //
578  ASTMaker M(C);
579  DeclRefExpr *DR = M.makeDeclRefExpr(PV);
580  ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
581  CallExpr *CE =
582      CallExpr::Create(C, ICE, None, C.VoidTy, VK_RValue, SourceLocation());
583  return CE;
584}
585
586static Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D)
587{
588  // There are exactly 3 arguments.
589  if (D->param_size() != 3)
590    return nullptr;
591
592  // Signature:
593  // _Bool OSAtomicCompareAndSwapPtr(void *__oldValue,
594  //                                 void *__newValue,
595  //                                 void * volatile *__theValue)
596  // Generate body:
597  //   if (oldValue == *theValue) {
598  //    *theValue = newValue;
599  //    return YES;
600  //   }
601  //   else return NO;
602
603  QualType ResultTy = D->getReturnType();
604  bool isBoolean = ResultTy->isBooleanType();
605  if (!isBoolean && !ResultTy->isIntegralType(C))
606    return nullptr;
607
608  const ParmVarDecl *OldValue = D->getParamDecl(0);
609  QualType OldValueTy = OldValue->getType();
610
611  const ParmVarDecl *NewValue = D->getParamDecl(1);
612  QualType NewValueTy = NewValue->getType();
613
614  assert(OldValueTy == NewValueTy);
615
616  const ParmVarDecl *TheValue = D->getParamDecl(2);
617  QualType TheValueTy = TheValue->getType();
618  const PointerType *PT = TheValueTy->getAs<PointerType>();
619  if (!PT)
620    return nullptr;
621  QualType PointeeTy = PT->getPointeeType();
622
623  ASTMaker M(C);
624  // Construct the comparison.
625  Expr *Comparison =
626    M.makeComparison(
627      M.makeLvalueToRvalue(M.makeDeclRefExpr(OldValue), OldValueTy),
628      M.makeLvalueToRvalue(
629        M.makeDereference(
630          M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
631          PointeeTy),
632        PointeeTy),
633      BO_EQ);
634
635  // Construct the body of the IfStmt.
636  Stmt *Stmts[2];
637  Stmts[0] =
638    M.makeAssignment(
639      M.makeDereference(
640        M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
641        PointeeTy),
642      M.makeLvalueToRvalue(M.makeDeclRefExpr(NewValue), NewValueTy),
643      NewValueTy);
644
645  Expr *BoolVal = M.makeObjCBool(true);
646  Expr *RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
647                           : M.makeIntegralCast(BoolVal, ResultTy);
648  Stmts[1] = M.makeReturn(RetVal);
649  CompoundStmt *Body = M.makeCompound(Stmts);
650
651  // Construct the else clause.
652  BoolVal = M.makeObjCBool(false);
653  RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
654                     : M.makeIntegralCast(BoolVal, ResultTy);
655  Stmt *Else = M.makeReturn(RetVal);
656
657  /// Construct the If.
658  auto *If = IfStmt::Create(C, SourceLocation(),
659                            /* IsConstexpr=*/false,
660                            /* Init=*/nullptr,
661                            /* Var=*/nullptr, Comparison, Body,
662                            SourceLocation(), Else);
663
664  return If;
665}
666
667Stmt *BodyFarm::getBody(const FunctionDecl *D) {
668  Optional<Stmt *> &Val = Bodies[D];
669  if (Val.hasValue())
670    return Val.getValue();
671
672  Val = nullptr;
673
674  if (D->getIdentifier() == nullptr)
675    return nullptr;
676
677  StringRef Name = D->getName();
678  if (Name.empty())
679    return nullptr;
680
681  FunctionFarmer FF;
682
683  if (Name.startswith("OSAtomicCompareAndSwap") ||
684      Name.startswith("objc_atomicCompareAndSwap")) {
685    FF = create_OSAtomicCompareAndSwap;
686  } else if (Name == "call_once" && D->getDeclContext()->isStdNamespace()) {
687    FF = create_call_once;
688  } else {
689    FF = llvm::StringSwitch<FunctionFarmer>(Name)
690          .Case("dispatch_sync", create_dispatch_sync)
691          .Case("dispatch_once", create_dispatch_once)
692          .Default(nullptr);
693  }
694
695  if (FF) { Val = FF(C, D); }
696  else if (Injector) { Val = Injector->getBody(D); }
697  return Val.getValue();
698}
699
700static const ObjCIvarDecl *findBackingIvar(const ObjCPropertyDecl *Prop) {
701  const ObjCIvarDecl *IVar = Prop->getPropertyIvarDecl();
702
703  if (IVar)
704    return IVar;
705
706  // When a readonly property is shadowed in a class extensions with a
707  // a readwrite property, the instance variable belongs to the shadowing
708  // property rather than the shadowed property. If there is no instance
709  // variable on a readonly property, check to see whether the property is
710  // shadowed and if so try to get the instance variable from shadowing
711  // property.
712  if (!Prop->isReadOnly())
713    return nullptr;
714
715  auto *Container = cast<ObjCContainerDecl>(Prop->getDeclContext());
716  const ObjCInterfaceDecl *PrimaryInterface = nullptr;
717  if (auto *InterfaceDecl = dyn_cast<ObjCInterfaceDecl>(Container)) {
718    PrimaryInterface = InterfaceDecl;
719  } else if (auto *CategoryDecl = dyn_cast<ObjCCategoryDecl>(Container)) {
720    PrimaryInterface = CategoryDecl->getClassInterface();
721  } else if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container)) {
722    PrimaryInterface = ImplDecl->getClassInterface();
723  } else {
724    return nullptr;
725  }
726
727  // FindPropertyVisibleInPrimaryClass() looks first in class extensions, so it
728  // is guaranteed to find the shadowing property, if it exists, rather than
729  // the shadowed property.
730  auto *ShadowingProp = PrimaryInterface->FindPropertyVisibleInPrimaryClass(
731      Prop->getIdentifier(), Prop->getQueryKind());
732  if (ShadowingProp && ShadowingProp != Prop) {
733    IVar = ShadowingProp->getPropertyIvarDecl();
734  }
735
736  return IVar;
737}
738
739static Stmt *createObjCPropertyGetter(ASTContext &Ctx,
740                                      const ObjCMethodDecl *MD) {
741    // First, find the backing ivar.
742  const ObjCIvarDecl *IVar = nullptr;
743
744  // Property accessor stubs sometimes do not correspond to any property decl
745  // in the current interface (but in a superclass). They still have a
746  // corresponding property impl decl in this case.
747  if (MD->isSynthesizedAccessorStub()) {
748    const ObjCInterfaceDecl *IntD = MD->getClassInterface();
749    const ObjCImplementationDecl *ImpD = IntD->getImplementation();
750    for (const auto *PI: ImpD->property_impls()) {
751      if (const ObjCPropertyDecl *P = PI->getPropertyDecl()) {
752        if (P->getGetterName() == MD->getSelector())
753          IVar = P->getPropertyIvarDecl();
754      }
755    }
756  }
757
758  if (!IVar) {
759    const ObjCPropertyDecl *Prop = MD->findPropertyDecl();
760    IVar = findBackingIvar(Prop);
761    if (!IVar)
762      return nullptr;
763
764    // Ignore weak variables, which have special behavior.
765    if (Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak)
766      return nullptr;
767
768    // Look to see if Sema has synthesized a body for us. This happens in
769    // Objective-C++ because the return value may be a C++ class type with a
770    // non-trivial copy constructor. We can only do this if we can find the
771    // @synthesize for this property, though (or if we know it's been auto-
772    // synthesized).
773    const ObjCImplementationDecl *ImplDecl =
774      IVar->getContainingInterface()->getImplementation();
775    if (ImplDecl) {
776      for (const auto *I : ImplDecl->property_impls()) {
777        if (I->getPropertyDecl() != Prop)
778          continue;
779
780        if (I->getGetterCXXConstructor()) {
781          ASTMaker M(Ctx);
782          return M.makeReturn(I->getGetterCXXConstructor());
783        }
784      }
785    }
786
787    // Sanity check that the property is the same type as the ivar, or a
788    // reference to it, and that it is either an object pointer or trivially
789    // copyable.
790    if (!Ctx.hasSameUnqualifiedType(IVar->getType(),
791                                    Prop->getType().getNonReferenceType()))
792      return nullptr;
793    if (!IVar->getType()->isObjCLifetimeType() &&
794        !IVar->getType().isTriviallyCopyableType(Ctx))
795      return nullptr;
796  }
797
798  // Generate our body:
799  //   return self->_ivar;
800  ASTMaker M(Ctx);
801
802  const VarDecl *selfVar = MD->getSelfDecl();
803  if (!selfVar)
804    return nullptr;
805
806  Expr *loadedIVar =
807    M.makeObjCIvarRef(
808      M.makeLvalueToRvalue(
809        M.makeDeclRefExpr(selfVar),
810        selfVar->getType()),
811      IVar);
812
813  if (!MD->getReturnType()->isReferenceType())
814    loadedIVar = M.makeLvalueToRvalue(loadedIVar, IVar->getType());
815
816  return M.makeReturn(loadedIVar);
817}
818
819Stmt *BodyFarm::getBody(const ObjCMethodDecl *D) {
820  // We currently only know how to synthesize property accessors.
821  if (!D->isPropertyAccessor())
822    return nullptr;
823
824  D = D->getCanonicalDecl();
825
826  // We should not try to synthesize explicitly redefined accessors.
827  // We do not know for sure how they behave.
828  if (!D->isImplicit())
829    return nullptr;
830
831  Optional<Stmt *> &Val = Bodies[D];
832  if (Val.hasValue())
833    return Val.getValue();
834  Val = nullptr;
835
836  // For now, we only synthesize getters.
837  // Synthesizing setters would cause false negatives in the
838  // RetainCountChecker because the method body would bind the parameter
839  // to an instance variable, causing it to escape. This would prevent
840  // warning in the following common scenario:
841  //
842  //  id foo = [[NSObject alloc] init];
843  //  self.foo = foo; // We should warn that foo leaks here.
844  //
845  if (D->param_size() != 0)
846    return nullptr;
847
848  // If the property was defined in an extension, search the extensions for
849  // overrides.
850  const ObjCInterfaceDecl *OID = D->getClassInterface();
851  if (dyn_cast<ObjCInterfaceDecl>(D->getParent()) != OID)
852    for (auto *Ext : OID->known_extensions()) {
853      auto *OMD = Ext->getInstanceMethod(D->getSelector());
854      if (OMD && !OMD->isImplicit())
855        return nullptr;
856    }
857
858  Val = createObjCPropertyGetter(C, D);
859
860  return Val.getValue();
861}
862