Skip to content

Commit 8a36b8e

Browse files
fangyi-zhoutstellar
authored andcommitted
[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. (cherry picked from commit 5dc9d55)
1 parent 070cf62 commit 8a36b8e

File tree

4 files changed

+31
-7
lines changed

4 files changed

+31
-7
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,6 +1472,9 @@ Crash and bug fixes
14721472
- The ``unix.BlockInCriticalSection`` now recognizes the ``lock()`` member function
14731473
as expected, even if it's inherited from a base class. Fixes (#GH104241).
14741474

1475+
- Fixed a crash when C++20 parenthesized initializer lists are used. This issue
1476+
was causing a crash in clang-tidy. (#GH136041)
1477+
14751478
Improvements
14761479
^^^^^^^^^^^^
14771480

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
@@ -637,9 +637,10 @@ void ExprEngine::handleConstructor(const Expr *E,
637637
// FIXME: For now this code essentially bails out. We need to find the
638638
// correct target region and set it.
639639
// FIXME: Instead of relying on the ParentMap, we should have the
640-
// trigger-statement (InitListExpr in this case) passed down from CFG or
641-
// otherwise always available during construction.
642-
if (isa_and_nonnull<InitListExpr>(LCtx->getParentMap().getParent(E))) {
640+
// trigger-statement (InitListExpr or CXXParenListInitExpr in this case)
641+
// passed down from CFG or otherwise always available during construction.
642+
if (isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(
643+
LCtx->getParentMap().getParent(E))) {
643644
MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
644645
Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
645646
CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
@@ -1010,7 +1011,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
10101011
// values are properly placed inside the required region, however if an
10111012
// initializer list is used, this doesn't happen automatically.
10121013
auto *Init = CNE->getInitializer();
1013-
bool isInitList = isa_and_nonnull<InitListExpr>(Init);
1014+
bool isInitList =
1015+
isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(Init);
10141016

10151017
QualType ObjTy =
10161018
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)