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
This commit is contained in:
Aaron Puchert 2022-07-14 13:39:04 +02:00
parent 32dc48094b
commit d8fa40dfa7
2 changed files with 21 additions and 7 deletions

View File

@ -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);
@ -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());

View File

@ -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()) {