brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · 3da3996 Raw
197 lines · cpp
1// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s2// RUN: %clang_cc1                                         -verify=ref,both      %s3 4 5constexpr int a = 10;6constexpr const int &b = a;7static_assert(a == b, "");8 9constexpr int assignToReference() {10  int a = 20;11  int &b = a;12 13  b = 100;14  return a;15}16static_assert(assignToReference() == 100, "");17 18 19constexpr void setValue(int &dest, int val) {20  dest = val;21}22 23constexpr int checkSetValue() {24  int l = 100;25  setValue(l, 200);26  return l;27}28static_assert(checkSetValue() == 200, "");29 30constexpr int readLocalRef() {31  int a = 20;32  int &b = a;33  return b;34}35static_assert(readLocalRef() == 20, "");36 37constexpr int incRef() {38  int a = 0;39  int &b = a;40 41  b = b + 1;42 43  return a;44}45static_assert(incRef() == 1, "");46 47 48template<const int &V>49constexpr void Plus3(int &A) {50  A = V + 3;51}52constexpr int foo = 4;53 54constexpr int callTemplate() {55  int a = 3;56  Plus3<foo>(a);57  return a;58}59static_assert(callTemplate() == 7, "");60 61 62constexpr int& getValue(int *array, int index) {63  return array[index];64}65constexpr int testGetValue() {66  int values[] = {1, 2, 3, 4};67  getValue(values, 2) = 30;68  return values[2];69}70static_assert(testGetValue() == 30, "");71 72constexpr const int &MCE = 20;73static_assert(MCE == 20, "");74static_assert(MCE == 30, ""); // both-error {{static assertion failed}} \75                              // both-note {{evaluates to '20 == 30'}}76 77constexpr int LocalMCE() {78  const int &m = 100;79  return m;80}81static_assert(LocalMCE() == 100, "");82static_assert(LocalMCE() == 200, ""); // both-error {{static assertion failed}} \83                                      // both-note {{evaluates to '100 == 200'}}84 85struct S {86  int i, j;87};88 89constexpr int RefToMemberExpr() {90  S s{1, 2};91 92  int &j = s.i;93  j = j + 10;94 95  return j;96}97static_assert(RefToMemberExpr() == 11, "");98 99struct Ref {100  int &a;101};102 103constexpr int RecordWithRef() {104  int m = 100;105  Ref r{m};106  m = 200;107  return r.a;108}109static_assert(RecordWithRef() == 200, "");110 111 112struct Ref2 {113  int &a;114  constexpr Ref2(int &a) : a(a) {}115};116 117constexpr int RecordWithRef2() {118  int m = 100;119  Ref2 r(m);120  m = 200;121  return r.a;122}123static_assert(RecordWithRef2() == 200, "");124 125const char (&nonextended_string_ref)[3] = {"hi"};126static_assert(nonextended_string_ref[0] == 'h', "");127static_assert(nonextended_string_ref[1] == 'i', "");128static_assert(nonextended_string_ref[2] == '\0', "");129 130/// This isa non-constant context. Reading A is not allowed,131/// but taking its address is.132int &&A = 12;133int arr[!&A];134 135namespace Temporaries {136  struct A { int n; };137  struct B { const A &a; };138  const B j = {{1}}; // both-note {{temporary created here}}139 140  static_assert(j.a.n == 1, "");  // both-error {{not an integral constant expression}} \141                                  // both-note {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}}142}143 144namespace Params {145  typedef __SIZE_TYPE__ size_t;146 147  template <class _Tp, size_t _Np>148  constexpr _Tp* end(_Tp (&__array)[_Np]) noexcept {149    return __array + _Np;150  }151 152 153  struct classnames {154    const char* elem_;155    int a;156  };157 158  constexpr classnames ClassNames[] = {159    {"a", 0},160    {"b", 1},161    {"b", 1},162    {"b", 1},163    {"b", 1},164    {"b", 1},165    {"b", 1},166    {"b", 1},167  };168 169  constexpr bool foo() {170    /// This will instantiate end() with ClassNames.171    /// In Sema, we will constant-evaluate the return statement, which is172    /// something like __array + 8. The APValue we return for this173    /// may NOT have a LValuePath set, since it's for a parameter174    /// of LValueReferenceType.175    end(ClassNames);176    return true;177  }178 179  static_assert(foo());180}181 182namespace ReadFromNullBlockPtr {183  struct S {184    int *const &t;185  };186 187  void foo(int x) {188    constexpr S s = {&x}; // both-error {{must be initialized by a constant expression}} \189                          // both-note {{reference to temporary}} \190                          // both-note {{created here}} \191                          // ref-note {{declared here}}192    static_assert(s.t == &x, ""); // both-error {{not an integral constant expression}} \193                                  // expected-note {{read of dereferenced null pointer}} \194                                  // ref-note {{initializer of 's' is not a constant expression}}195  }196}197