brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · 0cf3a4f Raw
152 lines · cpp
1// RUN: %clang_cc1 -std=c++17 -verify=expected,both %s -fexperimental-new-constant-interpreter2// RUN: %clang_cc1 -std=c++17 -verify=ref,both      %s3 4[[clang::require_constant_initialization]] int cc = cc; // both-error {{variable does not have a constant initializer}} \5                                                        // both-note {{attribute here}} \6                                                        // both-note {{ead of object outside its lifetime}}7 8 9struct F { int a; int b;};10constexpr F getF() {11  return {12, 3};12}13constexpr int f() {14  auto [a1, b1] = getF();15  auto [a2, b2] = getF();16 17  return a1 + a2 + b1 + b2;18}19static_assert(f() == 30);20 21 22constexpr int structRefs() {23  const auto &[a, b] = getF();24 25  return a + b;26}27static_assert(structRefs() == 15);28 29constexpr int structRefs2() {30  F f = getF();31  const auto &[a, b] = f;32 33  return a + b;34}35static_assert(structRefs2() == 15);36 37 38template<typename T>39struct Tuple {40  T first;41  T second;42  constexpr Tuple(T a, T b) : first(a), second(b) {}43};44template<typename T>45constexpr T addTuple(const Tuple<T> &Tu) {46  auto [a, b] = Tu;47  return a + b;48}49 50template<typename T>51constexpr T addTuple2(const Tuple<T> &Tu) {52  auto [a, b] = Tu;53  return Tu.first + Tu.second;54}55 56constexpr Tuple<int> T1 = Tuple(1,2);57static_assert(addTuple(T1) == 3);58static_assert(addTuple2(T1) == 3);59 60constexpr Tuple<short> T2 = Tuple<short>(11,2);61static_assert(addTuple(T2) == 13);62static_assert(addTuple2(T2) == 13);63 64constexpr int Modify() {65  auto T = Tuple<int>(10, 20);66  auto &[x, y] = T;67  x += 1;68  y += 1;69  return T.first + T.second;70}71static_assert(Modify() == 32, "");72 73constexpr int a() {74  int a[2] = {5, 3};75  auto [x, y] = a;76  return x + y;77}78static_assert(a() == 8);79 80constexpr int b() {81  int a[2] = {5, 3};82  auto &[x, y] = a;83  x += 1;84  y += 2;85  return a[0] + a[1];86}87static_assert(b() == 11);88 89namespace cwg1872 {90  template<typename T> struct A : T {91    constexpr int f() const { return 0; }92  };93  struct X {};94  struct Y { virtual int f() const; };95  struct Z : virtual X {};96 97  constexpr int z = A<Z>().f(); // both-error {{must be initialized by a constant expression}} \98                                // both-note {{non-literal type 'A<Z>' cannot be used in a constant expression}}99}100 101/// The diagnostics between the two interpreters used to be different here.102struct S { int a; };103constexpr S getS() { // both-error {{constexpr function never produces a constant expression}}104  (void)(1/0); // both-note 2{{division by zero}} \105               // both-warning {{division by zero}}106  return S{12};107}108constexpr S s = getS(); // both-error {{must be initialized by a constant expression}} \109                        // both-note {{in call to 'getS()'}} \110                        // both-note {{declared here}}111static_assert(s.a == 12, ""); // both-error {{not an integral constant expression}} \112                              // both-note {{initializer of 's' is not a constant expression}}113 114using size_t = decltype(sizeof(0));115namespace std { template<typename T> struct tuple_size; }116namespace std { template<size_t, typename> struct tuple_element; }117 118namespace constant {119  struct Q {};120  template<int N> constexpr int get(Q &&) { return N * N; }121}122template<> struct std::tuple_size<constant::Q> { static const int value = 3; };123template<int N> struct std::tuple_element<N, constant::Q> { typedef int type; };124 125namespace constant {126  Q q;127  constexpr bool f() {128    auto [a, b, c] = q;129    return a == 0 && b == 1 && c == 4;130  }131  static_assert(f());132}133 134 135template <int a> struct i; // both-note {{template is declared here}}136template <> struct i<0> {};137 138template <int x> constexpr auto c() {139  i<x> g; // both-error {{implicit instantiation of undefined template 'i<1>'}}140  return 0;141}142 143auto y = c<1>(); // both-note {{in instantiation of function template specialization 'c<1>' requested here}}144 145namespace NonConstexprStructuredBinding {146  void f1() {147    int arr[2] = {};148    auto [a, b] = arr;149    static_assert(&a != &b);150  }151}152