Skip to content

Commit

Permalink
Thread safety analysis: Handle additional cast in scoped capability c…
Browse files Browse the repository at this point in the history
…onstruction

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
  • Loading branch information
aaronpuchert committed Oct 6, 2022
1 parent 32dc480 commit d8fa40d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
21 changes: 14 additions & 7 deletions clang/lib/Analysis/ThreadSafety.cpp
Expand Up @@ -2087,6 +2087,19 @@ static Expr *buildFakeCtorCall(CXXConstructorDecl *CD, ArrayRef<Expr *> Args,
SourceRange(Loc, Loc));
}

static Expr *UnpackConstruction(Expr *E) {
if (auto *CE = dyn_cast<CastExpr>(E))
if (CE->getCastKind() == CK_NoOp)
E = CE->getSubExpr()->IgnoreParens();
if (auto *CE = dyn_cast<CastExpr>(E))
if (CE->getCastKind() == CK_ConstructorConversion ||
CE->getCastKind() == CK_UserDefinedConversion)
E = CE->getSubExpr();
if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
E = BTE->getSubExpr();
return E;
}

void BuildLockset::VisitDeclStmt(const DeclStmt *S) {
// adjust the context
LVarCtx = Analyzer->LocalVarMap.getNextContext(CtxIndex, S, LVarCtx);
Expand All @@ -2101,13 +2114,7 @@ void BuildLockset::VisitDeclStmt(const DeclStmt *S) {
// handle constructors that involve temporaries
if (auto *EWC = dyn_cast<ExprWithCleanups>(E))
E = EWC->getSubExpr()->IgnoreParens();
if (auto *CE = dyn_cast<CastExpr>(E))
if (CE->getCastKind() == CK_NoOp ||
CE->getCastKind() == CK_ConstructorConversion ||
CE->getCastKind() == CK_UserDefinedConversion)
E = CE->getSubExpr()->IgnoreParens();
if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
E = BTE->getSubExpr()->IgnoreParens();
E = UnpackConstruction(E);

if (const auto *CE = dyn_cast<CXXConstructExpr>(E)) {
const auto *CtorD = dyn_cast_or_null<NamedDecl>(CE->getConstructor());
Expand Down
7 changes: 7 additions & 0 deletions clang/test/SemaCXX/warn-thread-safety-analysis.cpp
Expand Up @@ -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()) {
Expand Down

0 comments on commit d8fa40d

Please sign in to comment.