1 //== BodyFarm.cpp - Factory for conjuring up fake bodies ----------*- C++ -*-// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // BodyFarm is a factory for creating faux implementations for functions/methods 10 // for analysis purposes. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Analysis/BodyFarm.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/CXXInheritance.h" 17 #include "clang/AST/Decl.h" 18 #include "clang/AST/Expr.h" 19 #include "clang/AST/ExprCXX.h" 20 #include "clang/AST/ExprObjC.h" 21 #include "clang/AST/NestedNameSpecifier.h" 22 #include "clang/Analysis/CodeInjector.h" 23 #include "clang/Basic/OperatorKinds.h" 24 #include "llvm/ADT/StringSwitch.h" 25 #include "llvm/Support/Debug.h" 26 27 #define DEBUG_TYPE "body-farm" 28 29 using namespace clang; 30 31 //===----------------------------------------------------------------------===// 32 // Helper creation functions for constructing faux ASTs. 33 //===----------------------------------------------------------------------===// 34 35 static bool isDispatchBlock(QualType Ty) { 36 // Is it a block pointer? 37 const BlockPointerType *BPT = Ty->getAs<BlockPointerType>(); 38 if (!BPT) 39 return false; 40 41 // Check if the block pointer type takes no arguments and 42 // returns void. 43 const FunctionProtoType *FT = 44 BPT->getPointeeType()->getAs<FunctionProtoType>(); 45 return FT && FT->getReturnType()->isVoidType() && FT->getNumParams() == 0; 46 } 47 48 namespace { 49 class ASTMaker { 50 public: 51 ASTMaker(ASTContext &C) : C(C) {} 52 53 /// Create a new BinaryOperator representing a simple assignment. 54 BinaryOperator *makeAssignment(const Expr *LHS, const Expr *RHS, QualType Ty); 55 56 /// Create a new BinaryOperator representing a comparison. 57 BinaryOperator *makeComparison(const Expr *LHS, const Expr *RHS, 58 BinaryOperator::Opcode Op); 59 60 /// Create a new compound stmt using the provided statements. 61 CompoundStmt *makeCompound(ArrayRef<Stmt*>); 62 63 /// Create a new DeclRefExpr for the referenced variable. 64 DeclRefExpr *makeDeclRefExpr(const VarDecl *D, 65 bool RefersToEnclosingVariableOrCapture = false); 66 67 /// Create a new UnaryOperator representing a dereference. 68 UnaryOperator *makeDereference(const Expr *Arg, QualType Ty); 69 70 /// Create an implicit cast for an integer conversion. 71 Expr *makeIntegralCast(const Expr *Arg, QualType Ty); 72 73 /// Create an implicit cast to a builtin boolean type. 74 ImplicitCastExpr *makeIntegralCastToBoolean(const Expr *Arg); 75 76 /// Create an implicit cast for lvalue-to-rvaluate conversions. 77 ImplicitCastExpr *makeLvalueToRvalue(const Expr *Arg, QualType Ty); 78 79 /// Make RValue out of variable declaration, creating a temporary 80 /// DeclRefExpr in the process. 81 ImplicitCastExpr * 82 makeLvalueToRvalue(const VarDecl *Decl, 83 bool RefersToEnclosingVariableOrCapture = false); 84 85 /// Create an implicit cast of the given type. 86 ImplicitCastExpr *makeImplicitCast(const Expr *Arg, QualType Ty, 87 CastKind CK = CK_LValueToRValue); 88 89 /// Create an Objective-C bool literal. 90 ObjCBoolLiteralExpr *makeObjCBool(bool Val); 91 92 /// Create an Objective-C ivar reference. 93 ObjCIvarRefExpr *makeObjCIvarRef(const Expr *Base, const ObjCIvarDecl *IVar); 94 95 /// Create a Return statement. 96 ReturnStmt *makeReturn(const Expr *RetVal); 97 98 /// Create an integer literal expression of the given type. 99 IntegerLiteral *makeIntegerLiteral(uint64_t Value, QualType Ty); 100 101 /// Create a member expression. 102 MemberExpr *makeMemberExpression(Expr *base, ValueDecl *MemberDecl, 103 bool IsArrow = false, 104 ExprValueKind ValueKind = VK_LValue); 105 106 /// Returns a *first* member field of a record declaration with a given name. 107 /// \return an nullptr if no member with such a name exists. 108 ValueDecl *findMemberField(const RecordDecl *RD, StringRef Name); 109 110 private: 111 ASTContext &C; 112 }; 113 } 114 115 BinaryOperator *ASTMaker::makeAssignment(const Expr *LHS, const Expr *RHS, 116 QualType Ty) { 117 return BinaryOperator::Create( 118 C, const_cast<Expr *>(LHS), const_cast<Expr *>(RHS), BO_Assign, Ty, 119 VK_RValue, OK_Ordinary, SourceLocation(), FPOptionsOverride()); 120 } 121 122 BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS, 123 BinaryOperator::Opcode Op) { 124 assert(BinaryOperator::isLogicalOp(Op) || 125 BinaryOperator::isComparisonOp(Op)); 126 return BinaryOperator::Create( 127 C, const_cast<Expr *>(LHS), const_cast<Expr *>(RHS), Op, 128 C.getLogicalOperationType(), VK_RValue, OK_Ordinary, SourceLocation(), 129 FPOptionsOverride()); 130 } 131 132 CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) { 133 return CompoundStmt::Create(C, Stmts, SourceLocation(), SourceLocation()); 134 } 135 136 DeclRefExpr *ASTMaker::makeDeclRefExpr( 137 const VarDecl *D, 138 bool RefersToEnclosingVariableOrCapture) { 139 QualType Type = D->getType().getNonReferenceType(); 140 141 DeclRefExpr *DR = DeclRefExpr::Create( 142 C, NestedNameSpecifierLoc(), SourceLocation(), const_cast<VarDecl *>(D), 143 RefersToEnclosingVariableOrCapture, SourceLocation(), Type, VK_LValue); 144 return DR; 145 } 146 147 UnaryOperator *ASTMaker::makeDereference(const Expr *Arg, QualType Ty) { 148 return UnaryOperator::Create(C, const_cast<Expr *>(Arg), UO_Deref, Ty, 149 VK_LValue, OK_Ordinary, SourceLocation(), 150 /*CanOverflow*/ false, FPOptionsOverride()); 151 } 152 153 ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) { 154 return makeImplicitCast(Arg, Ty, CK_LValueToRValue); 155 } 156 157 ImplicitCastExpr * 158 ASTMaker::makeLvalueToRvalue(const VarDecl *Arg, 159 bool RefersToEnclosingVariableOrCapture) { 160 QualType Type = Arg->getType().getNonReferenceType(); 161 return makeLvalueToRvalue(makeDeclRefExpr(Arg, 162 RefersToEnclosingVariableOrCapture), 163 Type); 164 } 165 166 ImplicitCastExpr *ASTMaker::makeImplicitCast(const Expr *Arg, QualType Ty, 167 CastKind CK) { 168 return ImplicitCastExpr::Create(C, Ty, 169 /* CastKind=*/ CK, 170 /* Expr=*/ const_cast<Expr *>(Arg), 171 /* CXXCastPath=*/ nullptr, 172 /* ExprValueKind=*/ VK_RValue); 173 } 174 175 Expr *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 183 ImplicitCastExpr *ASTMaker::makeIntegralCastToBoolean(const Expr *Arg) { 184 return ImplicitCastExpr::Create(C, C.BoolTy, CK_IntegralToBoolean, 185 const_cast<Expr*>(Arg), nullptr, VK_RValue); 186 } 187 188 ObjCBoolLiteralExpr *ASTMaker::makeObjCBool(bool Val) { 189 QualType Ty = C.getBOOLDecl() ? C.getBOOLType() : C.ObjCBuiltinBoolTy; 190 return new (C) ObjCBoolLiteralExpr(Val, Ty, SourceLocation()); 191 } 192 193 ObjCIvarRefExpr *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 201 ReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) { 202 return ReturnStmt::Create(C, SourceLocation(), const_cast<Expr *>(RetVal), 203 /* NRVOCandidate=*/nullptr); 204 } 205 206 IntegerLiteral *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 211 MemberExpr *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 224 ValueDecl *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 245 typedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D); 246 247 static 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 273 static 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 316 static 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. 477 static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) { 478 // Check if we have at least two parameters. 479 if (D->param_size() != 2) 480 return nullptr; 481 482 // Check if the first parameter is a pointer to integer type. 483 const ParmVarDecl *Predicate = D->getParamDecl(0); 484 QualType PredicateQPtrTy = Predicate->getType(); 485 const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>(); 486 if (!PredicatePtrTy) 487 return nullptr; 488 QualType PredicateTy = PredicatePtrTy->getPointeeType(); 489 if (!PredicateTy->isIntegerType()) 490 return nullptr; 491 492 // Check if the second parameter is the proper block type. 493 const ParmVarDecl *Block = D->getParamDecl(1); 494 QualType Ty = Block->getType(); 495 if (!isDispatchBlock(Ty)) 496 return nullptr; 497 498 // Everything checks out. Create a fakse body that checks the predicate, 499 // sets it, and calls the block. Basically, an AST dump of: 500 // 501 // void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) { 502 // if (*predicate != ~0l) { 503 // *predicate = ~0l; 504 // block(); 505 // } 506 // } 507 508 ASTMaker M(C); 509 510 // (1) Create the call. 511 CallExpr *CE = CallExpr::Create( 512 /*ASTContext=*/C, 513 /*StmtClass=*/M.makeLvalueToRvalue(/*Expr=*/Block), 514 /*Args=*/None, 515 /*QualType=*/C.VoidTy, 516 /*ExprValueType=*/VK_RValue, 517 /*SourceLocation=*/SourceLocation()); 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. 560 static 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 586 static 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 667 Stmt *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 700 static 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 739 static 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 819 Stmt *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