Skip to content

Commit 0629e90

Browse files
ilya-biryukovyuxuanchen1997
authored andcommitted
[AST] NFC: add an assertion for invariant of CXXFoldExpr
CXXFoldExpr relies on exactly one of the two operands to have unexpanded parameter packs. If this invariant does not holds, results of `getPattern()`, `isLeftFold()` and other related members are incorrect. Asserting this on construction makes debugging the problems easier as the failure is happening closer to the code that contains the error. Also move the constructor to the `.cpp` file to avoid potential ODR violations from having an `assert` in the header in combination with precompiled libraries.
1 parent de357ca commit 0629e90

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

clang/include/clang/AST/ExprCXX.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4854,15 +4854,7 @@ class CXXFoldExpr : public Expr {
48544854
CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
48554855
SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode,
48564856
SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc,
4857-
std::optional<unsigned> NumExpansions)
4858-
: Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary),
4859-
LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
4860-
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
4861-
SubExprs[SubExpr::Callee] = Callee;
4862-
SubExprs[SubExpr::LHS] = LHS;
4863-
SubExprs[SubExpr::RHS] = RHS;
4864-
setDependence(computeDependence(this));
4865-
}
4857+
std::optional<unsigned> NumExpansions);
48664858

48674859
CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
48684860

clang/lib/AST/ExprCXX.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,3 +1944,22 @@ CXXParenListInitExpr *CXXParenListInitExpr::CreateEmpty(ASTContext &C,
19441944
alignof(CXXParenListInitExpr));
19451945
return new (Mem) CXXParenListInitExpr(Empty, NumExprs);
19461946
}
1947+
1948+
CXXFoldExpr::CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
1949+
SourceLocation LParenLoc, Expr *LHS,
1950+
BinaryOperatorKind Opcode,
1951+
SourceLocation EllipsisLoc, Expr *RHS,
1952+
SourceLocation RParenLoc,
1953+
std::optional<unsigned> NumExpansions)
1954+
: Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary), LParenLoc(LParenLoc),
1955+
EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
1956+
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
1957+
// We rely on asserted invariant to distinguish left and right folds.
1958+
assert(((LHS && LHS->containsUnexpandedParameterPack()) !=
1959+
(RHS && RHS->containsUnexpandedParameterPack())) &&
1960+
"Exactly one of LHS or RHS should contain an unexpanded pack");
1961+
SubExprs[SubExpr::Callee] = Callee;
1962+
SubExprs[SubExpr::LHS] = LHS;
1963+
SubExprs[SubExpr::RHS] = RHS;
1964+
setDependence(computeDependence(this));
1965+
}

0 commit comments

Comments
 (0)