xref: /llvm-project/clang/test/AST/ByteCode/references.cpp (revision f79722b932ce40edf2937f3b9386e6fb43757bce)
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