[clang] [clang] Implement CWG2768 (PR #195101)

Victor Chernyakin via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 30 08:00:24 PDT 2026


https://github.com/localspook created https://github.com/llvm/llvm-project/pull/195101

[CWG2768](https://wg21.link/cwg2768) changes the semantics of `foo = {...};` when `foo` has scalar type. It used to create a temporary via direct-list-initialization, now it's via copy-list-initialization.

>From a73859ce3eba7c25b605835f32b514e84464a6a0 Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <chernyakin.victor.j at outlook.com>
Date: Thu, 30 Apr 2026 07:59:36 -0700
Subject: [PATCH] [clang] Implement CWG2768

---
 clang/lib/Sema/SemaExpr.cpp    | 13 ++++++++-----
 clang/test/CXX/drs/cwg27xx.cpp | 21 +++++++++++++++++++++
 clang/www/cxx_dr_status.html   |  2 +-
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c494669420282..7468f6d0b9c5e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -15466,11 +15466,14 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
     // The syntax only allows initializer lists on the RHS of assignment,
     // so we don't need to worry about accepting invalid code for
     // non-assignment operators.
-    // C++11 5.17p9:
-    //   The meaning of x = {v} [...] is that of x = T(v) [...]. The meaning
-    //   of x = {} is x = T().
-    InitializationKind Kind = InitializationKind::CreateDirectList(
-        RHSExpr->getBeginLoc(), RHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
+    // C++ [expr.assign]/8:
+    //   A braced-init-list B may appear on the right-hand side of
+    //      - an assignment to a scalar of type T, in which case B shall have at
+    //        most a single element. The meaning of x = B is x = t, where t is
+    //        an invented temporary variable declared and initialized as T t =
+    //        B.
+    InitializationKind Kind =
+        InitializationKind::CreateCopy(RHSExpr->getBeginLoc(), OpLoc);
     InitializedEntity Entity =
         InitializedEntity::InitializeTemporary(LHSExpr->getType());
     InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr);
diff --git a/clang/test/CXX/drs/cwg27xx.cpp b/clang/test/CXX/drs/cwg27xx.cpp
index ae5874ce3c46d..6721020a0a283 100644
--- a/clang/test/CXX/drs/cwg27xx.cpp
+++ b/clang/test/CXX/drs/cwg27xx.cpp
@@ -174,6 +174,27 @@ static_assert(!__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion3)
 #endif
 } // namespace cwg2759
 
+namespace cwg2768 { // cwg2768: 23
+#if __cplusplus >= 201103L
+void test() {
+  enum class E { E1 };
+
+  E e;
+  e = {0};
+  // expected-error at -1 {{cannot initialize a value of type 'E' with an rvalue of type 'int'}}
+
+  struct NotImplicitlyConvertibleToInt {
+    explicit operator int(); // #cwg2768-conversion-operator
+  };
+
+  int i;
+  i = {NotImplicitlyConvertibleToInt{}};
+  // expected-error at -1 {{no viable conversion from 'NotImplicitlyConvertibleToInt' to 'int'}}
+  //   expected-note@#cwg2768-conversion-operator {{explicit conversion function is not a candidate}}
+}
+#endif
+} // namespace cwg2768
+
 namespace cwg2770 { // cwg2770: 20 open 2023-07-14
 #if __cplusplus >= 202002L
 template<typename T>
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 2a1e79471ceea..2d9432640c099 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -19181,7 +19181,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
     <td>[<a href="https://wg21.link/expr.assign">expr.assign</a>]</td>
     <td>CD7</td>
     <td>Assignment to enumeration variable with a <I>braced-init-list</I></td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="unreleased" align="center">Clang 23</td>
   </tr>
   <tr class="open" id="2769">
     <td><a href="https://cplusplus.github.io/CWG/issues/2769.html">2769</a></td>



More information about the cfe-commits mailing list