[clang] [clang] Sequence C++20 Parenthesized List Init (PR #83476)

via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 29 12:23:06 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Douglas Deslauriers (vapdrs)

<details>
<summary>Changes</summary>

Parenthesized list intializers are sequenced operations, see C++20 [decl.init]p17.5 and [decl.init]p17.6.2.2 for more details.

Fixes #<!-- -->83474

---
Full diff: https://github.com/llvm/llvm-project/pull/83476.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaChecking.cpp (+19) 
- (added) clang/test/SemaCXX/warn-unsequenced-paren-list-init.cpp (+15) 


``````````diff
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 016e9830662042..eaa45378f8eb49 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -17626,6 +17626,25 @@ class SequenceChecker : public ConstEvaluatedExprVisitor<SequenceChecker> {
     for (unsigned I = 0; I < Elts.size(); ++I)
       Tree.merge(Elts[I]);
   }
+
+  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
+    // C++20 parenthesized list initializations are sequenced. See C++20
+    // [decl.init]p17.5 and [decl.init]p17.6.2.2
+    SmallVector<SequenceTree::Seq, 32> Elts;
+    SequenceTree::Seq Parent = Region;
+    for (const Expr *E : PLIE->getInitExprs()) {
+      if (!E)
+        continue;
+      Region = Tree.allocate(Parent);
+      Elts.push_back(Region);
+      Visit(E);
+    }
+
+    // Forget that the initializers are sequenced.
+    Region = Parent;
+    for (unsigned I = 0; I < Elts.size(); ++I)
+      Tree.merge(Elts[I]);
+  }
 };
 
 SequenceChecker::UsageInfo::UsageInfo() = default;
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'}}
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/83476


More information about the cfe-commits mailing list