brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.4 KiB · a594a1a Raw
206 lines · cpp
1// RUN: %clang_cc1 -std=c++23  -x c++ %s -verify2// RUN: %clang_cc1 -std=c++20 -pedantic -x c++ %s -verify=ext,expected3// RUN: %clang_cc1 -std=c++23  -x c++ %s -verify -fexperimental-new-constant-interpreter4// RUN: %clang_cc1 -std=c++20 -pedantic -x c++ %s -verify=ext,expected -fexperimental-new-constant-interpreter5// RUN: %clang_cc1 -std=c++26  -x c++ %s -verify6// RUN: %clang_cc1 -std=c++26  -x c++ %s -verify -fexperimental-new-constant-interpreter7 8struct A{};9struct B{ explicit operator bool() { return true; } };10 11// This should be the first test case of this file.12void IsActOnFinishFullExprCalled() {13  // Do not add other test cases to this function.14  // Make sure `ActOnFinishFullExpr` is called and creates `ExprWithCleanups`15  // to avoid assertion failure.16  [[assume(B{})]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}}17}18 19template <bool cond>20void f() {21  [[assume(cond)]]; // ext-warning {{C++23 extension}}22}23 24template <bool cond>25struct S {26  void f() {27    [[assume(cond)]]; // ext-warning {{C++23 extension}}28  }29 30  template <typename T>31  constexpr bool g() {32    [[assume(cond == sizeof(T))]]; // expected-note {{assumption evaluated to false}} ext-warning {{C++23 extension}}33    return true;34  }35};36 37bool f2();38 39template <typename T>40constexpr void f3() {41  [[assume(T{})]]; // expected-error {{not contextually convertible to 'bool'}} expected-warning {{assumption is ignored because it contains (potential) side-effects}} ext-warning {{C++23 extension}}42}43 44void g(int x) {45  f<true>();46  f<false>();47  S<true>{}.f();48  S<false>{}.f();49  S<true>{}.g<char>();50  S<true>{}.g<int>();51  [[assume(f2())]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} ext-warning {{C++23 extension}}52 53  [[assume((x = 3))]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}}54  [[assume(x++)]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}}55  [[assume(++x)]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}}56  [[assume([]{ return true; }())]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}}57  [[assume(B{})]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}}58  [[assume((1, 2))]]; // expected-warning {{has no effect}} // ext-warning {{C++23 extension}}59 60  f3<A>(); // expected-note {{in instantiation of}}61  f3<B>(); // expected-note {{in instantiation of}}62  [[assume]]; // expected-error {{takes one argument}}63  [[assume(z)]]; // expected-error {{undeclared identifier}}64  [[assume(A{})]]; // expected-error {{not contextually convertible to 'bool'}}65  [[assume(true)]] if (true) {} // expected-error {{only applies to empty statements}}66  [[assume(true)]] {} // expected-error {{only applies to empty statements}}67  [[assume(true)]] for (;false;) {} // expected-error {{only applies to empty statements}}68  [[assume(true)]] while (false) {} // expected-error {{only applies to empty statements}}69  [[assume(true)]] label:; // expected-error {{cannot be applied to a declaration}}70  [[assume(true)]] goto label; // expected-error {{only applies to empty statements}}71 72  // Also check variant spellings.73  __attribute__((__assume__(true))); // Should not issue a warning because it doesn't use the [[]] spelling.74  __attribute__((assume(true))) {}; // expected-error {{only applies to empty statements}}75  [[clang::assume(true)]] {}; // expected-error {{only applies to empty statements}}76}77 78// Check that 'x' is ODR-used here.79constexpr int h(int x) { return sizeof([=] { [[assume(x)]]; }); } // ext-warning {{C++23 extension}}80static_assert(h(4) == sizeof(int));81 82static_assert(__has_cpp_attribute(assume) == 202207L);83static_assert(__has_attribute(assume));84 85constexpr bool i() { // ext-error {{never produces a constant expression}}86  [[assume(false)]]; // ext-note {{assumption evaluated to false}} expected-note {{assumption evaluated to false}} ext-warning {{C++23 extension}}87  return true;88}89 90constexpr bool j(bool b) {91  [[assume(b)]]; // expected-note {{assumption evaluated to false}} ext-warning {{C++23 extension}}92  return true;93}94 95static_assert(i()); // expected-error {{not an integral constant expression}} expected-note {{in call to}}96static_assert(j(true));97static_assert(j(false)); // expected-error {{not an integral constant expression}} expected-note {{in call to}}98static_assert(S<true>{}.g<char>());99static_assert(S<false>{}.g<A>()); // expected-error {{not an integral constant expression}} expected-note {{in call to}}100 101 102template <typename T>103constexpr bool f4() {104  [[assume(!T{})]]; // expected-error {{invalid argument type 'D'}} // expected-warning 2 {{assumption is ignored because it contains (potential) side-effects}} ext-warning {{C++23 extension}}105  return sizeof(T) == sizeof(int);106}107 108template <typename T>109concept C = f4<T>(); // expected-note 3 {{in instantiation of}}110                     // expected-note@-1 3 {{while substituting}}111                     // expected-error@-2 {{resulted in a non-constant expression}}112                     // expected-note@-3 {{because substituted constraint expression is ill-formed: substitution into constraint expression resulted in a non-constant expression}}113 114struct D {115  int x;116};117 118struct E {119  int x;120  constexpr explicit operator bool() { return false; }121};122 123struct F {124  int x;125  int y;126  constexpr explicit operator bool() { return false; }127};128 129template <typename T>130constexpr int f5() requires C<T> { return 1; } // expected-note {{while checking the satisfaction}}131                                               // expected-note@-1 {{candidate template ignored}}132 133template <typename T>134constexpr int f5() requires (!C<T>) { return 2; } // expected-note 3 {{while checking the satisfaction}} \135                                                  // expected-note 3 {{while substituting template arguments}} \136                                                  // expected-note {{candidate template ignored}}137 138static_assert(f5<int>() == 1);139static_assert(f5<D>() == 1); // expected-note 2 {{while checking constraint satisfaction}}140                             // expected-note@-1 2 {{while substituting deduced template arguments}}141                             // expected-error@-2 {{no matching function for call}}142 143static_assert(f5<double>() == 2);144static_assert(f5<E>() == 1); // expected-note {{while checking constraint satisfaction}} expected-note {{while substituting deduced template arguments}}145static_assert(f5<F>() == 2); // expected-note {{while checking constraint satisfaction}} expected-note {{while substituting deduced template arguments}}146 147// Do not validate assumptions whose evaluation would have side-effects.148constexpr int foo() {149  int a = 0;150  [[assume(a++)]] [[assume(++a)]]; // expected-warning 2 {{assumption is ignored because it contains (potential) side-effects}} ext-warning 2 {{C++23 extension}}151  [[assume((a+=1))]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} ext-warning {{C++23 extension}}152  return a;153}154 155static_assert(foo() == 0);156 157template <bool ...val>158void f() {159    [[assume(val)]]; // expected-error {{expression contains unexpanded parameter pack}}160}161 162namespace gh71858 {163int164foo (int x, int y)165{166  __attribute__((assume(x == 42)));167  __attribute__((assume(++y == 43))); // expected-warning {{assumption is ignored because it contains (potential) side-effects}}168  return x + y;169}170}171 172// Do not crash when assumptions are unreachable.173namespace gh106898 {174int foo () {175    while(1);176    int a = 0, b = 1;177    __attribute__((assume (a < b)));178}179}180 181namespace GH114787 {182 183// FIXME: Correct the C++26 value184#if __cplusplus >= 202400L185 186constexpr int test(auto... xs) {187  // FIXME: Investigate why addresses of PackIndexingExprs are printed for the next188  // 'in call to' note.189  return [&]<int I>() { // expected-note {{in call to}}190    [[assume(191      xs...[I] == 2192    )]];193    [[assume(194      xs...[I + 1] == 0 // expected-note {{assumption evaluated to false}}195    )]];196    return xs...[I];197  }.template operator()<1>();198}199 200static_assert(test(1, 2, 3, 5, 6) == 2); // expected-error {{not an integral constant expression}} \201                                         // expected-note {{in call to}}202 203#endif204 205} // namespace GH114787206