1 // RUN: %clang_cc1 -std=c++1z -Wno-binding-in-condition -verify %s
2 // RUN: %clang_cc1 -std=c++1z -Wno-binding-in-condition -verify %s -fexperimental-new-constant-interpreter
3
4 struct X {
5 bool flag;
6 int data;
operator boolX7 constexpr explicit operator bool() const {
8 return flag;
9 }
operator intX10 constexpr operator int() const {
11 return data;
12 }
13 };
14
15 namespace CondInIf {
f(X x)16 constexpr int f(X x) {
17 if (auto [ok, d] = x)
18 return d + int(ok);
19 else
20 return d * int(ok);
21 ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
22 d = {}; // expected-error {{use of undeclared identifier 'd'}}
23 }
24
25 static_assert(f({true, 2}) == 3);
26 static_assert(f({false, 2}) == 0);
27
g(char const (& x)[2])28 constexpr char g(char const (&x)[2]) {
29 if (auto &[a, b] = x)
30 return a;
31 else
32 return b;
33
34 if (auto [a, b] = x) // expected-error {{an array type is not allowed here}}
35 ;
36 }
37
38 static_assert(g("x") == 'x');
39 } // namespace CondInIf
40
41 namespace CondInSwitch {
f(int n)42 constexpr int f(int n) {
43 switch (X s = {true, n}; auto [ok, d] = s) {
44 s = {};
45 case 0:
46 return int(ok);
47 case 1:
48 return d * 10;
49 case 2:
50 return d * 40;
51 default:
52 return 0;
53 }
54 ok = {}; // expected-error {{use of undeclared identifier 'ok'}}
55 d = {}; // expected-error {{use of undeclared identifier 'd'}}
56 s = {}; // expected-error {{use of undeclared identifier 's'}}
57 }
58
59 static_assert(f(0) == 1);
60 static_assert(f(1) == 10);
61 static_assert(f(2) == 80);
62 } // namespace CondInSwitch
63
64 namespace CondInWhile {
f(int n)65 constexpr int f(int n) {
66 int m = 1;
67 while (auto [ok, d] = X{n > 1, n}) {
68 m *= d;
69 --n;
70 }
71 return m;
72 return ok; // expected-error {{use of undeclared identifier 'ok'}}
73 }
74
75 static_assert(f(0) == 1);
76 static_assert(f(1) == 1);
77 static_assert(f(4) == 24);
78 } // namespace CondInWhile
79
80 namespace CondInFor {
f(int n)81 constexpr int f(int n) {
82 int a = 1, b = 1;
83 for (X x = {true, n}; auto &[ok, d] = x; --d) {
84 if (d < 2)
85 ok = false;
86 else {
87 int x = b;
88 b += a;
89 a = x;
90 }
91 }
92 return b;
93 return d; // expected-error {{use of undeclared identifier 'd'}}
94 }
95
96 static_assert(f(0) == 1);
97 static_assert(f(1) == 1);
98 static_assert(f(2) == 2);
99 static_assert(f(5) == 8);
100 } // namespace CondInFor
101