1 | // RUN: %clang_cc1 -std=c++1z %s -verify |
2 | |
3 | namespace std { |
4 | template<typename> struct tuple_size; |
5 | template<int, typename> struct tuple_element; |
6 | } |
7 | |
8 | struct Get { |
9 | template<int> int get() { return 0; } |
10 | operator bool() { return true; } |
11 | }; |
12 | |
13 | namespace std { |
14 | template<> struct tuple_size<Get> { static constexpr int value = 1; }; |
15 | template<> struct tuple_element<0, Get> { using type = int; }; |
16 | } |
17 | |
18 | struct Na { |
19 | bool flag; |
20 | float data; |
21 | }; |
22 | |
23 | struct Rst { |
24 | bool flag; |
25 | float data; |
26 | explicit operator bool() const { |
27 | return flag; |
28 | } |
29 | }; |
30 | |
31 | Rst f(); |
32 | Na g(); |
33 | |
34 | namespace CondInIf { |
35 | int h() { |
36 | if (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} |
37 | ; |
38 | if (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}} |
39 | ; |
40 | if (auto [value] = Get()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} |
41 | return value; |
42 | } |
43 | } // namespace CondInIf |
44 | |
45 | namespace CondInWhile { |
46 | int h() { |
47 | while (auto [ok, d] = f()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} |
48 | ; |
49 | while (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}} |
50 | ; |
51 | while (auto [value] = Get()) // expected-warning{{ISO C++17 does not permit structured binding declaration in a condition}} |
52 | return value; |
53 | } |
54 | } // namespace CondInWhile |
55 | |
56 | namespace CondInFor { |
57 | int h() { |
58 | for (; auto [ok, d] = f();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} |
59 | ; |
60 | for (; auto [ok, d] = g();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{value of type 'Na' is not contextually convertible to 'bool'}} |
61 | ; |
62 | for (; auto [value] = Get();) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} |
63 | return value; |
64 | } |
65 | } // namespace CondInFor |
66 | |
67 | struct IntegerLike { |
68 | bool flag; |
69 | float data; |
70 | operator int() const { |
71 | return int(data); |
72 | } |
73 | }; |
74 | |
75 | namespace CondInSwitch { |
76 | int h(IntegerLike x) { |
77 | switch (auto [ok, d] = x) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} |
78 | ; |
79 | switch (auto [ok, d] = g()) // expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} expected-error {{statement requires expression of integer type ('Na' invalid)}} |
80 | ; |
81 | switch (auto [value] = Get()) {// expected-warning {{ISO C++17 does not permit structured binding declaration in a condition}} |
82 | // expected-warning@-1{{switch condition has boolean value}} |
83 | case 1: |
84 | return value; |
85 | } |
86 | } |
87 | } // namespace CondInSwitch |
88 | |