Skip to content

Commit 24485ae

Browse files
committed
[clang analysis] Make mutex guard detection more reliable.
-Wthread-safety was failing to detect certain AST patterns it should detect. Make the pattern detection a bit more comprehensive. Due to an unrelated bug involving template instantiation, this showed up as a regression in 10.0 vs. 9.0 in the original bug report. The included testcase fails on older versions of clang, though. Fixes https://bugs.llvm.org/show_bug.cgi?id=45323 . Differential Revision: https://reviews.llvm.org/D76943
1 parent a235215 commit 24485ae

File tree

2 files changed

+23
-5
lines changed

2 files changed

+23
-5
lines changed

clang/lib/Analysis/ThreadSafety.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,12 +2139,14 @@ void BuildLockset::VisitDeclStmt(const DeclStmt *S) {
21392139

21402140
// handle constructors that involve temporaries
21412141
if (auto *EWC = dyn_cast<ExprWithCleanups>(E))
2142-
E = EWC->getSubExpr();
2143-
if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
2144-
if (ICE->getCastKind() == CK_NoOp)
2145-
E = ICE->getSubExpr();
2142+
E = EWC->getSubExpr()->IgnoreParens();
2143+
if (auto *CE = dyn_cast<CastExpr>(E))
2144+
if (CE->getCastKind() == CK_NoOp ||
2145+
CE->getCastKind() == CK_ConstructorConversion ||
2146+
CE->getCastKind() == CK_UserDefinedConversion)
2147+
E = CE->getSubExpr()->IgnoreParens();
21462148
if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
2147-
E = BTE->getSubExpr();
2149+
E = BTE->getSubExpr()->IgnoreParens();
21482150

21492151
if (const auto *CE = dyn_cast<CXXConstructExpr>(E)) {
21502152
const auto *CtorD = dyn_cast_or_null<NamedDecl>(CE->getConstructor());

clang/test/SemaCXX/warn-thread-safety-analysis.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5648,6 +5648,22 @@ namespace ReturnScopedLockable {
56485648
auto ptr = get();
56495649
return ptr->f();
56505650
}
5651+
void use_constructor() {
5652+
auto ptr = ReadLockedPtr<Object>(nullptr);
5653+
ptr->f();
5654+
auto ptr2 = ReadLockedPtr<Object>{nullptr};
5655+
ptr2->f();
5656+
auto ptr3 = (ReadLockedPtr<Object>{nullptr});
5657+
ptr3->f();
5658+
}
5659+
struct Convertible {
5660+
Convertible();
5661+
operator ReadLockedPtr<Object>();
5662+
};
5663+
void use_conversion() {
5664+
ReadLockedPtr<Object> ptr = Convertible();
5665+
ptr->f();
5666+
}
56515667
}
56525668

56535669
namespace PR38640 {

0 commit comments

Comments
 (0)