Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,8 @@ Static Analyzer
---------------
- Fixed a crash when C++20 parenthesized initializer lists are used. This issue
was causing a crash in clang-tidy. (#GH136041)
- The Clang Static Analyzer now handles parenthesized initialization.
(#GH148875)

New features
^^^^^^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,9 @@ class ExprEngine {
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
ExplodedNodeSet &Dst);

void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE,
ExplodedNode *Pred, ExplodedNodeSet &Dst);

/// Create a C++ temporary object for an rvalue.
void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
ExplodedNode *Pred,
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1941,7 +1941,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::ConceptSpecializationExprClass:
case Stmt::CXXRewrittenBinaryOperatorClass:
case Stmt::RequiresExprClass:
case Expr::CXXParenListInitExprClass:
case Stmt::EmbedExprClass:
// Fall through.

Expand Down Expand Up @@ -2321,6 +2320,12 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
Bldr.addNodes(Dst);
break;

case Expr::CXXParenListInitExprClass:
Bldr.takeNodes(Pred);
VisitCXXParenListInitExpr(cast<CXXParenListInitExpr>(S), Pred, Dst);
Bldr.addNodes(Dst);
break;

case Stmt::MemberExprClass:
Bldr.takeNodes(Pred);
VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst);
Expand Down
28 changes: 28 additions & 0 deletions clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1233,3 +1233,31 @@ void ExprEngine::VisitAttributedStmt(const AttributedStmt *A,

getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, A, *this);
}

void ExprEngine::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
const LocationContext *LC = Pred->getLocationContext();

StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
ProgramStateRef S = Pred->getState();

QualType T = E->getType().getCanonicalType();
ArrayRef<Expr *> Inits = E->getInitExprs();

if (Inits.size() > 1 ||
(E->isPRValue() && (T->isRecordType() || T->isArrayType()))) {
llvm::ImmutableList<SVal> ArgList = getBasicVals().getEmptySValList();
for (Expr *E : llvm::reverse(Inits))
ArgList = getBasicVals().prependSVal(S->getSVal(E, LC), ArgList);

Bldr.generateNode(
E, Pred, S->BindExpr(E, LC, svalBuilder.makeCompoundVal(T, ArgList)));
} else {
Bldr.generateNode(E, Pred,
S->BindExpr(E, LC,
Inits.size() == 0
? getSValBuilder().makeZeroVal(T)
: S->getSVal(Inits.front(), LC)));
}
}
52 changes: 52 additions & 0 deletions clang/test/Analysis/div-zero-cxx20.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core.DivideZero -std=c++20 -verify %s

namespace GH148875 {
struct A {
int x;
A(int v) : x(v) {}
};

struct B {
int x;
B() : x(0) {}
};

struct C {
int x, y;
C(int a, int b) : x(a), y(b) {}
};

struct D {
int x;
};

struct E {
D d;
E(int a) : d(a) {}
};

int t1() {
A a(42);
return 1 / (a.x - 42); // expected-warning {{Division by zero}}
}

int t2() {
B b;
return 1 / b.x; // expected-warning {{Division by zero}}
}

int t3() {
C c1(1, -1);
return 1 / (c1.x + c1.y); // expected-warning {{Division by zero}}
}

int t4() {
C c2(0, 0);
return 1 / (c2.x + c2.y); // expected-warning {{Division by zero}}
}

int t5() {
E e = 32;
return 1 / (e.d.x - 32); // expected-warning {{Division by zero}}
}
} // namespace GH148875