[clang][analyzer] Handle CXXParenInitListExpr alongside InitListExpr (#136041)
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. Fixes #135665.
This commit is contained in:
@@ -677,6 +677,8 @@ Code Completion
|
||||
|
||||
Static Analyzer
|
||||
---------------
|
||||
- Fixed a crash when C++20 parenthesized initializer lists are used. This issue
|
||||
was causing a crash in clang-tidy. (#GH136041)
|
||||
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
@@ -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<InitListExpr>(
|
||||
// trigger-statement (InitListExpr or CXXParenListInitExpr in this case)
|
||||
// available in this callback, ideally as part of CallEvent.
|
||||
if (isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(
|
||||
LCtx->getParentMap().getParent(Ctor->getOriginExpr())))
|
||||
return;
|
||||
|
||||
|
||||
@@ -644,9 +644,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<InitListExpr>(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<InitListExpr, CXXParenListInitExpr>(
|
||||
LCtx->getParentMap().getParent(E))) {
|
||||
MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
|
||||
Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));
|
||||
CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true;
|
||||
@@ -1017,7 +1018,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<InitListExpr>(Init);
|
||||
bool isInitList =
|
||||
isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(Init);
|
||||
|
||||
QualType ObjTy =
|
||||
isInitList ? Init->getType() : CNE->getType()->getPointeeType();
|
||||
|
||||
19
clang/test/Analysis/PR135665.cpp
Normal file
19
clang/test/Analysis/PR135665.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
// RUN: %clang_analyze_cc1 -std=c++20 -analyzer-checker=core -verify %s
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
template<typename... F>
|
||||
struct overload : public F...
|
||||
{
|
||||
using F::operator()...;
|
||||
};
|
||||
|
||||
template<typename... F>
|
||||
overload(F&&...) -> overload<F...>;
|
||||
|
||||
int main()
|
||||
{
|
||||
const auto l = overload([](const int* i) {}); // no-crash
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user