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 {
getGet9   template<int> int get() { return 0; }
operator boolGet10   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;
operator boolRst26   explicit operator bool() const {
27     return flag;
28   }
29 };
30 
31 Rst f();
32 Na g();
33 
34 namespace CondInIf {
h()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 {
h()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 {
h()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;
operator intIntegerLike70   operator int() const {
71     return int(data);
72   }
73 };
74 
75 namespace CondInSwitch {
h(IntegerLike x)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