BodyFarm.cpp revision 360784
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 new (C) BinaryOperator(const_cast<Expr*>(LHS), const_cast<Expr*>(RHS),
118                               BO_Assign, Ty, VK_RValue,
119                               OK_Ordinary, SourceLocation(), FPOptions());
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 new (C) BinaryOperator(const_cast<Expr*>(LHS),
127                                const_cast<Expr*>(RHS),
128                                Op,
129                                C.getLogicalOperationType(),
130                                VK_RValue,
131                                OK_Ordinary, SourceLocation(), FPOptions());
132}
133
134CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
135  return CompoundStmt::Create(C, Stmts, SourceLocation(), SourceLocation());
136}
137
138DeclRefExpr *ASTMaker::makeDeclRefExpr(
139    const VarDecl *D,
140    bool RefersToEnclosingVariableOrCapture) {
141  QualType Type = D->getType().getNonReferenceType();
142
143  DeclRefExpr *DR = DeclRefExpr::Create(
144      C, NestedNameSpecifierLoc(), SourceLocation(), const_cast<VarDecl *>(D),
145      RefersToEnclosingVariableOrCapture, SourceLocation(), Type, VK_LValue);
146  return DR;
147}
148
149UnaryOperator *ASTMaker::makeDereference(const Expr *Arg, QualType Ty) {
150  return new (C) UnaryOperator(const_cast<Expr*>(Arg), UO_Deref, Ty,
151                               VK_LValue, OK_Ordinary, SourceLocation(),
152                              /*CanOverflow*/ false);
153}
154
155ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) {
156  return makeImplicitCast(Arg, Ty, CK_LValueToRValue);
157}
158
159ImplicitCastExpr *
160ASTMaker::makeLvalueToRvalue(const VarDecl *Arg,
161                             bool RefersToEnclosingVariableOrCapture) {
162  QualType Type = Arg->getType().getNonReferenceType();
163  return makeLvalueToRvalue(makeDeclRefExpr(Arg,
164                                            RefersToEnclosingVariableOrCapture),
165                            Type);
166}
167
168ImplicitCastExpr *ASTMaker::makeImplicitCast(const Expr *Arg, QualType Ty,
169                                             CastKind CK) {
170  return ImplicitCastExpr::Create(C, Ty,
171                                  /* CastKind=*/ CK,
172                                  /* Expr=*/ const_cast<Expr *>(Arg),
173                                  /* CXXCastPath=*/ nullptr,
174                                  /* ExprValueKind=*/ VK_RValue);
175}
176
177Expr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
178  if (Arg->getType() == Ty)
179    return const_cast<Expr*>(Arg);
180
181  return ImplicitCastExpr::Create(C, Ty, CK_IntegralCast,
182                                  const_cast<Expr*>(Arg), nullptr, VK_RValue);
183}
184
185ImplicitCastExpr *ASTMaker::makeIntegralCastToBoolean(const Expr *Arg) {
186  return ImplicitCastExpr::Create(C, C.BoolTy, CK_IntegralToBoolean,
187                                  const_cast<Expr*>(Arg), nullptr, VK_RValue);
188}
189
190ObjCBoolLiteralExpr *ASTMaker::makeObjCBool(bool Val) {
191  QualType Ty = C.getBOOLDecl() ? C.getBOOLType() : C.ObjCBuiltinBoolTy;
192  return new (C) ObjCBoolLiteralExpr(Val, Ty, SourceLocation());
193}
194
195ObjCIvarRefExpr *ASTMaker::makeObjCIvarRef(const Expr *Base,
196                                           const ObjCIvarDecl *IVar) {
197  return new (C) ObjCIvarRefExpr(const_cast<ObjCIvarDecl*>(IVar),
198                                 IVar->getType(), SourceLocation(),
199                                 SourceLocation(), const_cast<Expr*>(Base),
200                                 /*arrow=*/true, /*free=*/false);
201}
202
203ReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) {
204  return ReturnStmt::Create(C, SourceLocation(), const_cast<Expr *>(RetVal),
205                            /* NRVOCandidate=*/nullptr);
206}
207
208IntegerLiteral *ASTMaker::makeIntegerLiteral(uint64_t Value, QualType Ty) {
209  llvm::APInt APValue = llvm::APInt(C.getTypeSize(Ty), Value);
210  return IntegerLiteral::Create(C, APValue, Ty, SourceLocation());
211}
212
213MemberExpr *ASTMaker::makeMemberExpression(Expr *base, ValueDecl *MemberDecl,
214                                           bool IsArrow,
215                                           ExprValueKind ValueKind) {
216
217  DeclAccessPair FoundDecl = DeclAccessPair::make(MemberDecl, AS_public);
218  return MemberExpr::Create(
219      C, base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(),
220      SourceLocation(), MemberDecl, FoundDecl,
221      DeclarationNameInfo(MemberDecl->getDeclName(), SourceLocation()),
222      /* TemplateArgumentListInfo=*/ nullptr, MemberDecl->getType(), ValueKind,
223      OK_Ordinary, NOUR_None);
224}
225
226ValueDecl *ASTMaker::findMemberField(const RecordDecl *RD, StringRef Name) {
227
228  CXXBasePaths Paths(
229      /* FindAmbiguities=*/false,
230      /* RecordPaths=*/false,
231      /* DetectVirtual=*/ false);
232  const IdentifierInfo &II = C.Idents.get(Name);
233  DeclarationName DeclName = C.DeclarationNames.getIdentifier(&II);
234
235  DeclContextLookupResult Decls = RD->lookup(DeclName);
236  for (NamedDecl *FoundDecl : Decls)
237    if (!FoundDecl->getDeclContext()->isFunctionOrMethod())
238      return cast<ValueDecl>(FoundDecl);
239
240  return nullptr;
241}
242
243//===----------------------------------------------------------------------===//
244// Creation functions for faux ASTs.
245//===----------------------------------------------------------------------===//
246
247typedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D);
248
249static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M,
250                                               const ParmVarDecl *Callback,
251                                               ArrayRef<Expr *> CallArgs) {
252
253  QualType Ty = Callback->getType();
254  DeclRefExpr *Call = M.makeDeclRefExpr(Callback);
255  Expr *SubExpr;
256  if (Ty->isRValueReferenceType()) {
257    SubExpr = M.makeImplicitCast(
258        Call, Ty.getNonReferenceType(), CK_LValueToRValue);
259  } else if (Ty->isLValueReferenceType() &&
260             Call->getType()->isFunctionType()) {
261    Ty = C.getPointerType(Ty.getNonReferenceType());
262    SubExpr = M.makeImplicitCast(Call, Ty, CK_FunctionToPointerDecay);
263  } else if (Ty->isLValueReferenceType()
264             && Call->getType()->isPointerType()
265             && Call->getType()->getPointeeType()->isFunctionType()){
266    SubExpr = Call;
267  } else {
268    llvm_unreachable("Unexpected state");
269  }
270
271  return CallExpr::Create(C, SubExpr, CallArgs, C.VoidTy, VK_RValue,
272                          SourceLocation());
273}
274
275static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
276                                              const ParmVarDecl *Callback,
277                                              CXXRecordDecl *CallbackDecl,
278                                              ArrayRef<Expr *> CallArgs) {
279  assert(CallbackDecl != nullptr);
280  assert(CallbackDecl->isLambda());
281  FunctionDecl *callOperatorDecl = CallbackDecl->getLambdaCallOperator();
282  assert(callOperatorDecl != nullptr);
283
284  DeclRefExpr *callOperatorDeclRef =
285      DeclRefExpr::Create(/* Ctx =*/ C,
286                          /* QualifierLoc =*/ NestedNameSpecifierLoc(),
287                          /* TemplateKWLoc =*/ SourceLocation(),
288                          const_cast<FunctionDecl *>(callOperatorDecl),
289                          /* RefersToEnclosingVariableOrCapture=*/ false,
290                          /* NameLoc =*/ SourceLocation(),
291                          /* T =*/ callOperatorDecl->getType(),
292                          /* VK =*/ VK_LValue);
293
294  return CXXOperatorCallExpr::Create(
295      /*AstContext=*/C, OO_Call, callOperatorDeclRef,
296      /*Args=*/CallArgs,
297      /*QualType=*/C.VoidTy,
298      /*ExprValueType=*/VK_RValue,
299      /*SourceLocation=*/SourceLocation(), FPOptions());
300}
301
302/// Create a fake body for std::call_once.
303/// Emulates the following function body:
304///
305/// \code
306/// typedef struct once_flag_s {
307///   unsigned long __state = 0;
308/// } once_flag;
309/// template<class Callable>
310/// void call_once(once_flag& o, Callable func) {
311///   if (!o.__state) {
312///     func();
313///   }
314///   o.__state = 1;
315/// }
316/// \endcode
317static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) {
318  LLVM_DEBUG(llvm::dbgs() << "Generating body for call_once\n");
319
320  // We need at least two parameters.
321  if (D->param_size() < 2)
322    return nullptr;
323
324  ASTMaker M(C);
325
326  const ParmVarDecl *Flag = D->getParamDecl(0);
327  const ParmVarDecl *Callback = D->getParamDecl(1);
328
329  if (!Callback->getType()->isReferenceType()) {
330    llvm::dbgs() << "libcxx03 std::call_once implementation, skipping.\n";
331    return nullptr;
332  }
333  if (!Flag->getType()->isReferenceType()) {
334    llvm::dbgs() << "unknown std::call_once implementation, skipping.\n";
335    return nullptr;
336  }
337
338  QualType CallbackType = Callback->getType().getNonReferenceType();
339
340  // Nullable pointer, non-null iff function is a CXXRecordDecl.
341  CXXRecordDecl *CallbackRecordDecl = CallbackType->getAsCXXRecordDecl();
342  QualType FlagType = Flag->getType().getNonReferenceType();
343  auto *FlagRecordDecl = FlagType->getAsRecordDecl();
344
345  if (!FlagRecordDecl) {
346    LLVM_DEBUG(llvm::dbgs() << "Flag field is not a record: "
347                            << "unknown std::call_once implementation, "
348                            << "ignoring the call.\n");
349    return nullptr;
350  }
351
352  // We initially assume libc++ implementation of call_once,
353  // where the once_flag struct has a field `__state_`.
354  ValueDecl *FlagFieldDecl = M.findMemberField(FlagRecordDecl, "__state_");
355
356  // Otherwise, try libstdc++ implementation, with a field
357  // `_M_once`
358  if (!FlagFieldDecl) {
359    FlagFieldDecl = M.findMemberField(FlagRecordDecl, "_M_once");
360  }
361
362  if (!FlagFieldDecl) {
363    LLVM_DEBUG(llvm::dbgs() << "No field _M_once or __state_ found on "
364                            << "std::once_flag struct: unknown std::call_once "
365                            << "implementation, ignoring the call.");
366    return nullptr;
367  }
368
369  bool isLambdaCall = CallbackRecordDecl && CallbackRecordDecl->isLambda();
370  if (CallbackRecordDecl && !isLambdaCall) {
371    LLVM_DEBUG(llvm::dbgs()
372               << "Not supported: synthesizing body for functors when "
373               << "body farming std::call_once, ignoring the call.");
374    return nullptr;
375  }
376
377  SmallVector<Expr *, 5> CallArgs;
378  const FunctionProtoType *CallbackFunctionType;
379  if (isLambdaCall) {
380
381    // Lambda requires callback itself inserted as a first parameter.
382    CallArgs.push_back(
383        M.makeDeclRefExpr(Callback,
384                          /* RefersToEnclosingVariableOrCapture=*/ true));
385    CallbackFunctionType = CallbackRecordDecl->getLambdaCallOperator()
386                               ->getType()
387                               ->getAs<FunctionProtoType>();
388  } else if (!CallbackType->getPointeeType().isNull()) {
389    CallbackFunctionType =
390        CallbackType->getPointeeType()->getAs<FunctionProtoType>();
391  } else {
392    CallbackFunctionType = CallbackType->getAs<FunctionProtoType>();
393  }
394
395  if (!CallbackFunctionType)
396    return nullptr;
397
398  // First two arguments are used for the flag and for the callback.
399  if (D->getNumParams() != CallbackFunctionType->getNumParams() + 2) {
400    LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
401                            << "params passed to std::call_once, "
402                            << "ignoring the call\n");
403    return nullptr;
404  }
405
406  // All arguments past first two ones are passed to the callback,
407  // and we turn lvalues into rvalues if the argument is not passed by
408  // reference.
409  for (unsigned int ParamIdx = 2; ParamIdx < D->getNumParams(); ParamIdx++) {
410    const ParmVarDecl *PDecl = D->getParamDecl(ParamIdx);
411    assert(PDecl);
412    if (CallbackFunctionType->getParamType(ParamIdx - 2)
413                .getNonReferenceType()
414                .getCanonicalType() !=
415            PDecl->getType().getNonReferenceType().getCanonicalType()) {
416      LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
417                              << "params passed to std::call_once, "
418                              << "ignoring the call\n");
419      return nullptr;
420    }
421    Expr *ParamExpr = M.makeDeclRefExpr(PDecl);
422    if (!CallbackFunctionType->getParamType(ParamIdx - 2)->isReferenceType()) {
423      QualType PTy = PDecl->getType().getNonReferenceType();
424      ParamExpr = M.makeLvalueToRvalue(ParamExpr, PTy);
425    }
426    CallArgs.push_back(ParamExpr);
427  }
428
429  CallExpr *CallbackCall;
430  if (isLambdaCall) {
431
432    CallbackCall = create_call_once_lambda_call(C, M, Callback,
433                                                CallbackRecordDecl, CallArgs);
434  } else {
435
436    // Function pointer case.
437    CallbackCall = create_call_once_funcptr_call(C, M, Callback, CallArgs);
438  }
439
440  DeclRefExpr *FlagDecl =
441      M.makeDeclRefExpr(Flag,
442                        /* RefersToEnclosingVariableOrCapture=*/true);
443
444
445  MemberExpr *Deref = M.makeMemberExpression(FlagDecl, FlagFieldDecl);
446  assert(Deref->isLValue());
447  QualType DerefType = Deref->getType();
448
449  // Negation predicate.
450  UnaryOperator *FlagCheck = new (C) UnaryOperator(
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);
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      new (C) UnaryOperator(M.makeIntegerLiteral(0, C.LongTy), UO_Not, C.LongTy,
522                            VK_RValue, OK_Ordinary, SourceLocation(),
523                            /*CanOverflow*/false);
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() & ObjCPropertyDecl::OBJC_PR_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