209 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify -Wunused-variable %s2 3template <typename, typename>4constexpr bool is_same = false;5template <typename T>6constexpr bool is_same<T, T> = true;7 8struct S {9 int i;10 int &j;11};12 13void check_category() {14 int a = 42;15 {16 auto [v, r] = S{1, a};17 (void)[ v, r ] {18 static_assert(is_same<decltype(v), int>);19 static_assert(is_same<decltype(r), int &>);20 };21 }22 {23 auto [v, r] = S{1, a};24 (void)[&v, &r ] {25 static_assert(is_same<decltype(v), int>);26 static_assert(is_same<decltype(r), int &>);27 };28 }29 {30 S s{1, a};31 const auto &[v, r] = s;32 (void)[ v, r ] {33 static_assert(is_same<decltype(v), const int>);34 static_assert(is_same<decltype(r), int &>);35 };36 }37 {38 S s{1, a};39 const auto &[v, r] = s;40 (void)[&v, &r ] {41 static_assert(is_same<decltype(v), const int>);42 static_assert(is_same<decltype(r), int &>);43 };44 }45}46 47void check_array() {48 int arr[2] = {42, 42};49 auto &[a, b] = arr;50 (void)[ a, &b ] {51 static_assert(is_same<decltype(a), int>);52 static_assert(is_same<decltype(b), int>);53 };54}55 56struct tuple {57 template <unsigned long I>58 decltype(auto) get() {59 if constexpr (I == 0) {60 return a;61 } else {62 return b;63 }64 }65 66 template <unsigned long I>67 decltype(auto) get() const {68 if constexpr (I == 0) {69 return a;70 } else {71 return b;72 }73 }74 75 int a = 0;76 int &b = a;77};78 79namespace std {80 81template <typename T>82struct tuple_size;83 84template <typename T>85struct tuple_size<T&> : tuple_size<T>{};86 87template <typename T>88requires requires { tuple_size<T>::value; }89struct tuple_size<const T> : tuple_size<T>{};90 91template <>92struct tuple_size<tuple> {93 static constexpr unsigned long value = 2;94};95 96template <unsigned long, typename T>97struct tuple_element;98 99template <>100struct tuple_element<0, tuple> {101 using type = int;102};103 104template <>105struct tuple_element<1, tuple> {106 using type = int &;107};108 109template <>110struct tuple_element<0, const tuple> {111 using type = int;112};113 114template <>115struct tuple_element<1, const tuple> {116 using type = const int &;117};118} // namespace std119 120void check_tuple_like() {121 tuple t;122 {123 auto [v, r] = t;124 (void)[ v, r ] {125 static_assert(is_same<decltype(v), int>);126 static_assert(is_same<decltype(r), int &>);127 };128 }129 {130 auto &[v, r] = t;131 (void)[&v, &r ] {132 static_assert(is_same<decltype(v), int>);133 static_assert(is_same<decltype(r), int &>);134 };135 }136 {137 const auto &[v, r] = t;138 (void)[ v, r ] {139 static_assert(is_same<decltype(v), int>);140 static_assert(is_same<decltype(r), const int &>);141 };142 }143 {144 const auto &[v, r] = t;145 (void)[&v, &r ] {146 static_assert(is_same<decltype(v), int>);147 static_assert(is_same<decltype(r), const int &>);148 };149 }150}151 152namespace ODRUseTests {153 struct P { int a; int b; };154 void GH57826() {155 const auto [a, b] = P{1, 2}; //expected-note 2{{'b' declared here}} \156 //expected-note 3{{'a' declared here}}157 (void)[&](auto c) { return b + [&a] {158 return a;159 }(); }(0);160 (void)[&](auto c) { return b + [&a](auto) {161 return a;162 }(0); }(0);163 (void)[=](auto c) { return b + [&a](auto) {164 return a;165 }(0); }(0);166 (void)[&a,&b](auto c) { return b + [&a](auto) {167 return a;168 }(0); }(0);169 (void)[&a,&b](auto c) { return b + [a](auto) {170 return a;171 }(0); }(0);172 (void)[&a](auto c) { return b + [&a](auto) { // expected-error 2{{variable 'b' cannot be implicitly captured}} \173 // expected-note 2{{lambda expression begins here}} \174 // expected-note 4{{capture 'b'}}175 return a;176 }(0); }(0); // expected-note {{in instantiation}}177 (void)[&b](auto c) { return b + [](auto) { // expected-note 3{{lambda expression begins here}} \178 // expected-note 6{{capture 'a'}} \179 // expected-note 6{{default capture}} \180 // expected-note {{in instantiation}} \181 // expected-note {{while substituting into a lambda}}182 return a; // expected-error 3{{variable 'a' cannot be implicitly captured}}183 }(0); }(0); // expected-note 2{{in instantiation}}184 }185}186 187 188namespace GH95081 {189 void prevent_assignment_check() {190 int arr[] = {1,2};191 auto [e1, e2] = arr;192 193 auto lambda = [e1] {194 e1 = 42; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}195 };196 }197 198 void f(int&) = delete;199 void f(const int&);200 201 int arr[1];202 void foo() {203 auto [x] = arr;204 [x]() {205 f(x); // deleted f(int&) used to be picked up erroneously206 } ();207 }208}209