- 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
^^^^^^^^^^^^^^^^^^^^^
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<
// 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;
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()
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;
}
+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
// dr2642: na
--- /dev/null
+// 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}:""
+}
+
<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>