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