diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index 099e8590b50e3..70df7731aef7a 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -1659,6 +1659,11 @@ const CallExpr* ThreadSafetyAnalyzer::getTrylockCallExpr(const Stmt *Cond, return getTrylockCallExpr(COP->getCond(), C, Negate); } } + } else if (const auto *SE = dyn_cast(Cond)) { + if (const auto *CS = SE->getSubStmt(); CS && !CS->body_empty()) { + if (const auto *E = dyn_cast(CS->body_back())) + return getTrylockCallExpr(E, C, Negate); + } } return nullptr; } diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index d70d5f99cb515..9f11fdcf78f01 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -2008,6 +2008,13 @@ struct TestTryLock { } } + void foo3_stmtexpr() { + if (({ bool b = mu.TryLock(); b; })) { + a = 3; + mu.Unlock(); + } + } + void foo3_builtin_expect() { bool b = mu.TryLock(); if (__builtin_expect(b, true)) { @@ -2016,6 +2023,13 @@ struct TestTryLock { } } + void foo3_builtin_expect_stmtexpr() { + if (({ bool b = mu.TryLock(); __builtin_expect(b, true); })) { + a = 3; + mu.Unlock(); + } + } + void foo4() { bool b = mu.TryLock(); if (!b) return;