1 //===- ThreadSafetyCommon.cpp ---------------------------------------------===// 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 // Implementation of the interfaces declared in ThreadSafetyCommon.h 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/Analysis/Analyses/ThreadSafetyCommon.h" 14 #include "clang/AST/Attr.h" 15 #include "clang/AST/Decl.h" 16 #include "clang/AST/DeclCXX.h" 17 #include "clang/AST/DeclGroup.h" 18 #include "clang/AST/DeclObjC.h" 19 #include "clang/AST/Expr.h" 20 #include "clang/AST/ExprCXX.h" 21 #include "clang/AST/OperationKinds.h" 22 #include "clang/AST/Stmt.h" 23 #include "clang/AST/Type.h" 24 #include "clang/Analysis/Analyses/ThreadSafetyTIL.h" 25 #include "clang/Analysis/CFG.h" 26 #include "clang/Basic/LLVM.h" 27 #include "clang/Basic/OperatorKinds.h" 28 #include "clang/Basic/Specifiers.h" 29 #include "llvm/ADT/StringExtras.h" 30 #include "llvm/ADT/StringRef.h" 31 #include "llvm/Support/Casting.h" 32 #include <algorithm> 33 #include <cassert> 34 #include <string> 35 #include <utility> 36 37 using namespace clang; 38 using namespace threadSafety; 39 40 // From ThreadSafetyUtil.h 41 std::string threadSafety::getSourceLiteralString(const Expr *CE) { 42 switch (CE->getStmtClass()) { 43 case Stmt::IntegerLiteralClass: 44 return toString(cast<IntegerLiteral>(CE)->getValue(), 10, true); 45 case Stmt::StringLiteralClass: { 46 std::string ret("\""); 47 ret += cast<StringLiteral>(CE)->getString(); 48 ret += "\""; 49 return ret; 50 } 51 case Stmt::CharacterLiteralClass: 52 case Stmt::CXXNullPtrLiteralExprClass: 53 case Stmt::GNUNullExprClass: 54 case Stmt::CXXBoolLiteralExprClass: 55 case Stmt::FloatingLiteralClass: 56 case Stmt::ImaginaryLiteralClass: 57 case Stmt::ObjCStringLiteralClass: 58 default: 59 return "#lit"; 60 } 61 } 62 63 // Return true if E is a variable that points to an incomplete Phi node. 64 static bool isIncompletePhi(const til::SExpr *E) { 65 if (const auto *Ph = dyn_cast<til::Phi>(E)) 66 return Ph->status() == til::Phi::PH_Incomplete; 67 return false; 68 } 69 70 using CallingContext = SExprBuilder::CallingContext; 71 72 til::SExpr *SExprBuilder::lookupStmt(const Stmt *S) { return SMap.lookup(S); } 73 74 til::SCFG *SExprBuilder::buildCFG(CFGWalker &Walker) { 75 Walker.walk(*this); 76 return Scfg; 77 } 78 79 static bool isCalleeArrow(const Expr *E) { 80 const auto *ME = dyn_cast<MemberExpr>(E->IgnoreParenCasts()); 81 return ME ? ME->isArrow() : false; 82 } 83 84 static StringRef ClassifyDiagnostic(const CapabilityAttr *A) { 85 return A->getName(); 86 } 87 88 static StringRef ClassifyDiagnostic(QualType VDT) { 89 // We need to look at the declaration of the type of the value to determine 90 // which it is. The type should either be a record or a typedef, or a pointer 91 // or reference thereof. 92 if (const auto *RT = VDT->getAs<RecordType>()) { 93 if (const auto *RD = RT->getDecl()) 94 if (const auto *CA = RD->getAttr<CapabilityAttr>()) 95 return ClassifyDiagnostic(CA); 96 } else if (const auto *TT = VDT->getAs<TypedefType>()) { 97 if (const auto *TD = TT->getDecl()) 98 if (const auto *CA = TD->getAttr<CapabilityAttr>()) 99 return ClassifyDiagnostic(CA); 100 } else if (VDT->isPointerOrReferenceType()) 101 return ClassifyDiagnostic(VDT->getPointeeType()); 102 103 return "mutex"; 104 } 105 106 /// Translate a clang expression in an attribute to a til::SExpr. 107 /// Constructs the context from D, DeclExp, and SelfDecl. 108 /// 109 /// \param AttrExp The expression to translate. 110 /// \param D The declaration to which the attribute is attached. 111 /// \param DeclExp An expression involving the Decl to which the attribute 112 /// is attached. E.g. the call to a function. 113 /// \param Self S-expression to substitute for a \ref CXXThisExpr in a call, 114 /// or argument to a cleanup function. 115 CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, 116 const NamedDecl *D, 117 const Expr *DeclExp, 118 til::SExpr *Self) { 119 // If we are processing a raw attribute expression, with no substitutions. 120 if (!DeclExp && !Self) 121 return translateAttrExpr(AttrExp, nullptr); 122 123 CallingContext Ctx(nullptr, D); 124 125 // Examine DeclExp to find SelfArg and FunArgs, which are used to substitute 126 // for formal parameters when we call buildMutexID later. 127 if (!DeclExp) 128 /* We'll use Self. */; 129 else if (const auto *ME = dyn_cast<MemberExpr>(DeclExp)) { 130 Ctx.SelfArg = ME->getBase(); 131 Ctx.SelfArrow = ME->isArrow(); 132 } else if (const auto *CE = dyn_cast<CXXMemberCallExpr>(DeclExp)) { 133 Ctx.SelfArg = CE->getImplicitObjectArgument(); 134 Ctx.SelfArrow = isCalleeArrow(CE->getCallee()); 135 Ctx.NumArgs = CE->getNumArgs(); 136 Ctx.FunArgs = CE->getArgs(); 137 } else if (const auto *CE = dyn_cast<CallExpr>(DeclExp)) { 138 // Calls to operators that are members need to be treated like member calls. 139 if (isa<CXXOperatorCallExpr>(CE) && isa<CXXMethodDecl>(D)) { 140 Ctx.SelfArg = CE->getArg(0); 141 Ctx.SelfArrow = false; 142 Ctx.NumArgs = CE->getNumArgs() - 1; 143 Ctx.FunArgs = CE->getArgs() + 1; 144 } else { 145 Ctx.NumArgs = CE->getNumArgs(); 146 Ctx.FunArgs = CE->getArgs(); 147 } 148 } else if (const auto *CE = dyn_cast<CXXConstructExpr>(DeclExp)) { 149 Ctx.SelfArg = nullptr; // Will be set below 150 Ctx.NumArgs = CE->getNumArgs(); 151 Ctx.FunArgs = CE->getArgs(); 152 } 153 154 // Usually we want to substitute the self-argument for "this", but lambdas 155 // are an exception: "this" on or in a lambda call operator doesn't refer 156 // to the lambda, but to captured "this" in the context it was created in. 157 // This can happen for operator calls and member calls, so fix it up here. 158 if (const auto *CMD = dyn_cast<CXXMethodDecl>(D)) 159 if (CMD->getParent()->isLambda()) 160 Ctx.SelfArg = nullptr; 161 162 if (Self) { 163 assert(!Ctx.SelfArg && "Ambiguous self argument"); 164 assert(isa<FunctionDecl>(D) && "Self argument requires function"); 165 if (isa<CXXMethodDecl>(D)) 166 Ctx.SelfArg = Self; 167 else 168 Ctx.FunArgs = Self; 169 170 // If the attribute has no arguments, then assume the argument is "this". 171 if (!AttrExp) 172 return CapabilityExpr( 173 Self, 174 ClassifyDiagnostic( 175 cast<CXXMethodDecl>(D)->getFunctionObjectParameterType()), 176 false); 177 else // For most attributes. 178 return translateAttrExpr(AttrExp, &Ctx); 179 } 180 181 // If the attribute has no arguments, then assume the argument is "this". 182 if (!AttrExp) 183 return translateAttrExpr(cast<const Expr *>(Ctx.SelfArg), nullptr); 184 else // For most attributes. 185 return translateAttrExpr(AttrExp, &Ctx); 186 } 187 188 /// Translate a clang expression in an attribute to a til::SExpr. 189 // This assumes a CallingContext has already been created. 190 CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, 191 CallingContext *Ctx) { 192 if (!AttrExp) 193 return CapabilityExpr(); 194 195 if (const auto* SLit = dyn_cast<StringLiteral>(AttrExp)) { 196 if (SLit->getString() == "*") 197 // The "*" expr is a universal lock, which essentially turns off 198 // checks until it is removed from the lockset. 199 return CapabilityExpr(new (Arena) til::Wildcard(), StringRef("wildcard"), 200 false); 201 else 202 // Ignore other string literals for now. 203 return CapabilityExpr(); 204 } 205 206 bool Neg = false; 207 if (const auto *OE = dyn_cast<CXXOperatorCallExpr>(AttrExp)) { 208 if (OE->getOperator() == OO_Exclaim) { 209 Neg = true; 210 AttrExp = OE->getArg(0); 211 } 212 } 213 else if (const auto *UO = dyn_cast<UnaryOperator>(AttrExp)) { 214 if (UO->getOpcode() == UO_LNot) { 215 Neg = true; 216 AttrExp = UO->getSubExpr()->IgnoreImplicit(); 217 } 218 } 219 220 til::SExpr *E = translate(AttrExp, Ctx); 221 222 // Trap mutex expressions like nullptr, or 0. 223 // Any literal value is nonsense. 224 if (!E || isa<til::Literal>(E)) 225 return CapabilityExpr(); 226 227 StringRef Kind = ClassifyDiagnostic(AttrExp->getType()); 228 229 // Hack to deal with smart pointers -- strip off top-level pointer casts. 230 if (const auto *CE = dyn_cast<til::Cast>(E)) { 231 if (CE->castOpcode() == til::CAST_objToPtr) 232 return CapabilityExpr(CE->expr(), Kind, Neg); 233 } 234 return CapabilityExpr(E, Kind, Neg); 235 } 236 237 til::LiteralPtr *SExprBuilder::createVariable(const VarDecl *VD) { 238 return new (Arena) til::LiteralPtr(VD); 239 } 240 241 std::pair<til::LiteralPtr *, StringRef> 242 SExprBuilder::createThisPlaceholder(const Expr *Exp) { 243 return {new (Arena) til::LiteralPtr(nullptr), 244 ClassifyDiagnostic(Exp->getType())}; 245 } 246 247 // Translate a clang statement or expression to a TIL expression. 248 // Also performs substitution of variables; Ctx provides the context. 249 // Dispatches on the type of S. 250 til::SExpr *SExprBuilder::translate(const Stmt *S, CallingContext *Ctx) { 251 if (!S) 252 return nullptr; 253 254 // Check if S has already been translated and cached. 255 // This handles the lookup of SSA names for DeclRefExprs here. 256 if (til::SExpr *E = lookupStmt(S)) 257 return E; 258 259 switch (S->getStmtClass()) { 260 case Stmt::DeclRefExprClass: 261 return translateDeclRefExpr(cast<DeclRefExpr>(S), Ctx); 262 case Stmt::CXXThisExprClass: 263 return translateCXXThisExpr(cast<CXXThisExpr>(S), Ctx); 264 case Stmt::MemberExprClass: 265 return translateMemberExpr(cast<MemberExpr>(S), Ctx); 266 case Stmt::ObjCIvarRefExprClass: 267 return translateObjCIVarRefExpr(cast<ObjCIvarRefExpr>(S), Ctx); 268 case Stmt::CallExprClass: 269 return translateCallExpr(cast<CallExpr>(S), Ctx); 270 case Stmt::CXXMemberCallExprClass: 271 return translateCXXMemberCallExpr(cast<CXXMemberCallExpr>(S), Ctx); 272 case Stmt::CXXOperatorCallExprClass: 273 return translateCXXOperatorCallExpr(cast<CXXOperatorCallExpr>(S), Ctx); 274 case Stmt::UnaryOperatorClass: 275 return translateUnaryOperator(cast<UnaryOperator>(S), Ctx); 276 case Stmt::BinaryOperatorClass: 277 case Stmt::CompoundAssignOperatorClass: 278 return translateBinaryOperator(cast<BinaryOperator>(S), Ctx); 279 280 case Stmt::ArraySubscriptExprClass: 281 return translateArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Ctx); 282 case Stmt::ConditionalOperatorClass: 283 return translateAbstractConditionalOperator( 284 cast<ConditionalOperator>(S), Ctx); 285 case Stmt::BinaryConditionalOperatorClass: 286 return translateAbstractConditionalOperator( 287 cast<BinaryConditionalOperator>(S), Ctx); 288 289 // We treat these as no-ops 290 case Stmt::ConstantExprClass: 291 return translate(cast<ConstantExpr>(S)->getSubExpr(), Ctx); 292 case Stmt::ParenExprClass: 293 return translate(cast<ParenExpr>(S)->getSubExpr(), Ctx); 294 case Stmt::ExprWithCleanupsClass: 295 return translate(cast<ExprWithCleanups>(S)->getSubExpr(), Ctx); 296 case Stmt::CXXBindTemporaryExprClass: 297 return translate(cast<CXXBindTemporaryExpr>(S)->getSubExpr(), Ctx); 298 case Stmt::MaterializeTemporaryExprClass: 299 return translate(cast<MaterializeTemporaryExpr>(S)->getSubExpr(), Ctx); 300 301 // Collect all literals 302 case Stmt::CharacterLiteralClass: 303 case Stmt::CXXNullPtrLiteralExprClass: 304 case Stmt::GNUNullExprClass: 305 case Stmt::CXXBoolLiteralExprClass: 306 case Stmt::FloatingLiteralClass: 307 case Stmt::ImaginaryLiteralClass: 308 case Stmt::IntegerLiteralClass: 309 case Stmt::StringLiteralClass: 310 case Stmt::ObjCStringLiteralClass: 311 return new (Arena) til::Literal(cast<Expr>(S)); 312 313 case Stmt::DeclStmtClass: 314 return translateDeclStmt(cast<DeclStmt>(S), Ctx); 315 default: 316 break; 317 } 318 if (const auto *CE = dyn_cast<CastExpr>(S)) 319 return translateCastExpr(CE, Ctx); 320 321 return new (Arena) til::Undefined(S); 322 } 323 324 til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE, 325 CallingContext *Ctx) { 326 const auto *VD = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl()); 327 328 // Function parameters require substitution and/or renaming. 329 if (const auto *PV = dyn_cast<ParmVarDecl>(VD)) { 330 unsigned I = PV->getFunctionScopeIndex(); 331 const DeclContext *D = PV->getDeclContext(); 332 if (Ctx && Ctx->FunArgs) { 333 const Decl *Canonical = Ctx->AttrDecl->getCanonicalDecl(); 334 if (isa<FunctionDecl>(D) 335 ? (cast<FunctionDecl>(D)->getCanonicalDecl() == Canonical) 336 : (cast<ObjCMethodDecl>(D)->getCanonicalDecl() == Canonical)) { 337 // Substitute call arguments for references to function parameters 338 if (const Expr *const *FunArgs = 339 dyn_cast<const Expr *const *>(Ctx->FunArgs)) { 340 assert(I < Ctx->NumArgs); 341 return translate(FunArgs[I], Ctx->Prev); 342 } 343 344 assert(I == 0); 345 return cast<til::SExpr *>(Ctx->FunArgs); 346 } 347 } 348 // Map the param back to the param of the original function declaration 349 // for consistent comparisons. 350 VD = isa<FunctionDecl>(D) 351 ? cast<FunctionDecl>(D)->getCanonicalDecl()->getParamDecl(I) 352 : cast<ObjCMethodDecl>(D)->getCanonicalDecl()->getParamDecl(I); 353 } 354 355 // For non-local variables, treat it as a reference to a named object. 356 return new (Arena) til::LiteralPtr(VD); 357 } 358 359 til::SExpr *SExprBuilder::translateCXXThisExpr(const CXXThisExpr *TE, 360 CallingContext *Ctx) { 361 // Substitute for 'this' 362 if (Ctx && Ctx->SelfArg) { 363 if (const auto *SelfArg = dyn_cast<const Expr *>(Ctx->SelfArg)) 364 return translate(SelfArg, Ctx->Prev); 365 else 366 return cast<til::SExpr *>(Ctx->SelfArg); 367 } 368 assert(SelfVar && "We have no variable for 'this'!"); 369 return SelfVar; 370 } 371 372 static const ValueDecl *getValueDeclFromSExpr(const til::SExpr *E) { 373 if (const auto *V = dyn_cast<til::Variable>(E)) 374 return V->clangDecl(); 375 if (const auto *Ph = dyn_cast<til::Phi>(E)) 376 return Ph->clangDecl(); 377 if (const auto *P = dyn_cast<til::Project>(E)) 378 return P->clangDecl(); 379 if (const auto *L = dyn_cast<til::LiteralPtr>(E)) 380 return L->clangDecl(); 381 return nullptr; 382 } 383 384 static bool hasAnyPointerType(const til::SExpr *E) { 385 auto *VD = getValueDeclFromSExpr(E); 386 if (VD && VD->getType()->isAnyPointerType()) 387 return true; 388 if (const auto *C = dyn_cast<til::Cast>(E)) 389 return C->castOpcode() == til::CAST_objToPtr; 390 391 return false; 392 } 393 394 // Grab the very first declaration of virtual method D 395 static const CXXMethodDecl *getFirstVirtualDecl(const CXXMethodDecl *D) { 396 while (true) { 397 D = D->getCanonicalDecl(); 398 auto OverriddenMethods = D->overridden_methods(); 399 if (OverriddenMethods.begin() == OverriddenMethods.end()) 400 return D; // Method does not override anything 401 // FIXME: this does not work with multiple inheritance. 402 D = *OverriddenMethods.begin(); 403 } 404 return nullptr; 405 } 406 407 til::SExpr *SExprBuilder::translateMemberExpr(const MemberExpr *ME, 408 CallingContext *Ctx) { 409 til::SExpr *BE = translate(ME->getBase(), Ctx); 410 til::SExpr *E = new (Arena) til::SApply(BE); 411 412 const auto *D = cast<ValueDecl>(ME->getMemberDecl()->getCanonicalDecl()); 413 if (const auto *VD = dyn_cast<CXXMethodDecl>(D)) 414 D = getFirstVirtualDecl(VD); 415 416 til::Project *P = new (Arena) til::Project(E, D); 417 if (hasAnyPointerType(BE)) 418 P->setArrow(true); 419 return P; 420 } 421 422 til::SExpr *SExprBuilder::translateObjCIVarRefExpr(const ObjCIvarRefExpr *IVRE, 423 CallingContext *Ctx) { 424 til::SExpr *BE = translate(IVRE->getBase(), Ctx); 425 til::SExpr *E = new (Arena) til::SApply(BE); 426 427 const auto *D = cast<ObjCIvarDecl>(IVRE->getDecl()->getCanonicalDecl()); 428 429 til::Project *P = new (Arena) til::Project(E, D); 430 if (hasAnyPointerType(BE)) 431 P->setArrow(true); 432 return P; 433 } 434 435 til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE, 436 CallingContext *Ctx, 437 const Expr *SelfE) { 438 if (CapabilityExprMode) { 439 // Handle LOCK_RETURNED 440 if (const FunctionDecl *FD = CE->getDirectCallee()) { 441 FD = FD->getMostRecentDecl(); 442 if (LockReturnedAttr *At = FD->getAttr<LockReturnedAttr>()) { 443 CallingContext LRCallCtx(Ctx); 444 LRCallCtx.AttrDecl = CE->getDirectCallee(); 445 LRCallCtx.SelfArg = SelfE; 446 LRCallCtx.NumArgs = CE->getNumArgs(); 447 LRCallCtx.FunArgs = CE->getArgs(); 448 return const_cast<til::SExpr *>( 449 translateAttrExpr(At->getArg(), &LRCallCtx).sexpr()); 450 } 451 } 452 } 453 454 til::SExpr *E = translate(CE->getCallee(), Ctx); 455 for (const auto *Arg : CE->arguments()) { 456 til::SExpr *A = translate(Arg, Ctx); 457 E = new (Arena) til::Apply(E, A); 458 } 459 return new (Arena) til::Call(E, CE); 460 } 461 462 til::SExpr *SExprBuilder::translateCXXMemberCallExpr( 463 const CXXMemberCallExpr *ME, CallingContext *Ctx) { 464 if (CapabilityExprMode) { 465 // Ignore calls to get() on smart pointers. 466 if (ME->getMethodDecl()->getNameAsString() == "get" && 467 ME->getNumArgs() == 0) { 468 auto *E = translate(ME->getImplicitObjectArgument(), Ctx); 469 return new (Arena) til::Cast(til::CAST_objToPtr, E); 470 // return E; 471 } 472 } 473 return translateCallExpr(cast<CallExpr>(ME), Ctx, 474 ME->getImplicitObjectArgument()); 475 } 476 477 til::SExpr *SExprBuilder::translateCXXOperatorCallExpr( 478 const CXXOperatorCallExpr *OCE, CallingContext *Ctx) { 479 if (CapabilityExprMode) { 480 // Ignore operator * and operator -> on smart pointers. 481 OverloadedOperatorKind k = OCE->getOperator(); 482 if (k == OO_Star || k == OO_Arrow) { 483 auto *E = translate(OCE->getArg(0), Ctx); 484 return new (Arena) til::Cast(til::CAST_objToPtr, E); 485 // return E; 486 } 487 } 488 return translateCallExpr(cast<CallExpr>(OCE), Ctx); 489 } 490 491 til::SExpr *SExprBuilder::translateUnaryOperator(const UnaryOperator *UO, 492 CallingContext *Ctx) { 493 switch (UO->getOpcode()) { 494 case UO_PostInc: 495 case UO_PostDec: 496 case UO_PreInc: 497 case UO_PreDec: 498 return new (Arena) til::Undefined(UO); 499 500 case UO_AddrOf: 501 if (CapabilityExprMode) { 502 // interpret &Graph::mu_ as an existential. 503 if (const auto *DRE = dyn_cast<DeclRefExpr>(UO->getSubExpr())) { 504 if (DRE->getDecl()->isCXXInstanceMember()) { 505 // This is a pointer-to-member expression, e.g. &MyClass::mu_. 506 // We interpret this syntax specially, as a wildcard. 507 auto *W = new (Arena) til::Wildcard(); 508 return new (Arena) til::Project(W, DRE->getDecl()); 509 } 510 } 511 } 512 // otherwise, & is a no-op 513 return translate(UO->getSubExpr(), Ctx); 514 515 // We treat these as no-ops 516 case UO_Deref: 517 case UO_Plus: 518 return translate(UO->getSubExpr(), Ctx); 519 520 case UO_Minus: 521 return new (Arena) 522 til::UnaryOp(til::UOP_Minus, translate(UO->getSubExpr(), Ctx)); 523 case UO_Not: 524 return new (Arena) 525 til::UnaryOp(til::UOP_BitNot, translate(UO->getSubExpr(), Ctx)); 526 case UO_LNot: 527 return new (Arena) 528 til::UnaryOp(til::UOP_LogicNot, translate(UO->getSubExpr(), Ctx)); 529 530 // Currently unsupported 531 case UO_Real: 532 case UO_Imag: 533 case UO_Extension: 534 case UO_Coawait: 535 return new (Arena) til::Undefined(UO); 536 } 537 return new (Arena) til::Undefined(UO); 538 } 539 540 til::SExpr *SExprBuilder::translateBinOp(til::TIL_BinaryOpcode Op, 541 const BinaryOperator *BO, 542 CallingContext *Ctx, bool Reverse) { 543 til::SExpr *E0 = translate(BO->getLHS(), Ctx); 544 til::SExpr *E1 = translate(BO->getRHS(), Ctx); 545 if (Reverse) 546 return new (Arena) til::BinaryOp(Op, E1, E0); 547 else 548 return new (Arena) til::BinaryOp(Op, E0, E1); 549 } 550 551 til::SExpr *SExprBuilder::translateBinAssign(til::TIL_BinaryOpcode Op, 552 const BinaryOperator *BO, 553 CallingContext *Ctx, 554 bool Assign) { 555 const Expr *LHS = BO->getLHS(); 556 const Expr *RHS = BO->getRHS(); 557 til::SExpr *E0 = translate(LHS, Ctx); 558 til::SExpr *E1 = translate(RHS, Ctx); 559 560 const ValueDecl *VD = nullptr; 561 til::SExpr *CV = nullptr; 562 if (const auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 563 VD = DRE->getDecl(); 564 CV = lookupVarDecl(VD); 565 } 566 567 if (!Assign) { 568 til::SExpr *Arg = CV ? CV : new (Arena) til::Load(E0); 569 E1 = new (Arena) til::BinaryOp(Op, Arg, E1); 570 E1 = addStatement(E1, nullptr, VD); 571 } 572 if (VD && CV) 573 return updateVarDecl(VD, E1); 574 return new (Arena) til::Store(E0, E1); 575 } 576 577 til::SExpr *SExprBuilder::translateBinaryOperator(const BinaryOperator *BO, 578 CallingContext *Ctx) { 579 switch (BO->getOpcode()) { 580 case BO_PtrMemD: 581 case BO_PtrMemI: 582 return new (Arena) til::Undefined(BO); 583 584 case BO_Mul: return translateBinOp(til::BOP_Mul, BO, Ctx); 585 case BO_Div: return translateBinOp(til::BOP_Div, BO, Ctx); 586 case BO_Rem: return translateBinOp(til::BOP_Rem, BO, Ctx); 587 case BO_Add: return translateBinOp(til::BOP_Add, BO, Ctx); 588 case BO_Sub: return translateBinOp(til::BOP_Sub, BO, Ctx); 589 case BO_Shl: return translateBinOp(til::BOP_Shl, BO, Ctx); 590 case BO_Shr: return translateBinOp(til::BOP_Shr, BO, Ctx); 591 case BO_LT: return translateBinOp(til::BOP_Lt, BO, Ctx); 592 case BO_GT: return translateBinOp(til::BOP_Lt, BO, Ctx, true); 593 case BO_LE: return translateBinOp(til::BOP_Leq, BO, Ctx); 594 case BO_GE: return translateBinOp(til::BOP_Leq, BO, Ctx, true); 595 case BO_EQ: return translateBinOp(til::BOP_Eq, BO, Ctx); 596 case BO_NE: return translateBinOp(til::BOP_Neq, BO, Ctx); 597 case BO_Cmp: return translateBinOp(til::BOP_Cmp, BO, Ctx); 598 case BO_And: return translateBinOp(til::BOP_BitAnd, BO, Ctx); 599 case BO_Xor: return translateBinOp(til::BOP_BitXor, BO, Ctx); 600 case BO_Or: return translateBinOp(til::BOP_BitOr, BO, Ctx); 601 case BO_LAnd: return translateBinOp(til::BOP_LogicAnd, BO, Ctx); 602 case BO_LOr: return translateBinOp(til::BOP_LogicOr, BO, Ctx); 603 604 case BO_Assign: return translateBinAssign(til::BOP_Eq, BO, Ctx, true); 605 case BO_MulAssign: return translateBinAssign(til::BOP_Mul, BO, Ctx); 606 case BO_DivAssign: return translateBinAssign(til::BOP_Div, BO, Ctx); 607 case BO_RemAssign: return translateBinAssign(til::BOP_Rem, BO, Ctx); 608 case BO_AddAssign: return translateBinAssign(til::BOP_Add, BO, Ctx); 609 case BO_SubAssign: return translateBinAssign(til::BOP_Sub, BO, Ctx); 610 case BO_ShlAssign: return translateBinAssign(til::BOP_Shl, BO, Ctx); 611 case BO_ShrAssign: return translateBinAssign(til::BOP_Shr, BO, Ctx); 612 case BO_AndAssign: return translateBinAssign(til::BOP_BitAnd, BO, Ctx); 613 case BO_XorAssign: return translateBinAssign(til::BOP_BitXor, BO, Ctx); 614 case BO_OrAssign: return translateBinAssign(til::BOP_BitOr, BO, Ctx); 615 616 case BO_Comma: 617 // The clang CFG should have already processed both sides. 618 return translate(BO->getRHS(), Ctx); 619 } 620 return new (Arena) til::Undefined(BO); 621 } 622 623 til::SExpr *SExprBuilder::translateCastExpr(const CastExpr *CE, 624 CallingContext *Ctx) { 625 CastKind K = CE->getCastKind(); 626 switch (K) { 627 case CK_LValueToRValue: { 628 if (const auto *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) { 629 til::SExpr *E0 = lookupVarDecl(DRE->getDecl()); 630 if (E0) 631 return E0; 632 } 633 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx); 634 return E0; 635 // FIXME!! -- get Load working properly 636 // return new (Arena) til::Load(E0); 637 } 638 case CK_NoOp: 639 case CK_DerivedToBase: 640 case CK_UncheckedDerivedToBase: 641 case CK_ArrayToPointerDecay: 642 case CK_FunctionToPointerDecay: { 643 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx); 644 return E0; 645 } 646 default: { 647 // FIXME: handle different kinds of casts. 648 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx); 649 if (CapabilityExprMode) 650 return E0; 651 return new (Arena) til::Cast(til::CAST_none, E0); 652 } 653 } 654 } 655 656 til::SExpr * 657 SExprBuilder::translateArraySubscriptExpr(const ArraySubscriptExpr *E, 658 CallingContext *Ctx) { 659 til::SExpr *E0 = translate(E->getBase(), Ctx); 660 til::SExpr *E1 = translate(E->getIdx(), Ctx); 661 return new (Arena) til::ArrayIndex(E0, E1); 662 } 663 664 til::SExpr * 665 SExprBuilder::translateAbstractConditionalOperator( 666 const AbstractConditionalOperator *CO, CallingContext *Ctx) { 667 auto *C = translate(CO->getCond(), Ctx); 668 auto *T = translate(CO->getTrueExpr(), Ctx); 669 auto *E = translate(CO->getFalseExpr(), Ctx); 670 return new (Arena) til::IfThenElse(C, T, E); 671 } 672 673 til::SExpr * 674 SExprBuilder::translateDeclStmt(const DeclStmt *S, CallingContext *Ctx) { 675 DeclGroupRef DGrp = S->getDeclGroup(); 676 for (auto *I : DGrp) { 677 if (auto *VD = dyn_cast_or_null<VarDecl>(I)) { 678 Expr *E = VD->getInit(); 679 til::SExpr* SE = translate(E, Ctx); 680 681 // Add local variables with trivial type to the variable map 682 QualType T = VD->getType(); 683 if (T.isTrivialType(VD->getASTContext())) 684 return addVarDecl(VD, SE); 685 else { 686 // TODO: add alloca 687 } 688 } 689 } 690 return nullptr; 691 } 692 693 // If (E) is non-trivial, then add it to the current basic block, and 694 // update the statement map so that S refers to E. Returns a new variable 695 // that refers to E. 696 // If E is trivial returns E. 697 til::SExpr *SExprBuilder::addStatement(til::SExpr* E, const Stmt *S, 698 const ValueDecl *VD) { 699 if (!E || !CurrentBB || E->block() || til::ThreadSafetyTIL::isTrivial(E)) 700 return E; 701 if (VD) 702 E = new (Arena) til::Variable(E, VD); 703 CurrentInstructions.push_back(E); 704 if (S) 705 insertStmt(S, E); 706 return E; 707 } 708 709 // Returns the current value of VD, if known, and nullptr otherwise. 710 til::SExpr *SExprBuilder::lookupVarDecl(const ValueDecl *VD) { 711 auto It = LVarIdxMap.find(VD); 712 if (It != LVarIdxMap.end()) { 713 assert(CurrentLVarMap[It->second].first == VD); 714 return CurrentLVarMap[It->second].second; 715 } 716 return nullptr; 717 } 718 719 // if E is a til::Variable, update its clangDecl. 720 static void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD) { 721 if (!E) 722 return; 723 if (auto *V = dyn_cast<til::Variable>(E)) { 724 if (!V->clangDecl()) 725 V->setClangDecl(VD); 726 } 727 } 728 729 // Adds a new variable declaration. 730 til::SExpr *SExprBuilder::addVarDecl(const ValueDecl *VD, til::SExpr *E) { 731 maybeUpdateVD(E, VD); 732 LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.size())); 733 CurrentLVarMap.makeWritable(); 734 CurrentLVarMap.push_back(std::make_pair(VD, E)); 735 return E; 736 } 737 738 // Updates a current variable declaration. (E.g. by assignment) 739 til::SExpr *SExprBuilder::updateVarDecl(const ValueDecl *VD, til::SExpr *E) { 740 maybeUpdateVD(E, VD); 741 auto It = LVarIdxMap.find(VD); 742 if (It == LVarIdxMap.end()) { 743 til::SExpr *Ptr = new (Arena) til::LiteralPtr(VD); 744 til::SExpr *St = new (Arena) til::Store(Ptr, E); 745 return St; 746 } 747 CurrentLVarMap.makeWritable(); 748 CurrentLVarMap.elem(It->second).second = E; 749 return E; 750 } 751 752 // Make a Phi node in the current block for the i^th variable in CurrentVarMap. 753 // If E != null, sets Phi[CurrentBlockInfo->ArgIndex] = E. 754 // If E == null, this is a backedge and will be set later. 755 void SExprBuilder::makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E) { 756 unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors; 757 assert(ArgIndex > 0 && ArgIndex < NPreds); 758 759 til::SExpr *CurrE = CurrentLVarMap[i].second; 760 if (CurrE->block() == CurrentBB) { 761 // We already have a Phi node in the current block, 762 // so just add the new variable to the Phi node. 763 auto *Ph = dyn_cast<til::Phi>(CurrE); 764 assert(Ph && "Expecting Phi node."); 765 if (E) 766 Ph->values()[ArgIndex] = E; 767 return; 768 } 769 770 // Make a new phi node: phi(..., E) 771 // All phi args up to the current index are set to the current value. 772 til::Phi *Ph = new (Arena) til::Phi(Arena, NPreds); 773 Ph->values().setValues(NPreds, nullptr); 774 for (unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx) 775 Ph->values()[PIdx] = CurrE; 776 if (E) 777 Ph->values()[ArgIndex] = E; 778 Ph->setClangDecl(CurrentLVarMap[i].first); 779 // If E is from a back-edge, or either E or CurrE are incomplete, then 780 // mark this node as incomplete; we may need to remove it later. 781 if (!E || isIncompletePhi(E) || isIncompletePhi(CurrE)) 782 Ph->setStatus(til::Phi::PH_Incomplete); 783 784 // Add Phi node to current block, and update CurrentLVarMap[i] 785 CurrentArguments.push_back(Ph); 786 if (Ph->status() == til::Phi::PH_Incomplete) 787 IncompleteArgs.push_back(Ph); 788 789 CurrentLVarMap.makeWritable(); 790 CurrentLVarMap.elem(i).second = Ph; 791 } 792 793 // Merge values from Map into the current variable map. 794 // This will construct Phi nodes in the current basic block as necessary. 795 void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) { 796 assert(CurrentBlockInfo && "Not processing a block!"); 797 798 if (!CurrentLVarMap.valid()) { 799 // Steal Map, using copy-on-write. 800 CurrentLVarMap = std::move(Map); 801 return; 802 } 803 if (CurrentLVarMap.sameAs(Map)) 804 return; // Easy merge: maps from different predecessors are unchanged. 805 806 unsigned NPreds = CurrentBB->numPredecessors(); 807 unsigned ESz = CurrentLVarMap.size(); 808 unsigned MSz = Map.size(); 809 unsigned Sz = std::min(ESz, MSz); 810 811 for (unsigned i = 0; i < Sz; ++i) { 812 if (CurrentLVarMap[i].first != Map[i].first) { 813 // We've reached the end of variables in common. 814 CurrentLVarMap.makeWritable(); 815 CurrentLVarMap.downsize(i); 816 break; 817 } 818 if (CurrentLVarMap[i].second != Map[i].second) 819 makePhiNodeVar(i, NPreds, Map[i].second); 820 } 821 if (ESz > MSz) { 822 CurrentLVarMap.makeWritable(); 823 CurrentLVarMap.downsize(Map.size()); 824 } 825 } 826 827 // Merge a back edge into the current variable map. 828 // This will create phi nodes for all variables in the variable map. 829 void SExprBuilder::mergeEntryMapBackEdge() { 830 // We don't have definitions for variables on the backedge, because we 831 // haven't gotten that far in the CFG. Thus, when encountering a back edge, 832 // we conservatively create Phi nodes for all variables. Unnecessary Phi 833 // nodes will be marked as incomplete, and stripped out at the end. 834 // 835 // An Phi node is unnecessary if it only refers to itself and one other 836 // variable, e.g. x = Phi(y, y, x) can be reduced to x = y. 837 838 assert(CurrentBlockInfo && "Not processing a block!"); 839 840 if (CurrentBlockInfo->HasBackEdges) 841 return; 842 CurrentBlockInfo->HasBackEdges = true; 843 844 CurrentLVarMap.makeWritable(); 845 unsigned Sz = CurrentLVarMap.size(); 846 unsigned NPreds = CurrentBB->numPredecessors(); 847 848 for (unsigned i = 0; i < Sz; ++i) 849 makePhiNodeVar(i, NPreds, nullptr); 850 } 851 852 // Update the phi nodes that were initially created for a back edge 853 // once the variable definitions have been computed. 854 // I.e., merge the current variable map into the phi nodes for Blk. 855 void SExprBuilder::mergePhiNodesBackEdge(const CFGBlock *Blk) { 856 til::BasicBlock *BB = lookupBlock(Blk); 857 unsigned ArgIndex = BBInfo[Blk->getBlockID()].ProcessedPredecessors; 858 assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors()); 859 860 for (til::SExpr *PE : BB->arguments()) { 861 auto *Ph = dyn_cast_or_null<til::Phi>(PE); 862 assert(Ph && "Expecting Phi Node."); 863 assert(Ph->values()[ArgIndex] == nullptr && "Wrong index for back edge."); 864 865 til::SExpr *E = lookupVarDecl(Ph->clangDecl()); 866 assert(E && "Couldn't find local variable for Phi node."); 867 Ph->values()[ArgIndex] = E; 868 } 869 } 870 871 void SExprBuilder::enterCFG(CFG *Cfg, const NamedDecl *D, 872 const CFGBlock *First) { 873 // Perform initial setup operations. 874 unsigned NBlocks = Cfg->getNumBlockIDs(); 875 Scfg = new (Arena) til::SCFG(Arena, NBlocks); 876 877 // allocate all basic blocks immediately, to handle forward references. 878 BBInfo.resize(NBlocks); 879 BlockMap.resize(NBlocks, nullptr); 880 // create map from clang blockID to til::BasicBlocks 881 for (auto *B : *Cfg) { 882 auto *BB = new (Arena) til::BasicBlock(Arena); 883 BB->reserveInstructions(B->size()); 884 BlockMap[B->getBlockID()] = BB; 885 } 886 887 CurrentBB = lookupBlock(&Cfg->getEntry()); 888 auto Parms = isa<ObjCMethodDecl>(D) ? cast<ObjCMethodDecl>(D)->parameters() 889 : cast<FunctionDecl>(D)->parameters(); 890 for (auto *Pm : Parms) { 891 QualType T = Pm->getType(); 892 if (!T.isTrivialType(Pm->getASTContext())) 893 continue; 894 895 // Add parameters to local variable map. 896 // FIXME: right now we emulate params with loads; that should be fixed. 897 til::SExpr *Lp = new (Arena) til::LiteralPtr(Pm); 898 til::SExpr *Ld = new (Arena) til::Load(Lp); 899 til::SExpr *V = addStatement(Ld, nullptr, Pm); 900 addVarDecl(Pm, V); 901 } 902 } 903 904 void SExprBuilder::enterCFGBlock(const CFGBlock *B) { 905 // Initialize TIL basic block and add it to the CFG. 906 CurrentBB = lookupBlock(B); 907 CurrentBB->reservePredecessors(B->pred_size()); 908 Scfg->add(CurrentBB); 909 910 CurrentBlockInfo = &BBInfo[B->getBlockID()]; 911 912 // CurrentLVarMap is moved to ExitMap on block exit. 913 // FIXME: the entry block will hold function parameters. 914 // assert(!CurrentLVarMap.valid() && "CurrentLVarMap already initialized."); 915 } 916 917 void SExprBuilder::handlePredecessor(const CFGBlock *Pred) { 918 // Compute CurrentLVarMap on entry from ExitMaps of predecessors 919 920 CurrentBB->addPredecessor(BlockMap[Pred->getBlockID()]); 921 BlockInfo *PredInfo = &BBInfo[Pred->getBlockID()]; 922 assert(PredInfo->UnprocessedSuccessors > 0); 923 924 if (--PredInfo->UnprocessedSuccessors == 0) 925 mergeEntryMap(std::move(PredInfo->ExitMap)); 926 else 927 mergeEntryMap(PredInfo->ExitMap.clone()); 928 929 ++CurrentBlockInfo->ProcessedPredecessors; 930 } 931 932 void SExprBuilder::handlePredecessorBackEdge(const CFGBlock *Pred) { 933 mergeEntryMapBackEdge(); 934 } 935 936 void SExprBuilder::enterCFGBlockBody(const CFGBlock *B) { 937 // The merge*() methods have created arguments. 938 // Push those arguments onto the basic block. 939 CurrentBB->arguments().reserve( 940 static_cast<unsigned>(CurrentArguments.size()), Arena); 941 for (auto *A : CurrentArguments) 942 CurrentBB->addArgument(A); 943 } 944 945 void SExprBuilder::handleStatement(const Stmt *S) { 946 til::SExpr *E = translate(S, nullptr); 947 addStatement(E, S); 948 } 949 950 void SExprBuilder::handleDestructorCall(const VarDecl *VD, 951 const CXXDestructorDecl *DD) { 952 til::SExpr *Sf = new (Arena) til::LiteralPtr(VD); 953 til::SExpr *Dr = new (Arena) til::LiteralPtr(DD); 954 til::SExpr *Ap = new (Arena) til::Apply(Dr, Sf); 955 til::SExpr *E = new (Arena) til::Call(Ap); 956 addStatement(E, nullptr); 957 } 958 959 void SExprBuilder::exitCFGBlockBody(const CFGBlock *B) { 960 CurrentBB->instructions().reserve( 961 static_cast<unsigned>(CurrentInstructions.size()), Arena); 962 for (auto *V : CurrentInstructions) 963 CurrentBB->addInstruction(V); 964 965 // Create an appropriate terminator 966 unsigned N = B->succ_size(); 967 auto It = B->succ_begin(); 968 if (N == 1) { 969 til::BasicBlock *BB = *It ? lookupBlock(*It) : nullptr; 970 // TODO: set index 971 unsigned Idx = BB ? BB->findPredecessorIndex(CurrentBB) : 0; 972 auto *Tm = new (Arena) til::Goto(BB, Idx); 973 CurrentBB->setTerminator(Tm); 974 } 975 else if (N == 2) { 976 til::SExpr *C = translate(B->getTerminatorCondition(true), nullptr); 977 til::BasicBlock *BB1 = *It ? lookupBlock(*It) : nullptr; 978 ++It; 979 til::BasicBlock *BB2 = *It ? lookupBlock(*It) : nullptr; 980 // FIXME: make sure these aren't critical edges. 981 auto *Tm = new (Arena) til::Branch(C, BB1, BB2); 982 CurrentBB->setTerminator(Tm); 983 } 984 } 985 986 void SExprBuilder::handleSuccessor(const CFGBlock *Succ) { 987 ++CurrentBlockInfo->UnprocessedSuccessors; 988 } 989 990 void SExprBuilder::handleSuccessorBackEdge(const CFGBlock *Succ) { 991 mergePhiNodesBackEdge(Succ); 992 ++BBInfo[Succ->getBlockID()].ProcessedPredecessors; 993 } 994 995 void SExprBuilder::exitCFGBlock(const CFGBlock *B) { 996 CurrentArguments.clear(); 997 CurrentInstructions.clear(); 998 CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap); 999 CurrentBB = nullptr; 1000 CurrentBlockInfo = nullptr; 1001 } 1002 1003 void SExprBuilder::exitCFG(const CFGBlock *Last) { 1004 for (auto *Ph : IncompleteArgs) { 1005 if (Ph->status() == til::Phi::PH_Incomplete) 1006 simplifyIncompleteArg(Ph); 1007 } 1008 1009 CurrentArguments.clear(); 1010 CurrentInstructions.clear(); 1011 IncompleteArgs.clear(); 1012 } 1013 1014 #ifndef NDEBUG 1015 namespace { 1016 1017 class TILPrinter : 1018 public til::PrettyPrinter<TILPrinter, llvm::raw_ostream> {}; 1019 1020 } // namespace 1021 1022 namespace clang { 1023 namespace threadSafety { 1024 1025 void printSCFG(CFGWalker &Walker) { 1026 llvm::BumpPtrAllocator Bpa; 1027 til::MemRegionRef Arena(&Bpa); 1028 SExprBuilder SxBuilder(Arena); 1029 til::SCFG *Scfg = SxBuilder.buildCFG(Walker); 1030 TILPrinter::print(Scfg, llvm::errs()); 1031 } 1032 1033 } // namespace threadSafety 1034 } // namespace clang 1035 #endif // NDEBUG 1036