brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · 65d3339 Raw
210 lines · cpp
1// RUN: %clang_cc1 -std=c++2c -verify -emit-llvm -triple=x86_64-pc-linux-gnu %s -o -                                         | FileCheck %s2// RUN: %clang_cc1 -std=c++2c -verify -emit-llvm -triple=x86_64-pc-linux-gnu %s -o - -fexperimental-new-constant-interpreter | FileCheck %s3// expected-no-diagnostics4 5namespace std {6 7template <typename T> struct tuple_size;8 9template <int, typename> struct tuple_element;10 11} // namespace std12 13namespace Case1 {14 15struct S {16  int a, b;17  bool flag = false;18 19  constexpr explicit operator bool() {20    flag = true;21    return a != b;22  }23 24  constexpr operator int() {25    flag = true;26    return a * b;27  }28 29  constexpr bool operator==(S rhs) const {30    return a == rhs.a && b == rhs.b;31  }32 33  template <int I>34  constexpr int& get() {35    if (!flag)36      return a = a + b;37    return I == 0 ? a : b;38  }39};40 41} // namespace Case142 43template <> struct std::tuple_size<Case1::S> {44  static const int value = 2;45};46 47template <int I> struct std::tuple_element<I, Case1::S> {48  using type = int;49};50 51namespace Case1 {52 53void foo() {54  if (S s(1, 2); auto [a, b] = s) {55    __builtin_assume(a == 1);56    __builtin_assume(b == 2);57  }58// CHECK: %[[call:.+]] = call {{.*}} i1 @_ZN5Case11ScvbEv59// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi0EEERiv60// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi1EEERiv61// CHECK: br i1 %[[call]], label {{.*}}, label {{.*}}62 63  if (auto [a, b] = S(1, 2)) {64    __builtin_assume(a == 1);65    __builtin_assume(b == 2);66  }67// CHECK: %[[call2:.+]] = call {{.*}} i1 @_ZN5Case11ScvbEv68// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi0EEERiv69// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi1EEERiv70// CHECK: br i1 %[[call2]], label {{.*}}, label {{.*}}71 72  if (S s(3, 4); auto& [a, b] = s) {73    __builtin_assume(a == 3);74    __builtin_assume(b == 4);75  }76// CHECK: %[[call3:.+]] = call {{.*}} i1 @_ZN5Case11ScvbEv77// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi0EEERiv78// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi1EEERiv79// CHECK: br i1 %[[call3]], label {{.*}}, label {{.*}}80 81  while (auto [i, j] = S(5, 6))82    break;83 84// CHECK: while.cond{{.*}}:85// CHECK: %[[call4:.+]] = call {{.*}} i1 @_ZN5Case11ScvbEv86// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi0EEERiv87// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi1EEERiv88// CHECK: br i1 %[[call4]], label {{.*}}, label {{.*}}89 90  S s(7, 8);91  while (auto& [i, j] = s)92    break;93 94// CHECK: while.cond{{.*}}:95// CHECK: %[[call5:.+]] = call {{.*}} i1 @_ZN5Case11ScvbEv96// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi0EEERiv97// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi1EEERiv98// CHECK: br i1 %[[call5]], label {{.*}}, label {{.*}}99 100  for (int k = 0; auto [i, j] = S(24, 42); ++k)101    break;102 103// CHECK: for.cond{{.*}}:104// CHECK: %[[call6:.+]] = call {{.*}} i1 @_ZN5Case11ScvbEv105// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi0EEERiv106// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi1EEERiv107// CHECK: br i1 %[[call6]], label {{.*}}, label {{.*}}108 109  for (S s(114, 514); auto& [i, j] = s; ++i)110    break;111 112// CHECK: for.cond{{.*}}:113// CHECK: %[[call7:.+]] = call {{.*}} i1 @_ZN5Case11ScvbEv114// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi0EEERiv115// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi1EEERiv116// CHECK: br i1 %[[call7]], label {{.*}}, label {{.*}}117 118  switch (S s(10, 11); auto& [i, j] = s) {119    case 10 * 11:120      __builtin_assume(i == 10);121      __builtin_assume(j == 11);122      break;123    default:124      break;125  }126 127// CHECK: %[[call8:.+]] = call {{.*}} i32 @_ZN5Case11ScviEv128// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi0EEERiv129// CHECK: %{{.*}} = call {{.*}} ptr @_ZN5Case11S3getILi1EEERiv130// CHECK: switch i32 %[[call8]], label {{.*}}131 132}133 134constexpr int bar(auto) {135  constexpr auto value = [] {136    if (S s(1, 2); auto [i, j] = s)137      return S(i, j);138    return S(0, 0);139  }();140  static_assert(value == S(1, 2));141 142  constexpr auto value2 = [] {143    if (auto [a, b] = S(1, 2))144      return S(a, b);145    return S(0, 0);146  }();147  static_assert(value2 == S(1, 2));148 149  constexpr auto value3 = [] {150    if (auto&& [a, b] = S(3, 4))151      return S(a, b);152    return S(0, 0);153  }();154  static_assert(value3 == S(3, 4));155 156  constexpr auto value4 = [] {157    S s(7, 8);158    int cnt = 0;159    while (auto& [i, j] = s) {160      s.flag = false;161      ++i, ++j;162      if (++cnt == 10)163        break;164    }165    return s;166  }();167  static_assert(value4 == S(17, 18));168 169  constexpr auto value5 = [] {170    S s(3, 4);171    for (int cnt = 0; auto& [x, y] = s; s.flag = false, ++cnt) {172      if (cnt == 3)173        break;174      ++x, ++y;175    }176    return s;177  }();178  static_assert(value5 == S(6, 7));179 180  constexpr auto value6 = [] {181    switch (auto [x, y] = S(3, 4)) {182      case 3 * 4:183        return S(x, y);184      default:185        return S(y, x);186    }187  }();188  static_assert(value6 == S(3, 4));189 190  return 42;191}192 193constexpr int value = bar(1);194 195#if 0196 197// FIXME: This causes clang to ICE, though this is not a regression.198constexpr int ice(auto) {199  if constexpr (S s(1, 2); auto [i, j] = s) {200    static_assert(i == 1);201  }202  return 42;203}204 205constexpr int value2 = ice(1);206 207#endif208 209} // namespace Case1210