[clang] [clang] Sequence C++20 Parenthesized List Init (PR #83476)
Douglas Deslauriers via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 1 05:15:01 PST 2024
https://github.com/vapdrs updated https://github.com/llvm/llvm-project/pull/83476
>From f66254c6be64a7270ce2df8556c540344ade0619 Mon Sep 17 00:00:00 2001
From: Douglas Deslauriers <Douglas.Deslauriers at vector.com>
Date: Thu, 29 Feb 2024 20:18:34 +0000
Subject: [PATCH] [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
---
clang/lib/Sema/SemaChecking.cpp | 30 +++++++++----------
.../warn-unsequenced-paren-list-init.cpp | 15 ++++++++++
2 files changed, 29 insertions(+), 16 deletions(-)
create mode 100644 clang/test/SemaCXX/warn-unsequenced-paren-list-init.cpp
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 7be2b31df2413f..e14b8600818c1b 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -17617,20 +17617,8 @@ class SequenceChecker : public ConstEvaluatedExprVisitor<SequenceChecker> {
return VisitExpr(CCE);
// In C++11, list initializations are sequenced.
- SmallVector<SequenceTree::Seq, 32> Elts;
- SequenceTree::Seq Parent = Region;
- for (CXXConstructExpr::const_arg_iterator I = CCE->arg_begin(),
- E = CCE->arg_end();
- I != E; ++I) {
- Region = Tree.allocate(Parent);
- Elts.push_back(Region);
- Visit(*I);
- }
-
- // Forget that the initializers are sequenced.
- Region = Parent;
- for (unsigned I = 0; I < Elts.size(); ++I)
- Tree.merge(Elts[I]);
+ SequenceExpressionsInOrder(
+ llvm::ArrayRef(CCE->getArgs(), CCE->getNumArgs()));
}
void VisitInitListExpr(const InitListExpr *ILE) {
@@ -17638,10 +17626,20 @@ class SequenceChecker : public ConstEvaluatedExprVisitor<SequenceChecker> {
return VisitExpr(ILE);
// In C++11, list initializations are sequenced.
+ SequenceExpressionsInOrder(ILE->inits());
+ }
+
+ void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
+ // C++20 parenthesized list initializations are sequenced. See C++20
+ // [decl.init.general]p16.5 and [decl.init.general]p16.6.2.2.
+ SequenceExpressionsInOrder(PLIE->getInitExprs());
+ }
+
+private:
+ void SequenceExpressionsInOrder(ArrayRef<const Expr *> ExpressionList) {
SmallVector<SequenceTree::Seq, 32> Elts;
SequenceTree::Seq Parent = Region;
- for (unsigned I = 0; I < ILE->getNumInits(); ++I) {
- const Expr *E = ILE->getInit(I);
+ for (const Expr *E : ExpressionList) {
if (!E)
continue;
Region = Tree.allocate(Parent);
diff --git a/clang/test/SemaCXX/warn-unsequenced-paren-list-init.cpp b/clang/test/SemaCXX/warn-unsequenced-paren-list-init.cpp
new file mode 100644
index 00000000000000..5aeeb45f81e226
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unsequenced-paren-list-init.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -Wno-unused -Wunsequenced -verify %s
+
+struct A {
+ int x, y;
+};
+
+void test() {
+ int a = 0;
+
+ A agg1( a++, a++ ); // no warning
+ A agg2( a++ + a, a++ ); // expected-warning {{unsequenced modification and access to 'a'}}
+
+ int arr1[]( a++, a++ ); // no warning
+ int arr2[]( a++ + a, a++ ); // expected-warning {{unsequenced modification and access to 'a'}}
+}
More information about the cfe-commits
mailing list