Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ Attribute Changes in Clang

Improvements to Clang's diagnostics
-----------------------------------
- Diagnostics messages now refer to ``structured binding`` instead of ``decomposition``,
to align with `P0615R0 <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0615r0.html>`_ 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.
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -505,8 +505,8 @@ 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<DiagGroup<"empty-decomposition">>;
"ISO C++17 does not allow a structured binding group to be empty">,
InGroup<DiagGroup<"empty-structured-binding">>;

def err_function_parameter_limit_exceeded : Error<
"too many function parameters; subsequent parameters will be ignored">;
Expand Down
46 changes: 23 additions & 23 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand Down Expand Up @@ -591,58 +591,58 @@ def warn_modifying_shadowing_decl :

// C++ decomposition declarations
def err_decomp_decl_context : Error<
"decomposition declaration not permitted in this context">;
"structured binding declaration not permitted in this context">;
def err_decomp_decl_spec
: Error<"decomposition declaration cannot be declared '%0'">;
: Error<"structured binding declaration cannot be declared '%0'">;
def err_decomp_decl_type : Error<
"decomposition declaration cannot be declared with type %0; "
"structured binding 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'">;
"structured binding declaration cannot be declared with constrained 'auto'">;
def err_decomp_decl_parens : Error<
"decomposition declaration cannot be declared with parentheses">;
"structured binding declaration cannot be declared with parentheses">;
def err_decomp_decl_template : Error<
"decomposition declaration cannot be a template">;
"structured binding declaration cannot be a template">;
def err_decomp_decl_not_alone : Error<
"decomposition declaration must be the only declaration in its group">;
"structured binding declaration must be the only declaration in its group">;
def err_decomp_decl_requires_init : Error<
"decomposition declaration %0 requires an initializer">;
"structured binding declaration %0 requires an initializer">;
def err_decomp_decl_wrong_number_bindings : Error<
"type %0 decomposes into %3 %plural{1:element|:elements}2, but "
"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 decompose %select{union|non-class, non-array}1 type %2">;
"cannot bind %select{union|non-class, non-array}1 type %2">;
def err_decomp_decl_multiple_bases_with_members : Error<
"cannot decompose class type %1: "
"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 decompose members of ambiguous base class %1 of %0:%2">;
"cannot bind 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">,
"cannot bind 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">,
"cannot bind %select{private|protected}0 member %1 of %3">,
AccessControl;
def err_decomp_decl_lambda : Error<
"cannot decompose lambda closure type">;
"cannot bind lambda closure type">;
def err_decomp_decl_anon_union_member : Error<
"cannot decompose class type %0 because it has an anonymous "
"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 decompose this type; 'std::tuple_element<%0>::type' "
"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 decompose this type; 'std::tuple_size<%0>::value' "
"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">;
"type %0 cannot be bound">;

def err_std_type_trait_not_class_template : Error<
"unsupported standard library implementation: "
Expand Down Expand Up @@ -2620,7 +2620,7 @@ def err_auto_variable_cannot_appear_in_own_initializer
"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">;
"structured binding declaration">;
def err_new_array_of_auto : Error<
"cannot allocate array of 'auto'">;
def err_auto_not_allowed : Error<
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/zero-size-non-pod-array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
}
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CXX/dcl.decl/dcl.decomp/p2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 5 additions & 5 deletions clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@ 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<typename T> 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<Bad1> {};
void no_tuple_size_3() { auto [x, y] = Bad1(); } // ok, omitting value is valid after DR2386

struct Bad2 {};
template<> struct std::tuple_size<Bad2> { const int value = 5; };
void no_tuple_size_4() { auto [x, y] = Bad2(); } // expected-error {{cannot decompose this type; 'std::tuple_size<Bad2>::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<Bad2>::value' is not a valid integral constant expression}}

template<> struct std::tuple_size<A> { static const int value = 3; };
template<> struct std::tuple_size<B> { 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'}}
}
Expand Down
26 changes: 13 additions & 13 deletions clang/test/CXX/dcl.decl/dcl.decomp/p4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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'}}
}
}

Expand All @@ -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}}
}
}

Expand All @@ -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<decltype(m), int>();
Expand Down Expand Up @@ -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 {
Expand All @@ -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'}}
}
}
2 changes: 1 addition & 1 deletion clang/test/CXX/drs/cwg22xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CXX/drs/cwg23xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ template <> struct tuple_size<cwg2386::Bad2> {
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

Expand Down
8 changes: 4 additions & 4 deletions clang/test/CXX/drs/cwg26xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> 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<typename T>
void TemplUse() {
UnaryC auto [a, b] = get_T<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<T> auto [c, d] = get_T<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
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CXX/temp/temp.res/temp.local/p6.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ A<0>::B a;

template <typename T> 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{};
Expand Down
8 changes: 4 additions & 4 deletions clang/test/FixIt/fixit-constrained-structured-binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> 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<typename T>
void TemplUse() {
UnaryC auto [a, b] = get_T<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<T> auto [c, d] = get_T<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}:""
}

4 changes: 2 additions & 2 deletions clang/test/PCH/cxx1z-decomposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
6 changes: 3 additions & 3 deletions clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int>' 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<int>' binds to 0 elements, but 2 names were provided}}
}

namespace typename_specifier {
Expand All @@ -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<int>' (aka 'A<int>') decomposes into 0}}
typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{type 'typename ::A<int>' (aka 'A<int>') binds to 0}}

struct X { template<typename T> struct A { A(T); }; }; // expected-note 8{{declared here}}

Expand All @@ -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<int>' (aka 'typename_specifier::X::A<int>') 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<int>' (aka 'typename_specifier::X::A<int>') binds to 0}}
}
template void f<X>(); // expected-note {{instantiation of}}

Expand Down
Loading
Loading