This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG07008a8df57f: CWG2635: Disallow constrained structured 
bindings. (authored by erichkeane).
Herald added a project: clang.

Changed prior to commit:
  https://reviews.llvm.org/D138852?vs=478351&id=478381#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D138852/new/

https://reviews.llvm.org/D138852

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/drs/dr26xx.cpp
  clang/test/FixIt/fixit-constrained-structured-binding.cpp
  clang/www/cxx_dr_status.html

Index: clang/www/cxx_dr_status.html
===================================================================
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -15618,7 +15618,7 @@
     <td><a href="https://wg21.link/cwg2635";>2635</a></td>
     <td>DR</td>
     <td>Constrained structured bindings</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="unreleased" align="center">Clang 16</td>
   </tr>
   <tr id="2636">
     <td><a href="https://wg21.link/cwg2636";>2636</a></td>
Index: clang/test/FixIt/fixit-constrained-structured-binding.cpp
===================================================================
--- /dev/null
+++ clang/test/FixIt/fixit-constrained-structured-binding.cpp
@@ -0,0 +1,33 @@
+// RUN: not %clang_cc1 -std=c++20 -fdiagnostics-parseable-fixits -x c++ %s 2> %t
+// RUN: FileCheck %s < %t
+
+template<typename T>
+concept UnaryC = true;
+template<typename T, typename U>
+concept BinaryC = true;
+
+struct S{ int i, j; };
+S get_S();
+
+template<typename T>
+T get_T();
+
+void use() {
+  UnaryC auto [a, b] = get_S();
+  // CHECK: error: decomposition declaration cannot be declared with constrained 'auto'
+  // CHECK: fix-it:{{.*}}:{16:3-16:10}:""
+  BinaryC<int> auto [c, d] = get_S();
+  // CHECK: error: decomposition declaration cannot be declared with constrained 'auto'
+  // CHECK: fix-it:{{.*}}:{19:3-19:16}:""
+}
+
+template<typename T>
+void TemplUse() {
+  UnaryC auto [a, b] = get_T<T>();
+  // CHECK: error: decomposition declaration cannot be declared with constrained 'auto'
+  // XCHECK: fix-it:{{.*}}:{26:3-26:10}:""
+  BinaryC<T> auto [c, d] = get_T<T>();
+  // CHECK: error: decomposition declaration cannot be declared with constrained 'auto'
+  // XCHECK: fix-it:{{.*}}:{29:3-29:14}:""
+}
+
Index: clang/test/CXX/drs/dr26xx.cpp
===================================================================
--- clang/test/CXX/drs/dr26xx.cpp
+++ clang/test/CXX/drs/dr26xx.cpp
@@ -27,6 +27,34 @@
   // expected-note@#DR2628_CTOR {{marked deleted here}}
 }
 
+}
+
+namespace dr2635 { // dr2635: yes
+template<typename T>
+concept UnaryC = true;
+template<typename T, typename U>
+concept BinaryC = true;
+
+struct S{ int i, j; };
+S get_S();
+
+template<typename T>
+T get_T();
+
+void use() {
+  // expected-error@+1{{decomposition declaration cannot be declared with constrained 'auto'}}
+  UnaryC auto [a, b] = get_S();
+  // expected-error@+1{{decomposition declaration cannot be declared with constrained 'auto'}}
+  BinaryC<int> auto [c, d] = get_S();
+}
+
+template<typename T>
+void TemplUse() {
+  // expected-error@+1{{decomposition declaration cannot be declared with constrained 'auto'}}
+  UnaryC auto [a, b] = get_T<T>();
+  // expected-error@+1{{decomposition declaration cannot be declared with constrained 'auto'}}
+  BinaryC<T> auto [c, d] = get_T<T>();
+}
 }
 
   // dr2636: na
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -760,11 +760,16 @@
   // C++17 [dcl.dcl]/8:
   //   The decl-specifier-seq shall contain only the type-specifier auto
   //   and cv-qualifiers.
-  // C++2a [dcl.dcl]/8:
+  // C++20 [dcl.dcl]/8:
   //   If decl-specifier-seq contains any decl-specifier other than static,
   //   thread_local, auto, or cv-qualifiers, the program is ill-formed.
+  // C++2b [dcl.pre]/6:
+  //   Each decl-specifier in the decl-specifier-seq shall be static,
+  //   thread_local, auto (9.2.9.6 [dcl.spec.auto]), or a cv-qualifier.
   auto &DS = D.getDeclSpec();
   {
+    // Note: While constrained-auto needs to be checked, we do so separately so
+    // we can emit a better diagnostic.
     SmallVector<StringRef, 8> BadSpecifiers;
     SmallVector<SourceLocation, 8> BadSpecifierLocs;
     SmallVector<StringRef, 8> CPlusPlus20Specifiers;
@@ -791,6 +796,7 @@
       BadSpecifiers.push_back("inline");
       BadSpecifierLocs.push_back(DS.getInlineSpecLoc());
     }
+
     if (!BadSpecifiers.empty()) {
       auto &&Err = Diag(BadSpecifierLocs.front(), diag::err_decomp_decl_spec);
       Err << (int)BadSpecifiers.size()
@@ -851,6 +857,20 @@
       D.setInvalidType();
   }
 
+  // Constrained auto is prohibited by [decl.pre]p6, so check that here.
+  if (DS.isConstrainedAuto()) {
+    TemplateIdAnnotation *TemplRep = DS.getRepAsTemplateId();
+    assert(TemplRep->Kind == TNK_Concept_template &&
+           "No other template kind should be possible for a constrained auto");
+
+    SourceRange TemplRange{TemplRep->TemplateNameLoc,
+                           TemplRep->RAngleLoc.isValid()
+                               ? TemplRep->RAngleLoc
+                               : TemplRep->TemplateNameLoc};
+    Diag(TemplRep->TemplateNameLoc, diag::err_decomp_decl_constraint)
+        << TemplRange << FixItHint::CreateRemoval(TemplRange);
+  }
+
   // Build the BindingDecls.
   SmallVector<BindingDecl*, 8> Bindings;
 
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -492,6 +492,8 @@
 def err_decomp_decl_type : Error<
   "decomposition declaration cannot be declared with type %0; "
   "declared type must be 'auto' or reference to 'auto'">;
+def err_decomp_decl_constraint : Error<
+  "decomposition declaration cannot be declared with constrained 'auto'">;
 def err_decomp_decl_parens : Error<
   "decomposition declaration cannot be declared with parentheses">;
 def err_decomp_decl_template : Error<
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -655,6 +655,7 @@
 
 - Do not hide templated base members introduced via using-decl in derived class
   (useful specially for constrained members). Fixes `GH50886 <https://github.com/llvm/llvm-project/issues/50886>`_.
+- Implemented CWG2635 as a Defect Report, which prohibits structured bindings from being constrained.
 
 C++2b Feature Support
 ^^^^^^^^^^^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to