1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s 2 // RUN: %clang_cc1 -verify=ref,both %s 3 4 5 constexpr int a = 10; 6 constexpr const int &b = a; 7 static_assert(a == b, ""); 8 9 constexpr int assignToReference() { 10 int a = 20; 11 int &b = a; 12 13 b = 100; 14 return a; 15 } 16 static_assert(assignToReference() == 100, ""); 17 18 19 constexpr void setValue(int &dest, int val) { 20 dest = val; 21 } 22 23 constexpr int checkSetValue() { 24 int l = 100; 25 setValue(l, 200); 26 return l; 27 } 28 static_assert(checkSetValue() == 200, ""); 29 30 constexpr int readLocalRef() { 31 int a = 20; 32 int &b = a; 33 return b; 34 } 35 static_assert(readLocalRef() == 20, ""); 36 37 constexpr int incRef() { 38 int a = 0; 39 int &b = a; 40 41 b = b + 1; 42 43 return a; 44 } 45 static_assert(incRef() == 1, ""); 46 47 48 template<const int &V> 49 constexpr void Plus3(int &A) { 50 A = V + 3; 51 } 52 constexpr int foo = 4; 53 54 constexpr int callTemplate() { 55 int a = 3; 56 Plus3<foo>(a); 57 return a; 58 } 59 static_assert(callTemplate() == 7, ""); 60 61 62 constexpr int& getValue(int *array, int index) { 63 return array[index]; 64 } 65 constexpr int testGetValue() { 66 int values[] = {1, 2, 3, 4}; 67 getValue(values, 2) = 30; 68 return values[2]; 69 } 70 static_assert(testGetValue() == 30, ""); 71 72 constexpr const int &MCE = 20; 73 static_assert(MCE == 20, ""); 74 static_assert(MCE == 30, ""); // both-error {{static assertion failed}} \ 75 // both-note {{evaluates to '20 == 30'}} 76 77 constexpr int LocalMCE() { 78 const int &m = 100; 79 return m; 80 } 81 static_assert(LocalMCE() == 100, ""); 82 static_assert(LocalMCE() == 200, ""); // both-error {{static assertion failed}} \ 83 // both-note {{evaluates to '100 == 200'}} 84 85 struct S { 86 int i, j; 87 }; 88 89 constexpr int RefToMemberExpr() { 90 S s{1, 2}; 91 92 int &j = s.i; 93 j = j + 10; 94 95 return j; 96 } 97 static_assert(RefToMemberExpr() == 11, ""); 98 99 struct Ref { 100 int &a; 101 }; 102 103 constexpr int RecordWithRef() { 104 int m = 100; 105 Ref r{m}; 106 m = 200; 107 return r.a; 108 } 109 static_assert(RecordWithRef() == 200, ""); 110 111 112 struct Ref2 { 113 int &a; 114 constexpr Ref2(int &a) : a(a) {} 115 }; 116 117 constexpr int RecordWithRef2() { 118 int m = 100; 119 Ref2 r(m); 120 m = 200; 121 return r.a; 122 } 123 static_assert(RecordWithRef2() == 200, ""); 124 125 const char (&nonextended_string_ref)[3] = {"hi"}; 126 static_assert(nonextended_string_ref[0] == 'h', ""); 127 static_assert(nonextended_string_ref[1] == 'i', ""); 128 static_assert(nonextended_string_ref[2] == '\0', ""); 129 130 /// This isa non-constant context. Reading A is not allowed, 131 /// but taking its address is. 132 int &&A = 12; 133 int arr[!&A]; 134 135 namespace 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