Skip to content

Commit f66254c

Browse files
committed
[clang] Sequence C++20 Parenthesized List Init
Parenthesized list intializers are sequenced operations, see C++20 [decl.init]p16.5 and [decl.init]p16.6.2.2 for more details. Fixes #83474
1 parent 756166e commit f66254c

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17617,31 +17617,29 @@ class SequenceChecker : public ConstEvaluatedExprVisitor<SequenceChecker> {
1761717617
return VisitExpr(CCE);
1761817618

1761917619
// In C++11, list initializations are sequenced.
17620-
SmallVector<SequenceTree::Seq, 32> Elts;
17621-
SequenceTree::Seq Parent = Region;
17622-
for (CXXConstructExpr::const_arg_iterator I = CCE->arg_begin(),
17623-
E = CCE->arg_end();
17624-
I != E; ++I) {
17625-
Region = Tree.allocate(Parent);
17626-
Elts.push_back(Region);
17627-
Visit(*I);
17628-
}
17629-
17630-
// Forget that the initializers are sequenced.
17631-
Region = Parent;
17632-
for (unsigned I = 0; I < Elts.size(); ++I)
17633-
Tree.merge(Elts[I]);
17620+
SequenceExpressionsInOrder(
17621+
llvm::ArrayRef(CCE->getArgs(), CCE->getNumArgs()));
1763417622
}
1763517623

1763617624
void VisitInitListExpr(const InitListExpr *ILE) {
1763717625
if (!SemaRef.getLangOpts().CPlusPlus11)
1763817626
return VisitExpr(ILE);
1763917627

1764017628
// In C++11, list initializations are sequenced.
17629+
SequenceExpressionsInOrder(ILE->inits());
17630+
}
17631+
17632+
void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
17633+
// C++20 parenthesized list initializations are sequenced. See C++20
17634+
// [decl.init.general]p16.5 and [decl.init.general]p16.6.2.2.
17635+
SequenceExpressionsInOrder(PLIE->getInitExprs());
17636+
}
17637+
17638+
private:
17639+
void SequenceExpressionsInOrder(ArrayRef<const Expr *> ExpressionList) {
1764117640
SmallVector<SequenceTree::Seq, 32> Elts;
1764217641
SequenceTree::Seq Parent = Region;
17643-
for (unsigned I = 0; I < ILE->getNumInits(); ++I) {
17644-
const Expr *E = ILE->getInit(I);
17642+
for (const Expr *E : ExpressionList) {
1764517643
if (!E)
1764617644
continue;
1764717645
Region = Tree.allocate(Parent);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %clang_cc1 -fsyntax-only -std=c++20 -Wno-unused -Wunsequenced -verify %s
2+
3+
struct A {
4+
int x, y;
5+
};
6+
7+
void test() {
8+
int a = 0;
9+
10+
A agg1( a++, a++ ); // no warning
11+
A agg2( a++ + a, a++ ); // expected-warning {{unsequenced modification and access to 'a'}}
12+
13+
int arr1[]( a++, a++ ); // no warning
14+
int arr2[]( a++ + a, a++ ); // expected-warning {{unsequenced modification and access to 'a'}}
15+
}

0 commit comments

Comments
 (0)