From b36c8d658e2dd86bb0a190c48fda83839c6b8d63 Mon Sep 17 00:00:00 2001 From: foxfromabyss Date: Sun, 12 Oct 2025 23:00:24 +0200 Subject: [PATCH 1/5] [Clang][Diagnostics] Use "structured binding" instead of "decomposition" P0615R0 changed the term "decomposition" to "structured binding". Some diagnostic messages were created before this paper. These messages should be updated using "structured binding" to avoid making users confused. See for context: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0615r0.html --- .../clang/Basic/DiagnosticParseKinds.td | 7 +- .../clang/Basic/DiagnosticSemaKinds.td | 107 +++++++++--------- .../test/Analysis/zero-size-non-pod-array.cpp | 2 +- clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp | 4 +- clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp | 10 +- clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp | 26 ++--- clang/test/CXX/drs/cwg22xx.cpp | 2 +- clang/test/CXX/drs/cwg23xx.cpp | 2 +- clang/test/CXX/drs/cwg26xx.cpp | 8 +- .../stmt.stmt/stmt.iter/stmt.ranged/p1.cpp | 2 +- .../test/CXX/temp/temp.res/temp.local/p6.cpp | 2 +- .../fixit-constrained-structured-binding.cpp | 8 +- clang/test/PCH/cxx1z-decomposition.cpp | 4 +- ...xx1z-class-template-argument-deduction.cpp | 6 +- clang/test/Parser/cxx1z-decomposition.cpp | 14 +-- clang/test/Parser/cxx2c-binding-pack.cpp | 2 +- .../builtin-structured-binding-size.cpp | 40 +++---- clang/test/SemaCXX/cxx17-compat.cpp | 12 +- clang/test/SemaCXX/cxx1z-decomposition.cpp | 30 ++--- .../cxx2c-binding-pack-nontemplate.cpp | 2 +- clang/test/SemaCXX/cxx2c-binding-pack.cpp | 6 +- clang/test/SemaCXX/sizeless-1.cpp | 2 +- clang/test/SemaCXX/warn-shadow-in-lambdas.cpp | 4 +- .../test/SemaTemplate/cxx1z-decomposition.cpp | 2 +- 24 files changed, 152 insertions(+), 152 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index c724136a7fdaf..5fc74cb8155b6 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -504,9 +504,10 @@ def err_expected_end_of_enumerator : Error< def err_expected_coloncolon_after_super : Error< "expected '::' after '__super'">; -def ext_decomp_decl_empty : ExtWarn< - "ISO C++17 does not allow a decomposition group to be empty">, - InGroup>; +def ext_decomp_decl_empty + : ExtWarn< + "ISO C++17 does not allow a structured binding group to be empty">, + InGroup>; def err_function_parameter_limit_exceeded : Error< "too many function parameters; subsequent parameters will be ignored">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 3df28f2ef3334..0abf14cbe7428 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -31,12 +31,12 @@ defm constexpr_body_multiple_return : CXX14Compat< defm variable_template : CXX14Compat<"variable templates are">; // C++17 compatibility with C++14 and earlier. -defm decomp_decl : CXX17Compat<"decomposition declarations are">; +defm decomp_decl : CXX17Compat<"structured binding declarations are">; defm inline_variable : CXX17Compat<"inline variables are">; // C++20 compatibility with C++17 and earlier. defm decomp_decl_spec - : CXX20Compat<"decomposition declaration declared '%0' is">; + : CXX20Compat<"structured binding declaration declared '%0' is">; defm constexpr_local_var_no_init : CXX20Compat< "uninitialized variable in a constexpr %select{function|constructor}0 is">; defm constexpr_function_try_block : CXX20Compat< @@ -589,60 +589,59 @@ def warn_modifying_shadowing_decl : "field of %1">, InGroup, DefaultIgnore; -// C++ decomposition declarations -def err_decomp_decl_context : Error< - "decomposition declaration not permitted in this context">; +// C++ structured binding declarations +def err_decomp_decl_context + : Error<"structured binding declaration not permitted in this context">; def err_decomp_decl_spec - : Error<"decomposition declaration cannot be declared '%0'">; -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< - "decomposition declaration cannot be a template">; -def err_decomp_decl_not_alone : Error< - "decomposition declaration must be the only declaration in its group">; -def err_decomp_decl_requires_init : Error< - "decomposition declaration %0 requires an initializer">; -def err_decomp_decl_wrong_number_bindings : Error< - "type %0 decomposes into %3 %plural{1:element|:elements}2, but " - "%select{%plural{0:no|:only %1}1|%1}4 " - "%plural{1:name was|:names were}1 provided">; -def err_decomp_decl_unbindable_type : Error< - "cannot decompose %select{union|non-class, non-array}1 type %2">; -def err_decomp_decl_multiple_bases_with_members : Error< - "cannot decompose class type %1: " - "%select{its base classes %2 and|both it and its base class}0 %3 " - "have non-static data members">; -def err_decomp_decl_ambiguous_base : Error< - "cannot decompose members of ambiguous base class %1 of %0:%2">; -def err_decomp_decl_inaccessible_base : Error< - "cannot decompose members of inaccessible base class %1 of %0">, - AccessControl; -def err_decomp_decl_inaccessible_field : Error< - "cannot decompose %select{private|protected}0 member %1 of %3">, - AccessControl; -def err_decomp_decl_lambda : Error< - "cannot decompose lambda closure type">; -def err_decomp_decl_anon_union_member : Error< - "cannot decompose class type %0 because it has an anonymous " - "%select{struct|union}1 member">; -def err_decomp_decl_std_tuple_element_not_specialized : Error< - "cannot decompose this type; 'std::tuple_element<%0>::type' " - "does not name a type">; -def err_decomp_decl_std_tuple_size_not_constant : Error< - "cannot decompose this type; 'std::tuple_size<%0>::value' " - "is not a valid integral constant expression">; + : Error<"structured binding declaration cannot be declared '%0'">; +def err_decomp_decl_type + : Error<"structured binding declaration cannot be declared with type %0; " + "declared type must be 'auto' or reference to 'auto'">; +def err_decomp_decl_constraint : Error<"structured binding declaration cannot " + "be declared with constrained 'auto'">; +def err_decomp_decl_parens + : Error< + "structured binding declaration cannot be declared with parentheses">; +def err_decomp_decl_template + : Error<"structured binding declaration cannot be a template">; +def err_decomp_decl_not_alone : Error<"structured binding declaration must be " + "the only declaration in its group">; +def err_decomp_decl_requires_init + : Error<"structured binding declaration %0 requires an initializer">; +def err_decomp_decl_wrong_number_bindings + : Error<"type %0 binds to %3 %plural{1:element|:elements}2, but " + "%select{%plural{0:no|:only %1}1|%1}4 " + "%plural{1:name was|:names were}1 provided">; +def err_decomp_decl_unbindable_type + : Error<"cannot bind %select{union|non-class, non-array}1 type %2">; +def err_decomp_decl_multiple_bases_with_members + : Error<"cannot bind class type %1: " + "%select{its base classes %2 and|both it and its base class}0 %3 " + "have non-static data members">; +def err_decomp_decl_ambiguous_base + : Error<"cannot bind members of ambiguous base class %1 of %0:%2">; +def err_decomp_decl_inaccessible_base + : Error<"cannot bind members of inaccessible base class %1 of %0">, + AccessControl; +def err_decomp_decl_inaccessible_field + : Error<"cannot bind %select{private|protected}0 member %1 of %3">, + AccessControl; +def err_decomp_decl_lambda : Error<"cannot bind lambda closure type">; +def err_decomp_decl_anon_union_member + : Error<"cannot bind class type %0 because it has an anonymous " + "%select{struct|union}1 member">; +def err_decomp_decl_std_tuple_element_not_specialized + : Error<"cannot bind this type; 'std::tuple_element<%0>::type' " + "does not name a type">; +def err_decomp_decl_std_tuple_size_not_constant + : Error<"cannot bind this type; 'std::tuple_size<%0>::value' " + "is not a valid integral constant expression">; def err_decomp_decl_std_tuple_size_invalid - : Error<"cannot decompose this type; 'std::tuple_size<%0>::value' " + : Error<"cannot bind this type; 'std::tuple_size<%0>::value' " "is not a valid size: %1">; def note_in_binding_decl_init : Note< "in implicit initialization of binding declaration %0">; -def err_arg_is_not_destructurable : Error< - "type %0 cannot be decomposed">; +def err_arg_is_not_destructurable : Error<"type %0 cannot be bound">; def err_std_type_trait_not_class_template : Error< "unsupported standard library implementation: " @@ -2618,9 +2617,9 @@ def err_auto_variable_cannot_appear_in_own_initializer "%VarTemplateExplicitSpec{variable template explicit " "specialization}}0 %1 " "declared with deduced type %2 cannot appear in its own initializer">; -def err_binding_cannot_appear_in_own_initializer : Error< - "binding %0 cannot appear in the initializer of its own " - "decomposition declaration">; +def err_binding_cannot_appear_in_own_initializer + : Error<"binding %0 cannot appear in the initializer of its own " + "structured binding declaration">; def err_new_array_of_auto : Error< "cannot allocate array of 'auto'">; def err_auto_not_allowed : Error< diff --git a/clang/test/Analysis/zero-size-non-pod-array.cpp b/clang/test/Analysis/zero-size-non-pod-array.cpp index 628be0d7896e0..8a32a4989613e 100644 --- a/clang/test/Analysis/zero-size-non-pod-array.cpp +++ b/clang/test/Analysis/zero-size-non-pod-array.cpp @@ -95,7 +95,7 @@ void zeroSizeArrayBinding() { // Note: This is an error in gcc but a warning in clang. // In MSVC the declaration of 'S arr[0]' is already an error // and it doesn't recognize this syntax as a structured binding. - auto [] = arr; //expected-warning{{ISO C++17 does not allow a decomposition group to be empty}} + auto [] = arr; //expected-warning{{ISO C++17 does not allow a structured binding group to be empty}} clang_analyzer_eval(S::CtorInvocationCount == 0); //expected-warning{{TRUE}} } diff --git a/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp b/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp index cad7d8e89ce0f..717ea3aaa2276 100644 --- a/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp +++ b/clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp @@ -16,8 +16,8 @@ int array() { using X3 = X[3]; auto [a3, b3, c3] = X3{1, 2, 3}; - auto &[d, e] = arr; // expected-error {{type 'int[3]' decomposes into 3 elements, but only 2 names were provided}} - auto &[f, g, h, i] = arr; // expected-error {{type 'int[3]' decomposes into 3 elements, but 4 names were provided}} + auto &[d, e] = arr; // expected-error {{type 'int[3]' binds to 3 elements, but only 2 names were provided}} + auto &[f, g, h, i] = arr; // expected-error {{type 'int[3]' binds to 3 elements, but 4 names were provided}} auto &[r0, r1, r2] = arr; const auto &[cr0, cr1, cr2] = arr; diff --git a/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp b/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp index ce5eefc6bfdb4..b7fef12a40b38 100644 --- a/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp +++ b/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp @@ -5,10 +5,10 @@ using size_t = decltype(sizeof(0)); struct A { int x, y; }; struct B { int x, y; }; -void no_tuple_size_1() { auto [x, y] = A(); } // ok, decompose elementwise +void no_tuple_size_1() { auto [x, y] = A(); } // ok, bind elementwise namespace std { template struct tuple_size; } -void no_tuple_size_2() { auto [x, y] = A(); } // ok, decompose elementwise +void no_tuple_size_2() { auto [x, y] = A(); } // ok, bind elementwise struct Bad1 { int a, b; }; template<> struct std::tuple_size {}; @@ -16,15 +16,15 @@ void no_tuple_size_3() { auto [x, y] = Bad1(); } // ok, omitting value is valid struct Bad2 {}; template<> struct std::tuple_size { const int value = 5; }; -void no_tuple_size_4() { auto [x, y] = Bad2(); } // expected-error {{cannot decompose this type; 'std::tuple_size::value' is not a valid integral constant expression}} +void no_tuple_size_4() { auto [x, y] = Bad2(); } // expected-error {{cannot bind this type; 'std::tuple_size::value' is not a valid integral constant expression}} template<> struct std::tuple_size { static const int value = 3; }; template<> struct std::tuple_size { enum { value = 3 }; }; void no_get_1() { { - auto [a0, a1] = A(); // expected-error {{decomposes into 3 elements}} - auto [b0, b1] = B(); // expected-error {{decomposes into 3 elements}} + auto [a0, a1] = A(); // expected-error {{binds to 3 elements}} + auto [b0, b1] = B(); // expected-error {{binds to 3 elements}} } auto [a0, a1, a2] = A(); // expected-error {{undeclared identifier 'get'}} expected-note {{in implicit initialization of binding declaration 'a0'}} } diff --git a/clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp b/clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp index 7141124768e01..532a967aa8f76 100644 --- a/clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp +++ b/clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp @@ -25,10 +25,10 @@ namespace NonPublicMembers { struct NonPublic4 : NonPublic2 {}; void test() { - auto [a1] = NonPublic1(); // expected-error {{cannot decompose protected member 'a' of 'NonPublicMembers::NonPublic1'}} - auto [a2] = NonPublic2(); // expected-error {{cannot decompose private member 'a' of 'NonPublicMembers::NonPublic2'}} - auto [a3] = NonPublic3(); // expected-error {{cannot decompose members of inaccessible base class 'A' of 'NonPublicMembers::NonPublic3'}} - auto [a4] = NonPublic4(); // expected-error {{cannot decompose private member 'a' of 'NonPublicMembers::NonPublic2'}} + auto [a1] = NonPublic1(); // expected-error {{cannot bind protected member 'a' of 'NonPublicMembers::NonPublic1'}} + auto [a2] = NonPublic2(); // expected-error {{cannot bind private member 'a' of 'NonPublicMembers::NonPublic2'}} + auto [a3] = NonPublic3(); // expected-error {{cannot bind members of inaccessible base class 'A' of 'NonPublicMembers::NonPublic3'}} + auto [a4] = NonPublic4(); // expected-error {{cannot bind private member 'a' of 'NonPublicMembers::NonPublic2'}} } } @@ -46,8 +46,8 @@ namespace AnonymousMember { }; void test() { - auto [a1] = Struct(); // expected-error {{cannot decompose class type 'Struct' because it has an anonymous struct member}} - auto [a2] = Union(); // expected-error {{cannot decompose class type 'Union' because it has an anonymous union member}} + auto [a1] = Struct(); // expected-error {{cannot bind class type 'Struct' because it has an anonymous struct member}} + auto [a2] = Union(); // expected-error {{cannot bind class type 'Union' because it has an anonymous union member}} } } @@ -73,12 +73,12 @@ namespace MultipleClasses { struct M : virtual J, L {}; void test() { - auto [b] = B(); // expected-error {{cannot decompose class type 'B': both it and its base class 'A' have non-static data members}} - auto [d] = D(); // expected-error {{cannot decompose class type 'D': its base classes 'A' and 'C' have non-static data members}} + auto [b] = B(); // expected-error {{cannot bind class type 'B': both it and its base class 'A' have non-static data members}} + auto [d] = D(); // expected-error {{cannot bind class type 'D': its base classes 'A' and 'C' have non-static data members}} auto [e] = E(); - auto [f] = F(); // expected-error-re {{cannot decompose members of ambiguous base class 'A' of 'F':{{.*}}struct MultipleClasses::F -> A{{.*}}struct MultipleClasses::F -> E -> A}} + auto [f] = F(); // expected-error-re {{cannot bind members of ambiguous base class 'A' of 'F':{{.*}}struct MultipleClasses::F -> A{{.*}}struct MultipleClasses::F -> E -> A}} auto [h] = H(); // ok, only one (virtual) base subobject even though there are two paths to it - auto [k] = K(); // expected-error {{cannot decompose members of ambiguous base class 'I'}} + auto [k] = K(); // expected-error {{cannot bind members of ambiguous base class 'I'}} auto [m] = M(); // ok, all paths to I are through the same virtual base subobject J same(); @@ -214,7 +214,7 @@ namespace p0969r0 { auto &[x, y] = b; } void test_external(B b) { - auto &[x, y] = b; // expected-error {{cannot decompose members of inaccessible base class 'A' of 'p0969r0::B'}} + auto &[x, y] = b; // expected-error {{cannot bind members of inaccessible base class 'A' of 'p0969r0::B'}} } struct C { @@ -229,13 +229,13 @@ namespace p0969r0 { struct D : C { static void test_member(D d, C c) { auto &[x1, y1] = d; - auto &[x2, y2] = c; // expected-error {{cannot decompose protected member 'y' of 'p0969r0::C'}} + auto &[x2, y2] = c; // expected-error {{cannot bind protected member 'y' of 'p0969r0::C'}} } }; void test_friend(D d) { auto &[x, y] = d; } void test_external(D d) { - auto &[x, y] = d; // expected-error {{cannot decompose protected member 'y' of 'p0969r0::C'}} + auto &[x, y] = d; // expected-error {{cannot bind protected member 'y' of 'p0969r0::C'}} } } diff --git a/clang/test/CXX/drs/cwg22xx.cpp b/clang/test/CXX/drs/cwg22xx.cpp index 8c8ad9f7f74ee..34119a162623e 100644 --- a/clang/test/CXX/drs/cwg22xx.cpp +++ b/clang/test/CXX/drs/cwg22xx.cpp @@ -202,7 +202,7 @@ namespace cwg2285 { // cwg2285: 4 void test() { using T = int[1]; auto [a] = T{a}; - // since-cxx17-error@-1 {{binding 'a' cannot appear in the initializer of its own decomposition declaration}} + // since-cxx17-error@-1 {{binding 'a' cannot appear in the initializer of its own structured binding declaration}} } #endif } // namespace cwg2285 diff --git a/clang/test/CXX/drs/cwg23xx.cpp b/clang/test/CXX/drs/cwg23xx.cpp index 128566537b577..72cf249f8b53d 100644 --- a/clang/test/CXX/drs/cwg23xx.cpp +++ b/clang/test/CXX/drs/cwg23xx.cpp @@ -440,7 +440,7 @@ template <> struct tuple_size { namespace cwg2386 { void no_value() { auto [x, y] = Bad1(); } void wrong_value() { auto [x, y] = Bad2(); } -// since-cxx17-error@-1 {{type 'Bad2' decomposes into 42 elements, but only 2 names were provided}} +// since-cxx17-error@-1 {{type 'Bad2' binds to 42 elements, but only 2 names were provided}} #endif } // namespace cwg2386 diff --git a/clang/test/CXX/drs/cwg26xx.cpp b/clang/test/CXX/drs/cwg26xx.cpp index bceef6419b00a..aa87f5a1857c6 100644 --- a/clang/test/CXX/drs/cwg26xx.cpp +++ b/clang/test/CXX/drs/cwg26xx.cpp @@ -183,17 +183,17 @@ T get_T(); void use() { UnaryC auto [a, b] = get_S(); - // since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}} + // since-cxx20-error@-1 {{structured binding declaration cannot be declared with constrained 'auto'}} BinaryC auto [c, d] = get_S(); - // since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}} + // since-cxx20-error@-1 {{structured binding declaration cannot be declared with constrained 'auto'}} } template void TemplUse() { UnaryC auto [a, b] = get_T(); - // since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}} + // since-cxx20-error@-1 {{structured binding declaration cannot be declared with constrained 'auto'}} BinaryC auto [c, d] = get_T(); - // since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}} + // since-cxx20-error@-1 {{structured binding declaration cannot be declared with constrained 'auto'}} } #endif } // namespace cwg2635 diff --git a/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp index 93c2beb5ba1fe..938a3d096ae37 100644 --- a/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp +++ b/clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -75,7 +75,7 @@ namespace X { void test_D() { #if __cplusplus >= 201703L for (extern auto [x, y] : D()) { - } // expected-error@-1 {{decomposition declaration cannot be declared 'extern'}} + } // expected-error@-1 {{structured binding declaration cannot be declared 'extern'}} // expected-error@-2 {{loop variable '[x, y]' may not be declared 'extern'}} #endif } diff --git a/clang/test/CXX/temp/temp.res/temp.local/p6.cpp b/clang/test/CXX/temp/temp.res/temp.local/p6.cpp index 205df5fa25870..beed7bfd15acf 100644 --- a/clang/test/CXX/temp/temp.res/temp.local/p6.cpp +++ b/clang/test/CXX/temp/temp.res/temp.local/p6.cpp @@ -165,7 +165,7 @@ A<0>::B a; template int shadow() { // expected-note{{template parameter is declared here}} using arr = int[1]; - // expected-warning@+1 {{decomposition declarations are a C++17 extension}} + // expected-warning@+1 {{structured binding declarations are a C++17 extension}} auto [ T // expected-error {{declaration of 'T' shadows template parameter}} ] = arr{}; diff --git a/clang/test/FixIt/fixit-constrained-structured-binding.cpp b/clang/test/FixIt/fixit-constrained-structured-binding.cpp index 3f21c1da45a4a..bfb004fe035e1 100644 --- a/clang/test/FixIt/fixit-constrained-structured-binding.cpp +++ b/clang/test/FixIt/fixit-constrained-structured-binding.cpp @@ -14,20 +14,20 @@ T get_T(); void use() { UnaryC auto [a, b] = get_S(); - // CHECK: error: decomposition declaration cannot be declared with constrained 'auto' + // CHECK: error: structured binding declaration cannot be declared with constrained 'auto' // CHECK: fix-it:{{.*}}:{16:3-16:10}:"" BinaryC auto [c, d] = get_S(); - // CHECK: error: decomposition declaration cannot be declared with constrained 'auto' + // CHECK: error: structured binding declaration cannot be declared with constrained 'auto' // CHECK: fix-it:{{.*}}:{19:3-19:16}:"" } template void TemplUse() { UnaryC auto [a, b] = get_T(); - // CHECK: error: decomposition declaration cannot be declared with constrained 'auto' + // CHECK: error: structured binding declaration cannot be declared with constrained 'auto' // XCHECK: fix-it:{{.*}}:{26:3-26:10}:"" BinaryC auto [c, d] = get_T(); - // CHECK: error: decomposition declaration cannot be declared with constrained 'auto' + // CHECK: error: structured binding declaration cannot be declared with constrained 'auto' // XCHECK: fix-it:{{.*}}:{29:3-29:14}:"" } diff --git a/clang/test/PCH/cxx1z-decomposition.cpp b/clang/test/PCH/cxx1z-decomposition.cpp index 914ce80c550d1..340d5eae0b8c3 100644 --- a/clang/test/PCH/cxx1z-decomposition.cpp +++ b/clang/test/PCH/cxx1z-decomposition.cpp @@ -22,7 +22,7 @@ constexpr int foo(Q &&q) { return a * 10 + b; } -auto [noinit]; // expected-error{{decomposition declaration '[noinit]' requires an initializer}} +auto [noinit]; // expected-error{{structured binding declaration '[noinit]' requires an initializer}} #else @@ -31,7 +31,7 @@ int k = decomp(arr); static_assert(foo({1, 2}) == 12); -// expected-error@15 {{cannot decompose non-class, non-array type 'const int'}} +// expected-error@15 {{cannot bind non-class, non-array type 'const int'}} int z = decomp(10); // expected-note {{instantiation of}} #endif diff --git a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp index 9d27f83698e00..ece00a08954b9 100644 --- a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp +++ b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp @@ -158,7 +158,7 @@ namespace decl { A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}} A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}} A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}} - A [x, y] = 0; // expected-error {{cannot be declared with type 'A'}} expected-error {{type 'A' decomposes into 0 elements, but 2 names were provided}} + A [x, y] = 0; // expected-error {{cannot be declared with type 'A'}} expected-error {{type 'A' binds to 0 elements, but 2 names were provided}} } namespace typename_specifier { @@ -185,7 +185,7 @@ namespace typename_specifier { typename ::A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}} typename ::A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}} typename ::A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}} - typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{type 'typename ::A' (aka 'A') decomposes into 0}} + typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{type 'typename ::A' (aka 'A') binds to 0}} struct X { template struct A { A(T); }; }; // expected-note 8{{declared here}} @@ -208,7 +208,7 @@ namespace typename_specifier { {typename T::A arr[3] = 0;} // expected-error {{refers to class template member}} {typename T::A F::*pm = 0;} // expected-error {{refers to class template member}} {typename T::A (*fp)() = 0;} // expected-error {{refers to class template member}} - {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{type 'typename typename_specifier::X::A' (aka 'typename_specifier::X::A') decomposes into 0}} + {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{type 'typename typename_specifier::X::A' (aka 'typename_specifier::X::A') binds to 0}} } template void f(); // expected-note {{instantiation of}} diff --git a/clang/test/Parser/cxx1z-decomposition.cpp b/clang/test/Parser/cxx1z-decomposition.cpp index 274e24ea55522..21c9419e8f413 100644 --- a/clang/test/Parser/cxx1z-decomposition.cpp +++ b/clang/test/Parser/cxx1z-decomposition.cpp @@ -5,7 +5,7 @@ struct S { int a, b, c; }; // expected-note 2 {{'S::a' declared here}} -// A simple-declaration can be a decompsition declaration. +// A simple-declaration can be a structured binding declaration. namespace SimpleDecl { auto [a_x, b_x, c_x] = S(); @@ -19,7 +19,7 @@ namespace SimpleDecl { } } -// A for-range-declaration can be a decomposition declaration. +// A for-range-declaration can be a structured binding declaration. namespace ForRangeDecl { extern S arr[10]; void h() { @@ -100,12 +100,12 @@ namespace BadSpecifiers { inline auto &[k] = n; // expected-error {{cannot be declared 'inline'}} const int K = 5; - auto ([c]) = s; // expected-error {{decomposition declaration cannot be declared with parentheses}} + auto ([c]) = s; // expected-error {{structured binding declaration cannot be declared with parentheses}} void g() { // defining-type-specifiers other than cv-qualifiers and 'auto' S [a] = s; // expected-error {{cannot be declared with type 'S'}} decltype(auto) [b] = s; // expected-error {{cannot be declared with type 'decltype(auto)'}} - auto ([c2]) = s; // cxx17-error {{decomposition declaration cannot be declared with parenthese}} \ + auto ([c2]) = s; // cxx17-error {{structured binding declaration cannot be declared with parenthese}} \ // post2b-error {{use of undeclared identifier 'c2'}} \ // post2b-error {{expected body of lambda expression}} \ @@ -114,7 +114,7 @@ namespace BadSpecifiers { auto [e][1] = s; // expected-error {{expected ';'}} expected-error {{requires an initializer}} // FIXME: This should fire the 'misplaced array declarator' diagnostic. - int [K] arr = {0}; // expected-error {{expected ';'}} expected-error {{cannot be declared with type 'int'}} expected-error {{decomposition declaration '[K]' requires an initializer}} + int [K] arr = {0}; // expected-error {{expected ';'}} expected-error {{cannot be declared with type 'int'}} expected-error {{structured binding declaration '[K]' requires an initializer}} int [5] arr = {0}; // expected-error {{place the brackets after the name}} auto *[f] = s; // expected-error {{cannot be declared with type 'auto *'}} expected-error {{incompatible initializer}} @@ -145,14 +145,14 @@ namespace MultiDeclarator { namespace Template { int n[3]; // Structured binding template is not allowed. - template auto [a, b, c] = n; // expected-error {{decomposition declaration cannot be a template}} + template auto [a, b, c] = n; // expected-error {{structured binding declaration cannot be a template}} } namespace Init { void f() { int arr[1]; struct S { int n; }; - auto &[bad1]; // expected-error {{decomposition declaration '[bad1]' requires an initializer}} + auto &[bad1]; // expected-error {{structured binding declaration '[bad1]' requires an initializer}} const auto &[bad2](S{}, S{}); // expected-error {{initializer for variable '[bad2]' with type 'const auto &' contains multiple expressions}} const auto &[bad3](); // expected-error {{expected expression}} auto &[good1] = arr; diff --git a/clang/test/Parser/cxx2c-binding-pack.cpp b/clang/test/Parser/cxx2c-binding-pack.cpp index 0daaad3a459ed..40d843e24ff66 100644 --- a/clang/test/Parser/cxx2c-binding-pack.cpp +++ b/clang/test/Parser/cxx2c-binding-pack.cpp @@ -12,7 +12,7 @@ void decompose_array() { auto [...] = arr; // #2 // expected-error@#2{{expected identifier}} // expected-error@#2{{{no names were provided}}} - // expected-warning@#2{{{does not allow a decomposition group to be empty}}} + // expected-warning@#2{{{does not allow a structured binding group to be empty}}} auto [a, ..., b] = arr; // #3 // expected-error@#3{{expected identifier}} // expected-error@#3{{{only 1 name was provided}}} diff --git a/clang/test/SemaCXX/builtin-structured-binding-size.cpp b/clang/test/SemaCXX/builtin-structured-binding-size.cpp index bcd13a6fb720d..a8f670546117f 100644 --- a/clang/test/SemaCXX/builtin-structured-binding-size.cpp +++ b/clang/test/SemaCXX/builtin-structured-binding-size.cpp @@ -40,8 +40,8 @@ static_assert(__builtin_structured_binding_size(S5) == 2); // expected-error@-1 {{static assertion failed due to requirement '__builtin_structured_binding_size(S5) == 2'}} \ // expected-note@-1 {{expression evaluates to '1 == 2'}} static_assert(__builtin_structured_binding_size(S6) == 2); -// expected-error@-1 {{cannot decompose class type 'S6' because it has an anonymous union member}} \ -// expected-error@-1 {{type 'S6' cannot be decomposed}} \ +// expected-error@-1 {{cannot bind class type 'S6' because it has an anonymous union member}} \ +// expected-error@-1 {{type 'S6' cannot be bound}} \ // expected-error@-1 {{static assertion expression is not an integral constant expression}} \ // expected-note@#note-anon-union {{declared here}} static_assert(__builtin_structured_binding_size(S7) == 1); @@ -49,15 +49,15 @@ static_assert(__builtin_structured_binding_size(S7) == 1); static_assert(__builtin_structured_binding_size(SD) == 1); static_assert(__builtin_structured_binding_size(SE1) == 1); -// expected-error@-1 {{cannot decompose class type 'SE1': both it and its base class 'S1' have non-static data members}} \ -// expected-error@-1 {{type 'SE1' cannot be decomposed}} \ +// expected-error@-1 {{cannot bind class type 'SE1': both it and its base class 'S1' have non-static data members}} \ +// expected-error@-1 {{type 'SE1' cannot be bound}} \ // expected-error@-1 {{static assertion expression is not an integral constant expression}} static_assert(__builtin_structured_binding_size(U1) == 0); -// expected-error@-1 {{type 'U1' cannot be decomposed}} \ +// expected-error@-1 {{type 'U1' cannot be bound}} \ // expected-error@-1 {{static assertion expression is not an integral constant expression}} static_assert(__builtin_structured_binding_size(U2) == 0); -// expected-error@-1 {{type 'U2' cannot be decomposed}} \ +// expected-error@-1 {{type 'U2' cannot be bound}} \ // expected-error@-1 {{static assertion expression is not an integral constant expression}} @@ -75,7 +75,7 @@ static_assert(__builtin_structured_binding_size(decltype(__builtin_complex(0., 0 int VLASize; // expected-note {{declared here}} static_assert(__builtin_structured_binding_size(int[VLASize]) == 42); -// expected-error@-1 {{type 'int[VLASize]' cannot be decomposed}} \ +// expected-error@-1 {{type 'int[VLASize]' cannot be bound}} \ // expected-warning@-1 {{variable length arrays in C++ are a Clang extension}} \ // expected-note@-1 {{read of non-const variable 'VLASize' is not allowed in a constant expression}} \ // expected-error@-1 {{static assertion expression is not an integral constant expression}} @@ -84,10 +84,10 @@ static_assert(__builtin_structured_binding_size(int[VLASize]) == 42); struct Incomplete; // expected-note {{forward declaration of 'Incomplete'}} static_assert(__builtin_structured_binding_size(Incomplete) == 1); // expected-error@-1 {{incomplete type 'Incomplete' where a complete type is required}} \ -// expected-error@-1 {{type 'Incomplete' cannot be decomposed}} \ +// expected-error@-1 {{type 'Incomplete' cannot be bound}} \ // expected-error@-1 {{static assertion expression is not an integral constant expression}} static_assert(__builtin_structured_binding_size(Incomplete[]) == 1); -// expected-error@-1 {{type 'Incomplete[]' cannot be decomposed}} \ +// expected-error@-1 {{type 'Incomplete[]' cannot be bound}} \ // expected-error@-1 {{static assertion expression is not an integral constant expression}} static_assert(__builtin_structured_binding_size(Incomplete[0]) == 0); static_assert(__builtin_structured_binding_size(Incomplete[1]) == 1); @@ -97,12 +97,12 @@ static_assert(__builtin_structured_binding_size(Incomplete[42]) == 42); static_assert(__builtin_structured_binding_size(P1) == 0); // expected-error@-1 {{static assertion failed due to requirement '__builtin_structured_binding_size(P1) == 0'}} \ // expected-note@-1 {{expression evaluates to '1 == 0'}} \ -// expected-error@-1 {{cannot decompose private member 'a' of 'P1}} \ +// expected-error@-1 {{cannot bind private member 'a' of 'P1}} \ // expected-note@#note-private {{implicitly declared private here}} void func(int array[14], int x = __builtin_structured_binding_size(decltype(array))); -//expected-error@-1 {{type 'decltype(array)' (aka 'int *') cannot be decomposed}} +//expected-error@-1 {{type 'decltype(array)' (aka 'int *') cannot be bound}} struct SM { static int array[14]; @@ -115,7 +115,7 @@ struct T { }; T t1; -// expected-error@#tpl-1 {{type 'int' cannot be decomposed}} \ +// expected-error@#tpl-1 {{type 'int' cannot be bound}} \ // expected-error@#tpl-1 {{non-type template argument is not a constant expression}} \ // expected-note@-1 {{in instantiation of default argument for 'T' required here}} \ // expected-note@-1 {{while checking a default template argument used here}} \ @@ -183,8 +183,8 @@ static_assert(!is_destructurable); static_assert(__builtin_structured_binding_size(T1) == 1); static_assert(__builtin_structured_binding_size(T42) == 42); static_assert(__builtin_structured_binding_size(TSizeError) == 42); -// expected-error@-1 {{cannot decompose this type; 'std::tuple_size::value' is not a valid integral constant expression}} \ -// expected-error@-1 {{type 'TSizeError' cannot be decomposed}} \ +// expected-error@-1 {{cannot bind this type; 'std::tuple_size::value' is not a valid integral constant expression}} \ +// expected-error@-1 {{type 'TSizeError' cannot be bound}} \ // expected-error@-1 {{static assertion expression is not an integral constant expression}} static_assert(!is_destructurable); } @@ -195,7 +195,7 @@ struct S { int y; static_assert(__builtin_structured_binding_size(S) == 2); //expected-error@-1 {{incomplete type 'S' where a complete type is required}} \ - // expected-error@-1 {{type 'S' cannot be decomposed}} \ + // expected-error@-1 {{type 'S' cannot be bound}} \ // expected-error@-1 {{static assertion expression is not an integral constant expression}} \ // expected-note@-4 {{definition of 'S' is not complete until the closing '}'}} }; @@ -228,20 +228,20 @@ static_assert(__is_same_as(tag_of_t, int)); static_assert(__is_same_as(tag_of_t, int)); // error // expected-error@-1 {{constraints not satisfied for alias template 'tag_of_t' [with T = int]}} -// expected-note@#tag-of-constr {{because substituted constraint expression is ill-formed: type 'int' cannot be decomposed}} +// expected-note@#tag-of-constr {{because substituted constraint expression is ill-formed: type 'int' cannot be bound}} struct MinusOne; template <> struct ::std::tuple_size { static constexpr int value = -1; }; int minus_one = __builtin_structured_binding_size(MinusOne); -// expected-error@-1 {{cannot decompose this type; 'std::tuple_size::value' is not a valid size: -1}} -// expected-error@-2 {{type 'MinusOne' cannot be decomposed}} +// expected-error@-1 {{cannot bind this type; 'std::tuple_size::value' is not a valid size: -1}} +// expected-error@-2 {{type 'MinusOne' cannot be bound}} struct UintMax; template <> struct ::std::tuple_size { static constexpr unsigned value = -1; }; int uint_max = __builtin_structured_binding_size(UintMax); -// expected-error@-1 {{cannot decompose this type; 'std::tuple_size::value' is not a valid size: 4294967295}} -// expected-error@-2 {{type 'UintMax' cannot be decomposed}} +// expected-error@-1 {{cannot bind this type; 'std::tuple_size::value' is not a valid size: 4294967295}} +// expected-error@-2 {{type 'UintMax' cannot be bound}} diff --git a/clang/test/SemaCXX/cxx17-compat.cpp b/clang/test/SemaCXX/cxx17-compat.cpp index 99e41d818a6c3..1c9060d388d2a 100644 --- a/clang/test/SemaCXX/cxx17-compat.cpp +++ b/clang/test/SemaCXX/cxx17-compat.cpp @@ -76,18 +76,18 @@ struct ConstexprVirtual { struct C { int x, y, z; }; static auto [cx, cy, cz] = C(); #if __cplusplus <= 201703L - // expected-warning@-2 {{decomposition declaration declared 'static' is a C++20 extension}} + // expected-warning@-2 {{structured binding declaration declared 'static' is a C++20 extension}} #else - // expected-warning@-4 {{decomposition declaration declared 'static' is incompatible with C++ standards before C++20}} + // expected-warning@-4 {{structured binding declaration declared 'static' is incompatible with C++ standards before C++20}} #endif void f() { static thread_local auto [cx, cy, cz] = C(); #if __cplusplus <= 201703L - // expected-warning@-2 {{decomposition declaration declared 'static' is a C++20 extension}} - // expected-warning@-3 {{decomposition declaration declared 'thread_local' is a C++20 extension}} + // expected-warning@-2 {{structured binding declaration declared 'static' is a C++20 extension}} + // expected-warning@-3 {{structured binding declaration declared 'thread_local' is a C++20 extension}} #else - // expected-warning@-5 {{decomposition declaration declared 'static' is incompatible with C++ standards before C++20}} - // expected-warning@-6 {{decomposition declaration declared 'thread_local' is incompatible with C++ standards before C++20}} + // expected-warning@-5 {{structured binding declaration declared 'static' is incompatible with C++ standards before C++20}} + // expected-warning@-6 {{structured binding declaration declared 'thread_local' is incompatible with C++ standards before C++20}} #endif } diff --git a/clang/test/SemaCXX/cxx1z-decomposition.cpp b/clang/test/SemaCXX/cxx1z-decomposition.cpp index 6ee1249a66c3f..158a3a66deb47 100644 --- a/clang/test/SemaCXX/cxx1z-decomposition.cpp +++ b/clang/test/SemaCXX/cxx1z-decomposition.cpp @@ -3,22 +3,22 @@ // RUN: %clang_cc1 -std=c++20 -Wpre-c++20-compat -fexperimental-new-constant-interpreter -verify=expected %s void use_from_own_init() { - auto [a] = a; // expected-error {{binding 'a' cannot appear in the initializer of its own decomposition declaration}} + auto [a] = a; // expected-error {{binding 'a' cannot appear in the initializer of its own structured binding declaration}} } void num_elems() { struct A0 {} a0; int a1[1], a2[2]; - auto [] = a0; // expected-warning {{does not allow a decomposition group to be empty}} - auto [v1] = a0; // expected-error {{type 'struct A0' decomposes into 0 elements, but 1 name was provided}} - auto [] = a1; // expected-error {{type 'int[1]' decomposes into 1 element, but no names were provided}} expected-warning {{empty}} + auto [] = a0; // expected-warning {{does not allow a structured binding group to be empty}} + auto [v1] = a0; // expected-error {{type 'struct A0' binds to 0 elements, but 1 name was provided}} + auto [] = a1; // expected-error {{type 'int[1]' binds to 1 element, but no names were provided}} expected-warning {{empty}} auto [v2] = a1; - auto [v3, v4] = a1; // expected-error {{type 'int[1]' decomposes into 1 element, but 2 names were provided}} - auto [] = a2; // expected-error {{type 'int[2]' decomposes into 2 elements, but no names were provided}} expected-warning {{empty}} - auto [v5] = a2; // expected-error {{type 'int[2]' decomposes into 2 elements, but only 1 name was provided}} + auto [v3, v4] = a1; // expected-error {{type 'int[1]' binds to 1 element, but 2 names were provided}} + auto [] = a2; // expected-error {{type 'int[2]' binds to 2 elements, but no names were provided}} expected-warning {{empty}} + auto [v5] = a2; // expected-error {{type 'int[2]' binds to 2 elements, but only 1 name was provided}} auto [v6, v7] = a2; - auto [v8, v9, v10] = a2; // expected-error {{type 'int[2]' decomposes into 2 elements, but 3 names were provided}} + auto [v8, v9, v10] = a2; // expected-error {{type 'int[2]' binds to 2 elements, but 3 names were provided}} } // As a Clang extension, _Complex can be decomposed. @@ -105,7 +105,7 @@ void enclosing() { void bitfield() { struct { int a : 3, : 4, b : 5; } a; auto &[x, y] = a; - auto &[p, q, r] = a; // expected-error-re {{type 'struct (unnamed struct at {{.*}})' decomposes into 2 elements, but 3 names were provided}} + auto &[p, q, r] = a; // expected-error-re {{type 'struct (unnamed struct at {{.*}})' binds to 2 elements, but 3 names were provided}} } void for_range() { @@ -115,7 +115,7 @@ void for_range() { } int y[5]; - for (auto[c] : y) { // expected-error {{cannot decompose non-class, non-array type 'int'}} + for (auto[c] : y) { // expected-error {{cannot bind non-class, non-array type 'int'}} c++; } } @@ -157,16 +157,16 @@ int f2() { namespace lambdas { void f() { int n; - auto [a] = // expected-error {{cannot decompose lambda closure type}} + auto [a] = // expected-error {{cannot bind lambda closure type}} [n] {}; // expected-note {{lambda expression}} } - auto [] = []{}; // expected-warning {{ISO C++17 does not allow a decomposition group to be empty}} + auto [] = []{}; // expected-warning {{ISO C++17 does not allow a structured binding group to be empty}} int g() { int n = 0; auto a = [=](auto &self) { // expected-note {{lambda expression}} - auto &[capture] = self; // expected-error {{cannot decompose lambda closure type}} + auto &[capture] = self; // expected-error {{cannot bind lambda closure type}} ++capture; return n; }; @@ -188,14 +188,14 @@ namespace lambdas { struct A : decltype(x) { int n; }; - auto &&[r] = A{x, 0}; // expected-error-re {{cannot decompose class type 'A': both it and its base class 'decltype(x)' (aka '(lambda {{.*}})') have non-static data members}} + auto &&[r] = A{x, 0}; // expected-error-re {{cannot bind class type 'A': both it and its base class 'decltype(x)' (aka '(lambda {{.*}})') have non-static data members}} return r; } void j() { auto x = [] {}; struct A : decltype(x) {}; - auto &&[] = A{x}; // expected-warning {{ISO C++17 does not allow a decomposition group to be empty}} + auto &&[] = A{x}; // expected-warning {{ISO C++17 does not allow a structured binding group to be empty}} } } diff --git a/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp b/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp index 638a2d805c2c5..0dfb52b3e0396 100644 --- a/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp +++ b/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp @@ -10,7 +10,7 @@ void decompose_array() { auto [x, ...rest, y] = arr; // cxx26-warning@+4 {{structured binding packs are incompatible with C++ standards before C++2c}} - // cxx23-error@+3 {{decomposition declaration cannot be declared 'constexpr'}} + // cxx23-error@+3 {{structured binding declaration cannot be declared 'constexpr'}} // cxx23-warning@+2 {{structured binding packs are a C++2c extension}} // nontemplate-error@+1 {{pack declaration outside of template}} constexpr auto [x_c, ...rest_c, y_c] = arr; diff --git a/clang/test/SemaCXX/cxx2c-binding-pack.cpp b/clang/test/SemaCXX/cxx2c-binding-pack.cpp index a8c1386ea5c18..0b0eb88fe4c98 100644 --- a/clang/test/SemaCXX/cxx2c-binding-pack.cpp +++ b/clang/test/SemaCXX/cxx2c-binding-pack.cpp @@ -82,7 +82,7 @@ void decompose_array() { static_assert(sizeof...(b) == 0); auto [...c] = arr1; static_assert(sizeof...(c) == 1); - auto [a1, ...b1, c1] = arr1; // expected-error{{decomposes into 1 element, but 3 names were provided}} + auto [a1, ...b1, c1] = arr1; // expected-error{{binds to 1 element, but 3 names were provided}} } // Test case by Younan Zhang. @@ -160,7 +160,7 @@ void now_i_know_my() { static_assert(sizeof...(e) == 2); auto [h, i, j, ...k] = C(); // OK, the pack k is empty static_assert(sizeof...(e) == 0); - auto [l, m, n, o, ...p] = C(); // expected-error{{{decomposes into 3 elements, but 5 names were provided}}} + auto [l, m, n, o, ...p] = C(); // expected-error{{{binds to 3 elements, but 5 names were provided}}} } } // namespace @@ -225,7 +225,7 @@ namespace GH125165 { template auto f(auto t) { const auto& [...pack] = t; - // expected-error@-1 {{cannot decompose non-class, non-array type 'char const'}} + // expected-error@-1 {{cannot bind non-class, non-array type 'char const'}} (pack, ...); }; diff --git a/clang/test/SemaCXX/sizeless-1.cpp b/clang/test/SemaCXX/sizeless-1.cpp index 688bbf058e4ca..ef3eec9507b58 100644 --- a/clang/test/SemaCXX/sizeless-1.cpp +++ b/clang/test/SemaCXX/sizeless-1.cpp @@ -532,7 +532,7 @@ void cxx_only(int sel) { auto auto_int8 = local_int8; auto auto_int16 = local_int16; #if __cplusplus >= 201703L - auto [auto_int8_a] = local_int8; // expected-error {{cannot decompose non-class, non-array type 'svint8_t' (aka '__SVInt8_t')}} + auto [auto_int8_a] = local_int8; // expected-error {{cannot bind non-class, non-array type 'svint8_t' (aka '__SVInt8_t')}} #endif #endif diff --git a/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp b/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp index 2388c5f16e4ca..0042ef035c84c 100644 --- a/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp +++ b/clang/test/SemaCXX/warn-shadow-in-lambdas.cpp @@ -259,11 +259,11 @@ struct S { int foo() { #ifdef AVOID - auto [a] = S{0}; // cxx14-warning {{decomposition declarations are a C++17 extension}} + auto [a] = S{0}; // cxx14-warning {{structured binding declarations are a C++17 extension}} [a = a] () { // No warning with basic -Wshadow due to uncaptured-local classification }(); #else - auto [a] = S{0}; // cxx14-warning {{decomposition declarations are a C++17 extension}} expected-note {{previous declaration is here}} + auto [a] = S{0}; // cxx14-warning {{structured binding declarations are a C++17 extension}} expected-note {{previous declaration is here}} [a = a] () { // expected-warning {{declaration shadows a structured binding}} }(); #endif diff --git a/clang/test/SemaTemplate/cxx1z-decomposition.cpp b/clang/test/SemaTemplate/cxx1z-decomposition.cpp index 779c4cf75e9db..b0cc4e66e3dc6 100644 --- a/clang/test/SemaTemplate/cxx1z-decomposition.cpp +++ b/clang/test/SemaTemplate/cxx1z-decomposition.cpp @@ -15,7 +15,7 @@ namespace std { template<> struct std::tuple_size { enum { value = 2 }; }; template int decomp(T &t) { - auto &[a, b] = t; // expected-error {{type 'D' decomposes into 3 elements, but only 2 names were provided}} + auto &[a, b] = t; // expected-error {{type 'D' binds to 3 elements, but only 2 names were provided}} return a + b; // expected-error {{cannot initialize return object of type 'int' with an rvalue of type 'int *'}} } From 197f3d635e009b35682d870580a4f392924ab3ea Mon Sep 17 00:00:00 2001 From: foxfromabyss Date: Mon, 13 Oct 2025 19:27:41 +0200 Subject: [PATCH 2/5] Add missing ReleaseNotes.rst update --- clang/docs/ReleaseNotes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 65b086caf3652..18c547733adae 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -297,6 +297,8 @@ Attribute Changes in Clang Improvements to Clang's diagnostics ----------------------------------- +- Diagnostics messages now refer to ``structured binding`` instead of ``decomposition``, + since `P0615R0 `_ changed the term. - Added a separate diagnostic group ``-Wfunction-effect-redeclarations``, for the more pedantic diagnostics for function effects (``[[clang::nonblocking]]`` and ``[[clang::nonallocating]]``). Moved the warning for a missing (though implied) attribute on a redeclaration into this group. From d7708b3489e4aa85834b1e62f8e279fe3ed0b3c7 Mon Sep 17 00:00:00 2001 From: foxfromabyss Date: Mon, 13 Oct 2025 19:33:29 +0200 Subject: [PATCH 3/5] Reword the release notes again --- clang/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 18c547733adae..f08c4166771b6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -298,7 +298,7 @@ Attribute Changes in Clang Improvements to Clang's diagnostics ----------------------------------- - Diagnostics messages now refer to ``structured binding`` instead of ``decomposition``, - since `P0615R0 `_ changed the term. + to align with `P0615R0 `_ changing the term. - Added a separate diagnostic group ``-Wfunction-effect-redeclarations``, for the more pedantic diagnostics for function effects (``[[clang::nonblocking]]`` and ``[[clang::nonallocating]]``). Moved the warning for a missing (though implied) attribute on a redeclaration into this group. From c05398e48ec5ee9a276c822a8457d96a7f531b51 Mon Sep 17 00:00:00 2001 From: foxfromabyss <22933823+foxfromabyss@users.noreply.github.com> Date: Mon, 13 Oct 2025 19:51:40 +0200 Subject: [PATCH 4/5] Link GH issue Co-authored-by: Sirraide --- clang/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f08c4166771b6..6f1f09ec99bbe 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -298,7 +298,7 @@ Attribute Changes in Clang Improvements to Clang's diagnostics ----------------------------------- - Diagnostics messages now refer to ``structured binding`` instead of ``decomposition``, - to align with `P0615R0 `_ changing the term. + to align with `P0615R0 `_ changing the term. (#GH157880) - Added a separate diagnostic group ``-Wfunction-effect-redeclarations``, for the more pedantic diagnostics for function effects (``[[clang::nonblocking]]`` and ``[[clang::nonallocating]]``). Moved the warning for a missing (though implied) attribute on a redeclaration into this group. From ae12747eac6fa694edd69286280cb18ca9d4df5c Mon Sep 17 00:00:00 2001 From: foxfromabyss Date: Mon, 13 Oct 2025 20:01:47 +0200 Subject: [PATCH 5/5] restore diagnostics formatting --- .../clang/Basic/DiagnosticParseKinds.td | 7 +- .../clang/Basic/DiagnosticSemaKinds.td | 99 ++++++++++--------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 5fc74cb8155b6..047a92da84569 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -504,10 +504,9 @@ def err_expected_end_of_enumerator : Error< def err_expected_coloncolon_after_super : Error< "expected '::' after '__super'">; -def ext_decomp_decl_empty - : ExtWarn< - "ISO C++17 does not allow a structured binding group to be empty">, - InGroup>; +def ext_decomp_decl_empty : ExtWarn< + "ISO C++17 does not allow a structured binding group to be empty">, + InGroup>; def err_function_parameter_limit_exceeded : Error< "too many function parameters; subsequent parameters will be ignored">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 0abf14cbe7428..b251972a8278e 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -589,59 +589,60 @@ def warn_modifying_shadowing_decl : "field of %1">, InGroup, DefaultIgnore; -// C++ structured binding declarations -def err_decomp_decl_context - : Error<"structured binding declaration not permitted in this context">; +// C++ decomposition declarations +def err_decomp_decl_context : Error< + "structured binding declaration not permitted in this context">; def err_decomp_decl_spec : Error<"structured binding declaration cannot be declared '%0'">; -def err_decomp_decl_type - : Error<"structured binding declaration cannot be declared with type %0; " - "declared type must be 'auto' or reference to 'auto'">; -def err_decomp_decl_constraint : Error<"structured binding declaration cannot " - "be declared with constrained 'auto'">; -def err_decomp_decl_parens - : Error< - "structured binding declaration cannot be declared with parentheses">; -def err_decomp_decl_template - : Error<"structured binding declaration cannot be a template">; -def err_decomp_decl_not_alone : Error<"structured binding declaration must be " - "the only declaration in its group">; -def err_decomp_decl_requires_init - : Error<"structured binding declaration %0 requires an initializer">; -def err_decomp_decl_wrong_number_bindings - : Error<"type %0 binds to %3 %plural{1:element|:elements}2, but " - "%select{%plural{0:no|:only %1}1|%1}4 " - "%plural{1:name was|:names were}1 provided">; -def err_decomp_decl_unbindable_type - : Error<"cannot bind %select{union|non-class, non-array}1 type %2">; -def err_decomp_decl_multiple_bases_with_members - : Error<"cannot bind class type %1: " - "%select{its base classes %2 and|both it and its base class}0 %3 " - "have non-static data members">; -def err_decomp_decl_ambiguous_base - : Error<"cannot bind members of ambiguous base class %1 of %0:%2">; -def err_decomp_decl_inaccessible_base - : Error<"cannot bind members of inaccessible base class %1 of %0">, - AccessControl; -def err_decomp_decl_inaccessible_field - : Error<"cannot bind %select{private|protected}0 member %1 of %3">, - AccessControl; -def err_decomp_decl_lambda : Error<"cannot bind lambda closure type">; -def err_decomp_decl_anon_union_member - : Error<"cannot bind class type %0 because it has an anonymous " - "%select{struct|union}1 member">; -def err_decomp_decl_std_tuple_element_not_specialized - : Error<"cannot bind this type; 'std::tuple_element<%0>::type' " - "does not name a type">; -def err_decomp_decl_std_tuple_size_not_constant - : Error<"cannot bind this type; 'std::tuple_size<%0>::value' " - "is not a valid integral constant expression">; +def err_decomp_decl_type : Error< + "structured binding declaration cannot be declared with type %0; " + "declared type must be 'auto' or reference to 'auto'">; +def err_decomp_decl_constraint : Error< + "structured binding declaration cannot be declared with constrained 'auto'">; +def err_decomp_decl_parens : Error< + "structured binding declaration cannot be declared with parentheses">; +def err_decomp_decl_template : Error< + "structured binding declaration cannot be a template">; +def err_decomp_decl_not_alone : Error< + "structured binding declaration must be the only declaration in its group">; +def err_decomp_decl_requires_init : Error< + "structured binding declaration %0 requires an initializer">; +def err_decomp_decl_wrong_number_bindings : Error< + "type %0 binds to %3 %plural{1:element|:elements}2, but " + "%select{%plural{0:no|:only %1}1|%1}4 " + "%plural{1:name was|:names were}1 provided">; +def err_decomp_decl_unbindable_type : Error< + "cannot bind %select{union|non-class, non-array}1 type %2">; +def err_decomp_decl_multiple_bases_with_members : Error< + "cannot bind class type %1: " + "%select{its base classes %2 and|both it and its base class}0 %3 " + "have non-static data members">; +def err_decomp_decl_ambiguous_base : Error< + "cannot bind members of ambiguous base class %1 of %0:%2">; +def err_decomp_decl_inaccessible_base : Error< + "cannot bind members of inaccessible base class %1 of %0">, + AccessControl; +def err_decomp_decl_inaccessible_field : Error< + "cannot bind %select{private|protected}0 member %1 of %3">, + AccessControl; +def err_decomp_decl_lambda : Error< + "cannot bind lambda closure type">; +def err_decomp_decl_anon_union_member : Error< + "cannot bind class type %0 because it has an anonymous " + "%select{struct|union}1 member">; +def err_decomp_decl_std_tuple_element_not_specialized : Error< + "cannot bind this type; 'std::tuple_element<%0>::type' " + "does not name a type">; +def err_decomp_decl_std_tuple_size_not_constant : Error< + "cannot bind this type; 'std::tuple_size<%0>::value' " + "is not a valid integral constant expression">; def err_decomp_decl_std_tuple_size_invalid : Error<"cannot bind this type; 'std::tuple_size<%0>::value' " "is not a valid size: %1">; def note_in_binding_decl_init : Note< "in implicit initialization of binding declaration %0">; -def err_arg_is_not_destructurable : Error<"type %0 cannot be bound">; +def err_arg_is_not_destructurable : Error< + "type %0 cannot be bound">; def err_std_type_trait_not_class_template : Error< "unsupported standard library implementation: " @@ -2617,9 +2618,9 @@ def err_auto_variable_cannot_appear_in_own_initializer "%VarTemplateExplicitSpec{variable template explicit " "specialization}}0 %1 " "declared with deduced type %2 cannot appear in its own initializer">; -def err_binding_cannot_appear_in_own_initializer - : Error<"binding %0 cannot appear in the initializer of its own " - "structured binding declaration">; +def err_binding_cannot_appear_in_own_initializer : Error< + "binding %0 cannot appear in the initializer of its own " + "structured binding declaration">; def err_new_array_of_auto : Error< "cannot allocate array of 'auto'">; def err_auto_not_allowed : Error<