BodyFarm.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  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. #include "BodyFarm.h"
  15. #include "clang/AST/ASTContext.h"
  16. #include "clang/AST/Decl.h"
  17. #include "clang/AST/Expr.h"
  18. #include "clang/AST/ExprObjC.h"
  19. #include "clang/Analysis/CodeInjector.h"
  20. #include "llvm/ADT/StringSwitch.h"
  21. using namespace clang;
  22. //===----------------------------------------------------------------------===//
  23. // Helper creation functions for constructing faux ASTs.
  24. //===----------------------------------------------------------------------===//
  25. static bool isDispatchBlock(QualType Ty) {
  26. // Is it a block pointer?
  27. const BlockPointerType *BPT = Ty->getAs<BlockPointerType>();
  28. if (!BPT)
  29. return false;
  30. // Check if the block pointer type takes no arguments and
  31. // returns void.
  32. const FunctionProtoType *FT =
  33. BPT->getPointeeType()->getAs<FunctionProtoType>();
  34. if (!FT || !FT->getReturnType()->isVoidType() || FT->getNumParams() != 0)
  35. return false;
  36. return true;
  37. }
  38. namespace {
  39. class ASTMaker {
  40. public:
  41. ASTMaker(ASTContext &C) : C(C) {}
  42. /// Create a new BinaryOperator representing a simple assignment.
  43. BinaryOperator *makeAssignment(const Expr *LHS, const Expr *RHS, QualType Ty);
  44. /// Create a new BinaryOperator representing a comparison.
  45. BinaryOperator *makeComparison(const Expr *LHS, const Expr *RHS,
  46. BinaryOperator::Opcode Op);
  47. /// Create a new compound stmt using the provided statements.
  48. CompoundStmt *makeCompound(ArrayRef<Stmt*>);
  49. /// Create a new DeclRefExpr for the referenced variable.
  50. DeclRefExpr *makeDeclRefExpr(const VarDecl *D);
  51. /// Create a new UnaryOperator representing a dereference.
  52. UnaryOperator *makeDereference(const Expr *Arg, QualType Ty);
  53. /// Create an implicit cast for an integer conversion.
  54. Expr *makeIntegralCast(const Expr *Arg, QualType Ty);
  55. /// Create an implicit cast to a builtin boolean type.
  56. ImplicitCastExpr *makeIntegralCastToBoolean(const Expr *Arg);
  57. // Create an implicit cast for lvalue-to-rvaluate conversions.
  58. ImplicitCastExpr *makeLvalueToRvalue(const Expr *Arg, QualType Ty);
  59. /// Create an Objective-C bool literal.
  60. ObjCBoolLiteralExpr *makeObjCBool(bool Val);
  61. /// Create an Objective-C ivar reference.
  62. ObjCIvarRefExpr *makeObjCIvarRef(const Expr *Base, const ObjCIvarDecl *IVar);
  63. /// Create a Return statement.
  64. ReturnStmt *makeReturn(const Expr *RetVal);
  65. private:
  66. ASTContext &C;
  67. };
  68. }
  69. BinaryOperator *ASTMaker::makeAssignment(const Expr *LHS, const Expr *RHS,
  70. QualType Ty) {
  71. return new (C) BinaryOperator(const_cast<Expr*>(LHS), const_cast<Expr*>(RHS),
  72. BO_Assign, Ty, VK_RValue,
  73. OK_Ordinary, SourceLocation(), false);
  74. }
  75. BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS,
  76. BinaryOperator::Opcode Op) {
  77. assert(BinaryOperator::isLogicalOp(Op) ||
  78. BinaryOperator::isComparisonOp(Op));
  79. return new (C) BinaryOperator(const_cast<Expr*>(LHS),
  80. const_cast<Expr*>(RHS),
  81. Op,
  82. C.getLogicalOperationType(),
  83. VK_RValue,
  84. OK_Ordinary, SourceLocation(), false);
  85. }
  86. CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
  87. return new (C) CompoundStmt(C, Stmts, SourceLocation(), SourceLocation());
  88. }
  89. DeclRefExpr *ASTMaker::makeDeclRefExpr(const VarDecl *D) {
  90. DeclRefExpr *DR =
  91. DeclRefExpr::Create(/* Ctx = */ C,
  92. /* QualifierLoc = */ NestedNameSpecifierLoc(),
  93. /* TemplateKWLoc = */ SourceLocation(),
  94. /* D = */ const_cast<VarDecl*>(D),
  95. /* RefersToEnclosingVariableOrCapture = */ false,
  96. /* NameLoc = */ SourceLocation(),
  97. /* T = */ D->getType(),
  98. /* VK = */ VK_LValue);
  99. return DR;
  100. }
  101. UnaryOperator *ASTMaker::makeDereference(const Expr *Arg, QualType Ty) {
  102. return new (C) UnaryOperator(const_cast<Expr*>(Arg), UO_Deref, Ty,
  103. VK_LValue, OK_Ordinary, SourceLocation());
  104. }
  105. ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) {
  106. return ImplicitCastExpr::Create(C, Ty, CK_LValueToRValue,
  107. const_cast<Expr*>(Arg), nullptr, VK_RValue);
  108. }
  109. Expr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
  110. if (Arg->getType() == Ty)
  111. return const_cast<Expr*>(Arg);
  112. return ImplicitCastExpr::Create(C, Ty, CK_IntegralCast,
  113. const_cast<Expr*>(Arg), nullptr, VK_RValue);
  114. }
  115. ImplicitCastExpr *ASTMaker::makeIntegralCastToBoolean(const Expr *Arg) {
  116. return ImplicitCastExpr::Create(C, C.BoolTy, CK_IntegralToBoolean,
  117. const_cast<Expr*>(Arg), nullptr, VK_RValue);
  118. }
  119. ObjCBoolLiteralExpr *ASTMaker::makeObjCBool(bool Val) {
  120. QualType Ty = C.getBOOLDecl() ? C.getBOOLType() : C.ObjCBuiltinBoolTy;
  121. return new (C) ObjCBoolLiteralExpr(Val, Ty, SourceLocation());
  122. }
  123. ObjCIvarRefExpr *ASTMaker::makeObjCIvarRef(const Expr *Base,
  124. const ObjCIvarDecl *IVar) {
  125. return new (C) ObjCIvarRefExpr(const_cast<ObjCIvarDecl*>(IVar),
  126. IVar->getType(), SourceLocation(),
  127. SourceLocation(), const_cast<Expr*>(Base),
  128. /*arrow=*/true, /*free=*/false);
  129. }
  130. ReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) {
  131. return new (C) ReturnStmt(SourceLocation(), const_cast<Expr*>(RetVal),
  132. nullptr);
  133. }
  134. //===----------------------------------------------------------------------===//
  135. // Creation functions for faux ASTs.
  136. //===----------------------------------------------------------------------===//
  137. typedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D);
  138. /// Create a fake body for dispatch_once.
  139. static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
  140. // Check if we have at least two parameters.
  141. if (D->param_size() != 2)
  142. return nullptr;
  143. // Check if the first parameter is a pointer to integer type.
  144. const ParmVarDecl *Predicate = D->getParamDecl(0);
  145. QualType PredicateQPtrTy = Predicate->getType();
  146. const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>();
  147. if (!PredicatePtrTy)
  148. return nullptr;
  149. QualType PredicateTy = PredicatePtrTy->getPointeeType();
  150. if (!PredicateTy->isIntegerType())
  151. return nullptr;
  152. // Check if the second parameter is the proper block type.
  153. const ParmVarDecl *Block = D->getParamDecl(1);
  154. QualType Ty = Block->getType();
  155. if (!isDispatchBlock(Ty))
  156. return nullptr;
  157. // Everything checks out. Create a fakse body that checks the predicate,
  158. // sets it, and calls the block. Basically, an AST dump of:
  159. //
  160. // void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
  161. // if (!*predicate) {
  162. // *predicate = 1;
  163. // block();
  164. // }
  165. // }
  166. ASTMaker M(C);
  167. // (1) Create the call.
  168. DeclRefExpr *DR = M.makeDeclRefExpr(Block);
  169. ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
  170. CallExpr *CE = new (C) CallExpr(C, ICE, None, C.VoidTy, VK_RValue,
  171. SourceLocation());
  172. // (2) Create the assignment to the predicate.
  173. IntegerLiteral *IL =
  174. IntegerLiteral::Create(C, llvm::APInt(C.getTypeSize(C.IntTy), (uint64_t) 1),
  175. C.IntTy, SourceLocation());
  176. BinaryOperator *B =
  177. M.makeAssignment(
  178. M.makeDereference(
  179. M.makeLvalueToRvalue(
  180. M.makeDeclRefExpr(Predicate), PredicateQPtrTy),
  181. PredicateTy),
  182. M.makeIntegralCast(IL, PredicateTy),
  183. PredicateTy);
  184. // (3) Create the compound statement.
  185. Stmt *Stmts[] = { B, CE };
  186. CompoundStmt *CS = M.makeCompound(Stmts);
  187. // (4) Create the 'if' condition.
  188. ImplicitCastExpr *LValToRval =
  189. M.makeLvalueToRvalue(
  190. M.makeDereference(
  191. M.makeLvalueToRvalue(
  192. M.makeDeclRefExpr(Predicate),
  193. PredicateQPtrTy),
  194. PredicateTy),
  195. PredicateTy);
  196. UnaryOperator *UO = new (C) UnaryOperator(LValToRval, UO_LNot, C.IntTy,
  197. VK_RValue, OK_Ordinary,
  198. SourceLocation());
  199. // (5) Create the 'if' statement.
  200. IfStmt *If = new (C) IfStmt(C, SourceLocation(), nullptr, UO, CS);
  201. return If;
  202. }
  203. /// Create a fake body for dispatch_sync.
  204. static Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) {
  205. // Check if we have at least two parameters.
  206. if (D->param_size() != 2)
  207. return nullptr;
  208. // Check if the second parameter is a block.
  209. const ParmVarDecl *PV = D->getParamDecl(1);
  210. QualType Ty = PV->getType();
  211. if (!isDispatchBlock(Ty))
  212. return nullptr;
  213. // Everything checks out. Create a fake body that just calls the block.
  214. // This is basically just an AST dump of:
  215. //
  216. // void dispatch_sync(dispatch_queue_t queue, void (^block)(void)) {
  217. // block();
  218. // }
  219. //
  220. ASTMaker M(C);
  221. DeclRefExpr *DR = M.makeDeclRefExpr(PV);
  222. ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
  223. CallExpr *CE = new (C) CallExpr(C, ICE, None, C.VoidTy, VK_RValue,
  224. SourceLocation());
  225. return CE;
  226. }
  227. static Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D)
  228. {
  229. // There are exactly 3 arguments.
  230. if (D->param_size() != 3)
  231. return nullptr;
  232. // Signature:
  233. // _Bool OSAtomicCompareAndSwapPtr(void *__oldValue,
  234. // void *__newValue,
  235. // void * volatile *__theValue)
  236. // Generate body:
  237. // if (oldValue == *theValue) {
  238. // *theValue = newValue;
  239. // return YES;
  240. // }
  241. // else return NO;
  242. QualType ResultTy = D->getReturnType();
  243. bool isBoolean = ResultTy->isBooleanType();
  244. if (!isBoolean && !ResultTy->isIntegralType(C))
  245. return nullptr;
  246. const ParmVarDecl *OldValue = D->getParamDecl(0);
  247. QualType OldValueTy = OldValue->getType();
  248. const ParmVarDecl *NewValue = D->getParamDecl(1);
  249. QualType NewValueTy = NewValue->getType();
  250. assert(OldValueTy == NewValueTy);
  251. const ParmVarDecl *TheValue = D->getParamDecl(2);
  252. QualType TheValueTy = TheValue->getType();
  253. const PointerType *PT = TheValueTy->getAs<PointerType>();
  254. if (!PT)
  255. return nullptr;
  256. QualType PointeeTy = PT->getPointeeType();
  257. ASTMaker M(C);
  258. // Construct the comparison.
  259. Expr *Comparison =
  260. M.makeComparison(
  261. M.makeLvalueToRvalue(M.makeDeclRefExpr(OldValue), OldValueTy),
  262. M.makeLvalueToRvalue(
  263. M.makeDereference(
  264. M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
  265. PointeeTy),
  266. PointeeTy),
  267. BO_EQ);
  268. // Construct the body of the IfStmt.
  269. Stmt *Stmts[2];
  270. Stmts[0] =
  271. M.makeAssignment(
  272. M.makeDereference(
  273. M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
  274. PointeeTy),
  275. M.makeLvalueToRvalue(M.makeDeclRefExpr(NewValue), NewValueTy),
  276. NewValueTy);
  277. Expr *BoolVal = M.makeObjCBool(true);
  278. Expr *RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
  279. : M.makeIntegralCast(BoolVal, ResultTy);
  280. Stmts[1] = M.makeReturn(RetVal);
  281. CompoundStmt *Body = M.makeCompound(Stmts);
  282. // Construct the else clause.
  283. BoolVal = M.makeObjCBool(false);
  284. RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
  285. : M.makeIntegralCast(BoolVal, ResultTy);
  286. Stmt *Else = M.makeReturn(RetVal);
  287. /// Construct the If.
  288. Stmt *If =
  289. new (C) IfStmt(C, SourceLocation(), nullptr, Comparison, Body,
  290. SourceLocation(), Else);
  291. return If;
  292. }
  293. Stmt *BodyFarm::getBody(const FunctionDecl *D) {
  294. D = D->getCanonicalDecl();
  295. Optional<Stmt *> &Val = Bodies[D];
  296. if (Val.hasValue())
  297. return Val.getValue();
  298. Val = nullptr;
  299. if (D->getIdentifier() == nullptr)
  300. return nullptr;
  301. StringRef Name = D->getName();
  302. if (Name.empty())
  303. return nullptr;
  304. FunctionFarmer FF;
  305. if (Name.startswith("OSAtomicCompareAndSwap") ||
  306. Name.startswith("objc_atomicCompareAndSwap")) {
  307. FF = create_OSAtomicCompareAndSwap;
  308. }
  309. else {
  310. FF = llvm::StringSwitch<FunctionFarmer>(Name)
  311. .Case("dispatch_sync", create_dispatch_sync)
  312. .Case("dispatch_once", create_dispatch_once)
  313. .Default(nullptr);
  314. }
  315. if (FF) { Val = FF(C, D); }
  316. else if (Injector) { Val = Injector->getBody(D); }
  317. return Val.getValue();
  318. }
  319. static Stmt *createObjCPropertyGetter(ASTContext &Ctx,
  320. const ObjCPropertyDecl *Prop) {
  321. // First, find the backing ivar.
  322. const ObjCIvarDecl *IVar = Prop->getPropertyIvarDecl();
  323. if (!IVar)
  324. return nullptr;
  325. // Ignore weak variables, which have special behavior.
  326. if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
  327. return nullptr;
  328. // Look to see if Sema has synthesized a body for us. This happens in
  329. // Objective-C++ because the return value may be a C++ class type with a
  330. // non-trivial copy constructor. We can only do this if we can find the
  331. // @synthesize for this property, though (or if we know it's been auto-
  332. // synthesized).
  333. const ObjCImplementationDecl *ImplDecl =
  334. IVar->getContainingInterface()->getImplementation();
  335. if (ImplDecl) {
  336. for (const auto *I : ImplDecl->property_impls()) {
  337. if (I->getPropertyDecl() != Prop)
  338. continue;
  339. if (I->getGetterCXXConstructor()) {
  340. ASTMaker M(Ctx);
  341. return M.makeReturn(I->getGetterCXXConstructor());
  342. }
  343. }
  344. }
  345. // Sanity check that the property is the same type as the ivar, or a
  346. // reference to it, and that it is either an object pointer or trivially
  347. // copyable.
  348. if (!Ctx.hasSameUnqualifiedType(IVar->getType(),
  349. Prop->getType().getNonReferenceType()))
  350. return nullptr;
  351. if (!IVar->getType()->isObjCLifetimeType() &&
  352. !IVar->getType().isTriviallyCopyableType(Ctx))
  353. return nullptr;
  354. // Generate our body:
  355. // return self->_ivar;
  356. ASTMaker M(Ctx);
  357. const VarDecl *selfVar = Prop->getGetterMethodDecl()->getSelfDecl();
  358. Expr *loadedIVar =
  359. M.makeObjCIvarRef(
  360. M.makeLvalueToRvalue(
  361. M.makeDeclRefExpr(selfVar),
  362. selfVar->getType()),
  363. IVar);
  364. if (!Prop->getType()->isReferenceType())
  365. loadedIVar = M.makeLvalueToRvalue(loadedIVar, IVar->getType());
  366. return M.makeReturn(loadedIVar);
  367. }
  368. Stmt *BodyFarm::getBody(const ObjCMethodDecl *D) {
  369. // We currently only know how to synthesize property accessors.
  370. if (!D->isPropertyAccessor())
  371. return nullptr;
  372. D = D->getCanonicalDecl();
  373. Optional<Stmt *> &Val = Bodies[D];
  374. if (Val.hasValue())
  375. return Val.getValue();
  376. Val = nullptr;
  377. const ObjCPropertyDecl *Prop = D->findPropertyDecl();
  378. if (!Prop)
  379. return nullptr;
  380. // For now, we only synthesize getters.
  381. if (D->param_size() != 0)
  382. return nullptr;
  383. Val = createObjCPropertyGetter(C, Prop);
  384. return Val.getValue();
  385. }