[clang] 4ce737b - [clang] Sequence C++20 Parenthesized List Init (#83476)

via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 5 06:07:59 PST 2024


Author: Douglas Deslauriers
Date: 2024-03-05T15:07:54+01:00
New Revision: 4ce737bfd6fd0aafb436eb220c3e724bfc831db4

URL: https://github.com/llvm/llvm-project/commit/4ce737bfd6fd0aafb436eb220c3e724bfc831db4
DIFF: https://github.com/llvm/llvm-project/commit/4ce737bfd6fd0aafb436eb220c3e724bfc831db4.diff

LOG: [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

Added: 
    clang/test/SemaCXX/warn-unsequenced-paren-list-init.cpp

Modified: 
    clang/lib/Sema/SemaChecking.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0d4d57db01c93a..2cda1d08784ece 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -17624,20 +17624,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) {
@@ -17645,10 +17633,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