diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -2139,12 +2139,14 @@ // handle constructors that involve temporaries if (auto *EWC = dyn_cast(E)) - E = EWC->getSubExpr(); - if (auto *ICE = dyn_cast(E)) - if (ICE->getCastKind() == CK_NoOp) - E = ICE->getSubExpr(); + E = EWC->getSubExpr()->IgnoreParens(); + if (auto *CE = dyn_cast(E)) + if (CE->getCastKind() == CK_NoOp || + CE->getCastKind() == CK_ConstructorConversion || + CE->getCastKind() == CK_UserDefinedConversion) + E = CE->getSubExpr()->IgnoreParens(); if (auto *BTE = dyn_cast(E)) - E = BTE->getSubExpr(); + E = BTE->getSubExpr()->IgnoreParens(); if (const auto *CE = dyn_cast(E)) { const auto *CtorD = dyn_cast_or_null(CE->getConstructor()); diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -5648,6 +5648,22 @@ auto ptr = get(); return ptr->f(); } + void use_constructor() { + auto ptr = ReadLockedPtr(nullptr); + ptr->f(); + auto ptr2 = ReadLockedPtr{nullptr}; + ptr2->f(); + auto ptr3 = (ReadLockedPtr{nullptr}); + ptr3->f(); + } + struct Convertible { + Convertible(); + operator ReadLockedPtr(); + }; + void use_conversion() { + ReadLockedPtr ptr = Convertible(); + ptr->f(); + } } namespace PR38640 {