xref: /llvm-project/clang/test/SemaCXX/decomposed-condition.cpp (revision 5334afcad827a6284ff56f5bde81d4e3416aae8c)
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