Skip to content

Commit 85958bd

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 856ce49 commit 85958bd

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17589,31 +17589,28 @@ class SequenceChecker : public ConstEvaluatedExprVisitor<SequenceChecker> {
1758917589
return VisitExpr(CCE);
1759017590

1759117591
// In C++11, list initializations are sequenced.
17592-
SmallVector<SequenceTree::Seq, 32> Elts;
17593-
SequenceTree::Seq Parent = Region;
17594-
for (CXXConstructExpr::const_arg_iterator I = CCE->arg_begin(),
17595-
E = CCE->arg_end();
17596-
I != E; ++I) {
17597-
Region = Tree.allocate(Parent);
17598-
Elts.push_back(Region);
17599-
Visit(*I);
17600-
}
17601-
17602-
// Forget that the initializers are sequenced.
17603-
Region = Parent;
17604-
for (unsigned I = 0; I < Elts.size(); ++I)
17605-
Tree.merge(Elts[I]);
17592+
SequenceExpressionsInOrder({CCE->getArgs(), CCE->getNumArgs()});
1760617593
}
1760717594

1760817595
void VisitInitListExpr(const InitListExpr *ILE) {
1760917596
if (!SemaRef.getLangOpts().CPlusPlus11)
1761017597
return VisitExpr(ILE);
1761117598

1761217599
// In C++11, list initializations are sequenced.
17600+
SequenceExpressionsInOrder(ILE->inits());
17601+
}
17602+
17603+
void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
17604+
// C++20 parenthesized list initializations are sequenced. See C++20
17605+
// [decl.init.general]p16.5 and [decl.init.general]p16.6.2.2.
17606+
SequenceExpressionsInOrder(PLIE->getInitExprs());
17607+
}
17608+
17609+
private:
17610+
void SequenceExpressionsInOrder(ArrayRef<const Expr *> ExpressionList) {
1761317611
SmallVector<SequenceTree::Seq, 32> Elts;
1761417612
SequenceTree::Seq Parent = Region;
17615-
for (unsigned I = 0; I < ILE->getNumInits(); ++I) {
17616-
const Expr *E = ILE->getInit(I);
17613+
for (const Expr *E : ExpressionList) {
1761717614
if (!E)
1761817615
continue;
1761917616
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)