diff options
Diffstat (limited to 'clang/lib/Analysis/ThreadSafetyCommon.cpp')
-rw-r--r-- | clang/lib/Analysis/ThreadSafetyCommon.cpp | 76 |
1 files changed, 39 insertions, 37 deletions
diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index 13cd7e2..d35ae94 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -67,6 +67,40 @@ static bool isIncompletePhi(const til::SExpr *E) { return false; } +static constexpr std::pair<StringRef, bool> ClassifyCapabilityFallback{ + /*Kind=*/StringRef("mutex"), + /*Reentrant=*/false}; + +// Returns pair (Kind, Reentrant). +static std::pair<StringRef, bool> classifyCapability(const TypeDecl &TD) { + if (const auto *CA = TD.getAttr<CapabilityAttr>()) + return {CA->getName(), TD.hasAttr<ReentrantCapabilityAttr>()}; + + return ClassifyCapabilityFallback; +} + +// Returns pair (Kind, Reentrant). +static std::pair<StringRef, bool> classifyCapability(QualType QT) { + // We need to look at the declaration of the type of the value to determine + // which it is. The type should either be a record or a typedef, or a pointer + // or reference thereof. + if (const auto *RT = QT->getAs<RecordType>()) { + if (const auto *RD = RT->getDecl()) + return classifyCapability(*RD); + } else if (const auto *TT = QT->getAs<TypedefType>()) { + if (const auto *TD = TT->getDecl()) + return classifyCapability(*TD); + } else if (QT->isPointerOrReferenceType()) + return classifyCapability(QT->getPointeeType()); + + return ClassifyCapabilityFallback; +} + +CapabilityExpr::CapabilityExpr(const til::SExpr *E, QualType QT, bool Neg) { + const auto &[Kind, Reentrant] = classifyCapability(QT); + *this = CapabilityExpr(E, Kind, Neg, Reentrant); +} + using CallingContext = SExprBuilder::CallingContext; til::SExpr *SExprBuilder::lookupStmt(const Stmt *S) { return SMap.lookup(S); } @@ -81,28 +115,6 @@ static bool isCalleeArrow(const Expr *E) { return ME ? ME->isArrow() : false; } -static StringRef ClassifyDiagnostic(const CapabilityAttr *A) { - return A->getName(); -} - -static StringRef ClassifyDiagnostic(QualType VDT) { - // We need to look at the declaration of the type of the value to determine - // which it is. The type should either be a record or a typedef, or a pointer - // or reference thereof. - if (const auto *RT = VDT->getAs<RecordType>()) { - if (const auto *RD = RT->getDecl()) - if (const auto *CA = RD->getAttr<CapabilityAttr>()) - return ClassifyDiagnostic(CA); - } else if (const auto *TT = VDT->getAs<TypedefType>()) { - if (const auto *TD = TT->getDecl()) - if (const auto *CA = TD->getAttr<CapabilityAttr>()) - return ClassifyDiagnostic(CA); - } else if (VDT->isPointerOrReferenceType()) - return ClassifyDiagnostic(VDT->getPointeeType()); - - return "mutex"; -} - /// Translate a clang expression in an attribute to a til::SExpr. /// Constructs the context from D, DeclExp, and SelfDecl. /// @@ -170,9 +182,7 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, // If the attribute has no arguments, then assume the argument is "this". if (!AttrExp) return CapabilityExpr( - Self, - ClassifyDiagnostic( - cast<CXXMethodDecl>(D)->getFunctionObjectParameterType()), + Self, cast<CXXMethodDecl>(D)->getFunctionObjectParameterType(), false); else // For most attributes. return translateAttrExpr(AttrExp, &Ctx); @@ -197,7 +207,7 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, // The "*" expr is a universal lock, which essentially turns off // checks until it is removed from the lockset. return CapabilityExpr(new (Arena) til::Wildcard(), StringRef("wildcard"), - false); + /*Neg=*/false, /*Reentrant=*/false); else // Ignore other string literals for now. return CapabilityExpr(); @@ -217,33 +227,25 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, } } - til::SExpr *E = translate(AttrExp, Ctx); + const til::SExpr *E = translate(AttrExp, Ctx); // Trap mutex expressions like nullptr, or 0. // Any literal value is nonsense. if (!E || isa<til::Literal>(E)) return CapabilityExpr(); - StringRef Kind = ClassifyDiagnostic(AttrExp->getType()); - // Hack to deal with smart pointers -- strip off top-level pointer casts. if (const auto *CE = dyn_cast<til::Cast>(E)) { if (CE->castOpcode() == til::CAST_objToPtr) - return CapabilityExpr(CE->expr(), Kind, Neg); + E = CE->expr(); } - return CapabilityExpr(E, Kind, Neg); + return CapabilityExpr(E, AttrExp->getType(), Neg); } til::LiteralPtr *SExprBuilder::createVariable(const VarDecl *VD) { return new (Arena) til::LiteralPtr(VD); } -std::pair<til::LiteralPtr *, StringRef> -SExprBuilder::createThisPlaceholder(const Expr *Exp) { - return {new (Arena) til::LiteralPtr(nullptr), - ClassifyDiagnostic(Exp->getType())}; -} - // Translate a clang statement or expression to a TIL expression. // Also performs substitution of variables; Ctx provides the context. // Dispatches on the type of S. |