Skip to content

Commit 4ce737b

Browse files
authored
[clang] Sequence C++20 Parenthesized List Init (#83476)
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 0d8e16a commit 4ce737b

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
@@ -17624,31 +17624,29 @@ class SequenceChecker : public ConstEvaluatedExprVisitor<SequenceChecker> {
1762417624
return VisitExpr(CCE);
1762517625

1762617626
// In C++11, list initializations are sequenced.
17627-
SmallVector<SequenceTree::Seq, 32> Elts;
17628-
SequenceTree::Seq Parent = Region;
17629-
for (CXXConstructExpr::const_arg_iterator I = CCE->arg_begin(),
17630-
E = CCE->arg_end();
17631-
I != E; ++I) {
17632-
Region = Tree.allocate(Parent);
17633-
Elts.push_back(Region);
17634-
Visit(*I);
17635-
}
17636-
17637-
// Forget that the initializers are sequenced.
17638-
Region = Parent;
17639-
for (unsigned I = 0; I < Elts.size(); ++I)
17640-
Tree.merge(Elts[I]);
17627+
SequenceExpressionsInOrder(
17628+
llvm::ArrayRef(CCE->getArgs(), CCE->getNumArgs()));
1764117629
}
1764217630

1764317631
void VisitInitListExpr(const InitListExpr *ILE) {
1764417632
if (!SemaRef.getLangOpts().CPlusPlus11)
1764517633
return VisitExpr(ILE);
1764617634

1764717635
// In C++11, list initializations are sequenced.
17636+
SequenceExpressionsInOrder(ILE->inits());
17637+
}
17638+
17639+
void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
17640+
// C++20 parenthesized list initializations are sequenced. See C++20
17641+
// [decl.init.general]p16.5 and [decl.init.general]p16.6.2.2.
17642+
SequenceExpressionsInOrder(PLIE->getInitExprs());
17643+
}
17644+
17645+
private:
17646+
void SequenceExpressionsInOrder(ArrayRef<const Expr *> ExpressionList) {
1764817647
SmallVector<SequenceTree::Seq, 32> Elts;
1764917648
SequenceTree::Seq Parent = Region;
17650-
for (unsigned I = 0; I < ILE->getNumInits(); ++I) {
17651-
const Expr *E = ILE->getInit(I);
17649+
for (const Expr *E : ExpressionList) {
1765217650
if (!E)
1765317651
continue;
1765417652
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)