From: Aaron Puchert Date: Thu, 14 Jul 2022 11:39:04 +0000 (+0200) Subject: Thread safety analysis: Handle additional cast in scoped capability construction X-Git-Tag: upstream/17.0.6~31339 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d8fa40dfa7adb062c969ce7ea6ce505e10626838;p=platform%2Fupstream%2Fllvm.git Thread safety analysis: Handle additional cast in scoped capability construction We might have a CK_NoOp cast and a further CK_ConstructorConversion. As an optimization, drop some IgnoreParens calls: inside of the CK_{Constructor,UserDefined}Conversion should be no more parentheses, and inside the CXXBindTemporaryExpr should also be none. Lastly, we factor out the unpacking so that we can reuse it for MaterializeTemporaryExprs later on. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D129752 --- diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index 3291d7f..a29134c 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -2087,6 +2087,19 @@ static Expr *buildFakeCtorCall(CXXConstructorDecl *CD, ArrayRef Args, SourceRange(Loc, Loc)); } +static Expr *UnpackConstruction(Expr *E) { + if (auto *CE = dyn_cast(E)) + if (CE->getCastKind() == CK_NoOp) + E = CE->getSubExpr()->IgnoreParens(); + if (auto *CE = dyn_cast(E)) + if (CE->getCastKind() == CK_ConstructorConversion || + CE->getCastKind() == CK_UserDefinedConversion) + E = CE->getSubExpr(); + if (auto *BTE = dyn_cast(E)) + E = BTE->getSubExpr(); + return E; +} + void BuildLockset::VisitDeclStmt(const DeclStmt *S) { // adjust the context LVarCtx = Analyzer->LocalVarMap.getNextContext(CtxIndex, S, LVarCtx); @@ -2101,13 +2114,7 @@ void BuildLockset::VisitDeclStmt(const DeclStmt *S) { // handle constructors that involve temporaries if (auto *EWC = dyn_cast(E)) E = EWC->getSubExpr()->IgnoreParens(); - if (auto *CE = dyn_cast(E)) - if (CE->getCastKind() == CK_NoOp || - CE->getCastKind() == CK_ConstructorConversion || - CE->getCastKind() == CK_UserDefinedConversion) - E = CE->getSubExpr()->IgnoreParens(); - if (auto *BTE = dyn_cast(E)) - E = BTE->getSubExpr()->IgnoreParens(); + E = UnpackConstruction(E); if (const auto *CE = dyn_cast(E)) { const auto *CtorD = dyn_cast_or_null(CE->getConstructor()); diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index ac854dc..e1cfa1f 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1683,6 +1683,13 @@ struct TestScopedLockable { a = 5; } +#ifdef __cpp_guaranteed_copy_elision + void const_lock() { + const MutexLock mulock = MutexLock(&mu1); + a = 5; + } +#endif + void foo2() { ReaderMutexLock mulock1(&mu1); if (getBool()) {