Skip to content

Commit 13d4ea6

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 0045b82 commit 13d4ea6

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -379,10 +379,12 @@ 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>(
385-
LCtx->getParentMap().getParent(Ctor->getOriginExpr())))
382+
// trigger-statement (InitListExpr or CXXParenListInitExpr in this case)
383+
// available in this callback, ideally as part of CallEvent.
384+
const Stmt *Parent =
385+
LCtx->getParentMap().getParent(Ctor->getOriginExpr());
386+
if (isa_and_nonnull<InitListExpr>(Parent) ||
387+
isa_and_nonnull<CXXParenListInitExpr>(Parent))
386388
return;
387389

388390
recordFixedType(Target, cast<CXXConstructorDecl>(LCtx->getDecl()), C);

clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -644,9 +644,11 @@ 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>(LCtx->getParentMap().getParent(E)) ||
650+
isa_and_nonnull<CXXParenListInitExpr>(
651+
LCtx->getParentMap().getParent(E))) {
650652
MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
651653
Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
652654
CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
@@ -1017,7 +1019,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
10171019
// values are properly placed inside the required region, however if an
10181020
// initializer list is used, this doesn't happen automatically.
10191021
auto *Init = CNE->getInitializer();
1020-
bool isInitList = isa_and_nonnull<InitListExpr>(Init);
1022+
bool isInitList = isa_and_nonnull<InitListExpr>(Init) ||
1023+
isa_and_nonnull<CXXParenListInitExpr>(Init);
10211024

10221025
QualType ObjTy =
10231026
isInitList ? Init->getType() : CNE->getType()->getPointeeType();

clang/test/Analysis/PR135665.cpp

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

0 commit comments

Comments
 (0)