diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 47ef2f80ac3f2..4d28c4742d926 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1467,6 +1467,9 @@ Crash and bug fixes - The ``unix.BlockInCriticalSection`` now recognizes the ``lock()`` member function as expected, even if it's inherited from a base class. Fixes (#GH104241). +- Fixed a crash when C++20 parenthesized initializer lists are used. This issue + was causing a crash in clang-tidy. (#GH136041) + Improvements ^^^^^^^^^^^^ diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp index a0bf776b11f53..e58329817d7cd 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -379,9 +379,9 @@ void DynamicTypePropagation::checkPostCall(const CallEvent &Call, // aggregates, and in such case no top-frame constructor will be called. // Figure out if we need to do anything in this case. // FIXME: Instead of relying on the ParentMap, we should have the - // trigger-statement (InitListExpr in this case) available in this - // callback, ideally as part of CallEvent. - if (isa_and_nonnull( + // trigger-statement (InitListExpr or CXXParenListInitExpr in this case) + // available in this callback, ideally as part of CallEvent. + if (isa_and_nonnull( LCtx->getParentMap().getParent(Ctor->getOriginExpr()))) return; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index f7020da2e6da2..30839a40389ba 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -637,9 +637,10 @@ void ExprEngine::handleConstructor(const Expr *E, // FIXME: For now this code essentially bails out. We need to find the // correct target region and set it. // FIXME: Instead of relying on the ParentMap, we should have the - // trigger-statement (InitListExpr in this case) passed down from CFG or - // otherwise always available during construction. - if (isa_and_nonnull(LCtx->getParentMap().getParent(E))) { + // trigger-statement (InitListExpr or CXXParenListInitExpr in this case) + // passed down from CFG or otherwise always available during construction. + if (isa_and_nonnull( + LCtx->getParentMap().getParent(E))) { MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx)); CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true; @@ -1010,7 +1011,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, // values are properly placed inside the required region, however if an // initializer list is used, this doesn't happen automatically. auto *Init = CNE->getInitializer(); - bool isInitList = isa_and_nonnull(Init); + bool isInitList = + isa_and_nonnull(Init); QualType ObjTy = isInitList ? Init->getType() : CNE->getType()->getPointeeType(); diff --git a/clang/test/Analysis/PR135665.cpp b/clang/test/Analysis/PR135665.cpp new file mode 100644 index 0000000000000..124b8c9b97b04 --- /dev/null +++ b/clang/test/Analysis/PR135665.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_analyze_cc1 -std=c++20 -analyzer-checker=core -verify %s + +// expected-no-diagnostics + +template +struct overload : public F... +{ + using F::operator()...; +}; + +template +overload(F&&...) -> overload; + +int main() +{ + const auto l = overload([](const int* i) {}); + + return 0; +}