brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.9 KiB · 42b3f81 Raw
257 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2a %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wno-c++23-extensions2// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=expected,cxx23 %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++23-compat3 4struct NonLiteral { // cxx2a-note {{'NonLiteral' is not literal}} \5                    // cxx23-note 2{{'NonLiteral' is not literal}}6  NonLiteral() {} // cxx23-note 2{{declared here}}7};8 9struct Constexpr{};10 11#if __cplusplus > 202002L12 13constexpr int f(int n) {  // cxx2a-error {{constexpr function never produces a constant expression}}14  static const int m = n; // cxx2a-note {{control flows through the definition of a static variable}} \15                          // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}16  return m;17}18constexpr int g(int n) {        // cxx2a-error {{constexpr function never produces a constant expression}}19  thread_local const int m = n; // cxx2a-note {{control flows through the definition of a thread_local variable}} \20                                // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}21  return m;22}23 24constexpr int c_thread_local(int n) { // cxx2a-error {{constexpr function never produces a constant expression}}25  static _Thread_local int m = 0;     // cxx2a-note {{control flows through the definition of a thread_local variable}} \26                                      // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}27  return m;28}29 30constexpr int gnu_thread_local(int n) { // cxx2a-error {{constexpr function never produces a constant expression}}31  static __thread int m = 0;            // cxx2a-note {{control flows through the definition of a thread_local variable}} \32                                        // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}33  return m;34}35 36constexpr int h(int n) {  // cxx2a-error {{constexpr function never produces a constant expression}}37  static const int m = n; // cxx2a-note {{control flows through the definition of a static variable}} \38                          // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}39  return &m - &m;40}41constexpr int i(int n) {        // cxx2a-error {{constexpr function never produces a constant expression}}42  thread_local const int m = n; // cxx2a-note {{control flows through the definition of a thread_local variable}} \43                                 // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}44  return &m - &m;45}46 47constexpr int j(int n) {48  if (!n)49    return 0;50  static const int m = n; // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}51  return m;52}53constexpr int j0 = j(0);54 55constexpr int k(int n) {56  if (!n)57    return 0;58  thread_local const int m = n; // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}59 60  return m;61}62constexpr int k0 = k(0);63 64constexpr int j_evaluated(int n) {65  if (!n)66    return 0;67  static const int m = n; // expected-note {{control flows through the definition of a static variable}} \68                          // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}69  return m;70}71 72constexpr int je = j_evaluated(1); // expected-error {{constexpr variable 'je' must be initialized by a constant expression}}  \73                                   // expected-note {{in call}}74 75constexpr int k_evaluated(int n) {76  if (!n)77    return 0;78  thread_local const int m = n; // expected-note {{control flows through the definition of a thread_local variable}} \79                                // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}80 81  return m;82}83 84constexpr int ke = k_evaluated(1); // expected-error {{constexpr variable 'ke' must be initialized by a constant expression}} \85                                   // expected-note {{in call}}86 87constexpr int static_constexpr() {88  static constexpr int m = 42;     // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}89  static constexpr Constexpr foo; // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}90  return m;91}92 93constexpr int thread_local_constexpr() {94  thread_local constexpr int m = 42; // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}95  thread_local constexpr Constexpr foo; // cxx23-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++23}}96  return m;97}98 99constexpr int non_literal(bool b) {100  if (!b)101    return 0;102  NonLiteral n; // cxx23-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++23}}103}104 105constexpr int non_literal_1 = non_literal(false);106 107namespace eval_goto {108 109constexpr int f(int x) {110  if (x) {111    return 0;112  } else {113    goto test; // expected-note {{subexpression not valid in a constant expression}} \114               // cxx23-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++23}}115  }116test:117  return 0;118}119 120int a = f(0);121constexpr int b = f(0); // expected-error {{must be initialized by a constant expression}} \122                        // expected-note {{in call to 'f(0)'}}123constexpr int c = f(1);124 125constexpr int label() {126 127test: // cxx23-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++23}}128  return 0;129}130 131constexpr int d = label();132 133} // namespace eval_goto134 135#endif136 137// Test that explicitly constexpr lambdas behave correctly,138// This is to be contrasted with the test for implicitly constexpr lambdas below.139int test_in_lambdas() {140  auto a = []() constexpr {141    static const int m = 32; // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}142    return m;143  };144 145  auto b = [](int n) constexpr {146    if (!n)147      return 0;148    static const int m = n; // cxx23-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++23}}149    return m;150  }151  (1);152 153  auto c = [](int n) constexpr {154    if (!n)155      return 0;156    else157      goto test; // expected-note {{subexpression not valid in a constant expression}} \158                 // cxx23-warning {{use of this statement in a constexpr function is incompatible with C++ standards before C++23}}159  test:160    return 1;161  };162  c(0);163  constexpr auto c_error = c(1); // expected-error {{constexpr variable 'c_error' must be initialized by a constant expression}} \164                                 // expected-note {{in call to}}165 166  auto non_literal = [](bool b) constexpr {167    if (!b)168      NonLiteral n; // cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++23}} \169                    // cxx23-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++23}} \170		    // cxx23-note {{non-constexpr constructor 'NonLiteral' cannot be used in a constant expression}}171    return 0;172  };173 174#if __cplusplus > 202002L175  constexpr auto non_literal_ko = non_literal(false); // cxx23-error {{constexpr variable 'non_literal_ko' must be initialized by a constant expression}} \176                                                      // cxx23-note {{in call}}177 178  constexpr auto non_literal_ok = non_literal(true);179#endif180}181 182// Test whether lambdas are correctly treated as implicitly constexpr under the183// relaxed C++23 rules (and similarly as not implicitly constexpr under the184// C++20 rules).185int test_lambdas_implicitly_constexpr() {186 187  auto b = [](int n) { // cxx2a-note 2{{declared here}}188    if (!n)189      return 0;190    static const int m = n; // cxx23-note {{control flows through the definition of a static variable}}191    return m;192  };193 194  auto b1 = b(1);195  constexpr auto b2 = b(0); // cxx2a-error {{must be initialized by a constant expression}} \196                            // cxx2a-note {{non-constexpr function}}197 198  constexpr auto b3 = b(1); // expected-error{{constexpr variable 'b3' must be initialized by a constant expression}} \199                            // cxx2a-note {{non-constexpr function}} \200                            // cxx23-note {{in call}}201 202  auto c = [](int n) { // cxx2a-note 2{{declared here}}203    if (!n)204      return 0;205    else206      goto test; // cxx23-note {{subexpression not valid in a constant expression}}207  test:208    return 1;209  };210  c(0);211  constexpr auto c_ok = c(0); // cxx2a-error {{must be initialized by a constant expression}} \212                              // cxx2a-note {{non-constexpr function}}213 214  constexpr auto c_error = c(1); // expected-error {{constexpr variable 'c_error' must be initialized by a constant expression}} \215                                 // cxx2a-note {{non-constexpr function}} \216                                 // cxx23-note {{in call to}}217 218  auto non_literal = [](bool b) { // cxx2a-note 2{{declared here}}219    if (b)220      NonLiteral n; // cxx23-note {{non-constexpr constructor 'NonLiteral' cannot be used in a constant expression}}221    return 0;222  };223 224  constexpr auto non_literal_ko = non_literal(true); // expected-error {{constexpr variable 'non_literal_ko' must be initialized by a constant expression}} \225                                                     // cxx2a-note {{non-constexpr function}} \226                                                     // cxx23-note {{in call}}227 228  constexpr auto non_literal_ok = non_literal(false); // cxx2a-error {{must be initialized by a constant expression}} \229                                                      // cxx2a-note {{non-constexpr function}}230}231 232template <typename T>233constexpr auto dependent_var_def_lambda() {234  return [](bool b) { // cxx2a-note {{declared here}}235    if (!b)236      T t;237    return 0;238  };239}240 241constexpr auto non_literal_valid_in_cxx23 = dependent_var_def_lambda<NonLiteral>()(true); // \242    // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx23' must be initialized by a constant expression}} \243    // cxx2a-note {{non-constexpr function}}244 245 246constexpr double evaluate_static_constexpr() {247  struct Constexpr{248    constexpr double f() const {249      return 42;250    }251  };252  thread_local constexpr Constexpr t; // cxx23-warning {{before C++23}}253  static constexpr Constexpr s; // cxx23-warning {{before C++23}}254  return t.f() + s.f();255}256static_assert(evaluate_static_constexpr() == 84);257