Skip to content

Commit d8fa40d

Browse files
committed
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
1 parent 32dc480 commit d8fa40d

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

clang/lib/Analysis/ThreadSafety.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,6 +2087,19 @@ static Expr *buildFakeCtorCall(CXXConstructorDecl *CD, ArrayRef<Expr *> Args,
20872087
SourceRange(Loc, Loc));
20882088
}
20892089

2090+
static Expr *UnpackConstruction(Expr *E) {
2091+
if (auto *CE = dyn_cast<CastExpr>(E))
2092+
if (CE->getCastKind() == CK_NoOp)
2093+
E = CE->getSubExpr()->IgnoreParens();
2094+
if (auto *CE = dyn_cast<CastExpr>(E))
2095+
if (CE->getCastKind() == CK_ConstructorConversion ||
2096+
CE->getCastKind() == CK_UserDefinedConversion)
2097+
E = CE->getSubExpr();
2098+
if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
2099+
E = BTE->getSubExpr();
2100+
return E;
2101+
}
2102+
20902103
void BuildLockset::VisitDeclStmt(const DeclStmt *S) {
20912104
// adjust the context
20922105
LVarCtx = Analyzer->LocalVarMap.getNextContext(CtxIndex, S, LVarCtx);
@@ -2101,13 +2114,7 @@ void BuildLockset::VisitDeclStmt(const DeclStmt *S) {
21012114
// handle constructors that involve temporaries
21022115
if (auto *EWC = dyn_cast<ExprWithCleanups>(E))
21032116
E = EWC->getSubExpr()->IgnoreParens();
2104-
if (auto *CE = dyn_cast<CastExpr>(E))
2105-
if (CE->getCastKind() == CK_NoOp ||
2106-
CE->getCastKind() == CK_ConstructorConversion ||
2107-
CE->getCastKind() == CK_UserDefinedConversion)
2108-
E = CE->getSubExpr()->IgnoreParens();
2109-
if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
2110-
E = BTE->getSubExpr()->IgnoreParens();
2117+
E = UnpackConstruction(E);
21112118

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

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,13 @@ struct TestScopedLockable {
16831683
a = 5;
16841684
}
16851685

1686+
#ifdef __cpp_guaranteed_copy_elision
1687+
void const_lock() {
1688+
const MutexLock mulock = MutexLock(&mu1);
1689+
a = 5;
1690+
}
1691+
#endif
1692+
16861693
void foo2() {
16871694
ReaderMutexLock mulock1(&mu1);
16881695
if (getBool()) {

0 commit comments

Comments
 (0)