Skip to content

Commit 5dc9d55

Browse files
committed
[clang][analyzer] Handle CXXParenInitListExpr alongside InitListExpr
As reported in #135665, C++20 parenthesis initializer list expressions are not handled correctly and were causing crashes. This commit attempts to fix the issue by handing parenthesis initializer lists along side existing initializer lists.
1 parent 52e10e6 commit 5dc9d55

File tree

4 files changed

+30
-7
lines changed

4 files changed

+30
-7
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,8 @@ Code Completion
667667

668668
Static Analyzer
669669
---------------
670+
- Fixed a crash when C++20 parenthesized initializer lists are used. This issue
671+
was causing a crash in clang-tidy. (#GH136041)
670672

671673
New features
672674
^^^^^^^^^^^^

clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,9 @@ void DynamicTypePropagation::checkPostCall(const CallEvent &Call,
379379
// aggregates, and in such case no top-frame constructor will be called.
380380
// Figure out if we need to do anything in this case.
381381
// FIXME: Instead of relying on the ParentMap, we should have the
382-
// trigger-statement (InitListExpr in this case) available in this
383-
// callback, ideally as part of CallEvent.
384-
if (isa_and_nonnull<InitListExpr>(
382+
// trigger-statement (InitListExpr or CXXParenListInitExpr in this case)
383+
// available in this callback, ideally as part of CallEvent.
384+
if (isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(
385385
LCtx->getParentMap().getParent(Ctor->getOriginExpr())))
386386
return;
387387

clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -644,9 +644,10 @@ void ExprEngine::handleConstructor(const Expr *E,
644644
// FIXME: For now this code essentially bails out. We need to find the
645645
// correct target region and set it.
646646
// FIXME: Instead of relying on the ParentMap, we should have the
647-
// trigger-statement (InitListExpr in this case) passed down from CFG or
648-
// otherwise always available during construction.
649-
if (isa_and_nonnull<InitListExpr>(LCtx->getParentMap().getParent(E))) {
647+
// trigger-statement (InitListExpr or CXXParenListInitExpr in this case)
648+
// passed down from CFG or otherwise always available during construction.
649+
if (isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(
650+
LCtx->getParentMap().getParent(E))) {
650651
MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
651652
Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
652653
CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
@@ -1017,7 +1018,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
10171018
// values are properly placed inside the required region, however if an
10181019
// initializer list is used, this doesn't happen automatically.
10191020
auto *Init = CNE->getInitializer();
1020-
bool isInitList = isa_and_nonnull<InitListExpr>(Init);
1021+
bool isInitList =
1022+
isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(Init);
10211023

10221024
QualType ObjTy =
10231025
isInitList ? Init->getType() : CNE->getType()->getPointeeType();

clang/test/Analysis/PR135665.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %clang_analyze_cc1 -std=c++20 -analyzer-checker=core -verify %s
2+
3+
// expected-no-diagnostics
4+
5+
template<typename... F>
6+
struct overload : public F...
7+
{
8+
using F::operator()...;
9+
};
10+
11+
template<typename... F>
12+
overload(F&&...) -> overload<F...>;
13+
14+
int main()
15+
{
16+
const auto l = overload([](const int* i) {});
17+
18+
return 0;
19+
}

0 commit comments

Comments
 (0)