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