1 /*
2 * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import java.io.PrintStream;
25 import jdk.incubator.code.Reflect;
26 import java.util.Spliterator;
27 import java.util.Spliterator.OfInt;
28
29 import static java.lang.System.out;
30 import static java.util.Spliterator.OfInt.*;
31
32 /*
33 * @test
34 * @summary Smoke test for code reflection with field access.
35 * @modules jdk.incubator.code
36 * @build FieldAccessTest
37 * @build CodeReflectionTester
38 * @run main CodeReflectionTester FieldAccessTest
39 */
40
41 public class FieldAccessTest {
42 static int s_f;
43 int f;
44
45 @Reflect
46 @IR("""
47 func @"test1" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
48 %1 : java.type:"int" = constant @1;
49 field.store %1 @java.ref:"FieldAccessTest::s_f:int";
50 %2 : java.type:"int" = constant @1;
51 field.store %0 %2 @java.ref:"FieldAccessTest::f:int";
52 return;
53 };
54 """)
55 void test1() {
56 s_f = 1;
57 f = 1;
58 }
59
60 @Reflect
61 @IR("""
62 func @"test1_1" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
63 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
64 %2 : java.type:"int" = constant @1;
65 %3 : java.type:"int" = add %1 %2;
66 field.store %0 %3 @java.ref:"FieldAccessTest::f:int";
67 %4 : java.type:"int" = field.load @java.ref:"FieldAccessTest::s_f:int";
68 %5 : java.type:"int" = constant @1;
69 %6 : java.type:"int" = add %4 %5;
70 field.store %6 @java.ref:"FieldAccessTest::s_f:int";
71 return;
72 };
73 """)
74 void test1_1() {
75 f += 1;
76 s_f += 1;
77 }
78
79 @Reflect
80 @IR("""
81 func @"test2" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
82 %1 : java.type:"int" = constant @1;
83 field.store %0 %1 @java.ref:"FieldAccessTest::f:int";
84 field.store %1 @java.ref:"FieldAccessTest::s_f:int";
85 return;
86 };
87 """)
88 void test2() {
89 s_f = f = 1;
90 }
91
92 @Reflect
93 @IR("""
94 func @"test2_1" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
95 %1 : java.type:"int" = constant @1;
96 field.store %0 %1 @java.ref:"FieldAccessTest::f:int";
97 return;
98 };
99 """)
100 void test2_1() {
101 this.f = 1;
102 }
103
104 @Reflect
105 @IR("""
106 func @"test2_2" (%0 : java.type:"FieldAccessTest")java.type:"int" -> {
107 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
108 return %1;
109 };
110 """)
111 int test2_2() {
112 return this.f;
113 }
114
115 @Reflect
116 @IR("""
117 func @"test2_3" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
118 %1 : java.type:"int" = constant @1;
119 field.store %0 %1 @java.ref:"FieldAccessTest::f:int";
120 return;
121 };
122 """)
123 void test2_3() {
124 FieldAccessTest.this.f = 1;
125 }
126
127 @Reflect
128 @IR("""
129 func @"test2_4" (%0 : java.type:"FieldAccessTest")java.type:"int" -> {
130 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
131 return %1;
132 };
133 """)
134 int test2_4() {
135 return FieldAccessTest.this.f;
136 }
137
138 @Reflect
139 @IR("""
140 func @"test3" (%0 : java.type:"FieldAccessTest")java.type:"int" -> {
141 %1 : java.type:"int" = field.load @java.ref:"FieldAccessTest::s_f:int";
142 %2 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
143 %3 : java.type:"int" = add %1 %2;
144 return %3;
145 };
146 """)
147 int test3() {
148 return s_f + f;
149 }
150
151 static class A {
152 B b;
153 }
154
155 static class B {
156 C c;
157 }
158
159 static class C {
160 int f;
161 }
162
163 @Reflect
164 @IR("""
165 func @"test4" (%0 : java.type:"FieldAccessTest", %1 : java.type:"FieldAccessTest$A")java.type:"void" -> {
166 %2 : Var<java.type:"FieldAccessTest$A"> = var %1 @"a";
167 %3 : java.type:"FieldAccessTest$A" = var.load %2;
168 %4 : java.type:"FieldAccessTest$B" = field.load %3 @java.ref:"FieldAccessTest$A::b:FieldAccessTest$B";
169 %5 : java.type:"FieldAccessTest$C" = field.load %4 @java.ref:"FieldAccessTest$B::c:FieldAccessTest$C";
170 %6 : java.type:"int" = constant @1;
171 field.store %5 %6 @java.ref:"FieldAccessTest$C::f:int";
172 return;
173 };
174 """)
175 void test4(A a) {
176 a.b.c.f = 1;
177 }
178
179 static class X {
180 int f;
181 static int s_f;
182 }
183
184 @Reflect
185 @IR("""
186 func @"test5" (%0 : java.type:"FieldAccessTest")java.type:"int" -> {
187 %1 : java.type:"int" = field.load @java.ref:"FieldAccessTest$X::s_f:int";
188 return %1;
189 };
190 """)
191 int test5() {
192 return X.s_f;
193 }
194
195 @Reflect
196 @IR("""
197 func @"test6" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
198 %1 : java.type:"int" = constant @1;
199 field.store %1 @java.ref:"FieldAccessTest$X::s_f:int";
200 return;
201 };
202 """)
203 void test6() {
204 X.s_f = 1;
205 }
206
207
208 @Reflect
209 @IR("""
210 func @"test7" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
211 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
212 %2 : java.type:"int" = constant @1;
213 %3 : java.type:"int" = add %1 %2;
214 field.store %0 %3 @java.ref:"FieldAccessTest::f:int";
215 %4 : java.type:"int" = field.load @java.ref:"FieldAccessTest::s_f:int";
216 %5 : java.type:"int" = constant @1;
217 %6 : java.type:"int" = add %4 %5;
218 field.store %6 @java.ref:"FieldAccessTest::s_f:int";
219 return;
220 };
221 """)
222 void test7() {
223 f += 1;
224 s_f += 1;
225 }
226
227 @Reflect
228 @IR("""
229 func @"test8" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
230 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
231 %2 : java.type:"int" = constant @1;
232 %3 : java.type:"int" = add %1 %2;
233 field.store %0 %3 @java.ref:"FieldAccessTest::f:int";
234 %4 : java.type:"int" = field.load @java.ref:"FieldAccessTest::s_f:int";
235 %5 : java.type:"int" = constant @1;
236 %6 : java.type:"int" = add %4 %5;
237 field.store %6 @java.ref:"FieldAccessTest::s_f:int";
238 return;
239 };
240 """)
241 void test8() {
242 this.f += 1;
243 this.s_f += 1;
244 }
245
246 @Reflect
247 @IR("""
248 func @"test9" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
249 %1 : java.type:"int" = field.load @java.ref:"FieldAccessTest$X::s_f:int";
250 %2 : java.type:"int" = constant @1;
251 %3 : java.type:"int" = add %1 %2;
252 field.store %3 @java.ref:"FieldAccessTest$X::s_f:int";
253 return;
254 };
255 """)
256 void test9() {
257 X.s_f += 1;
258 }
259
260 @Reflect
261 @IR("""
262 func @"test10" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
263 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
264 %2 : java.type:"int" = constant @1;
265 %3 : java.type:"int" = add %1 %2;
266 field.store %0 %3 @java.ref:"FieldAccessTest::f:int";
267 field.store %3 @java.ref:"FieldAccessTest::s_f:int";
268 return;
269 };
270 """)
271 void test10() {
272 s_f = f += 1;
273 }
274
275 @Reflect
276 @IR("""
277 func @"test11" (%0 : java.type:"FieldAccessTest", %1 : java.type:"FieldAccessTest$A")java.type:"void" -> {
278 %2 : Var<java.type:"FieldAccessTest$A"> = var %1 @"a";
279 %3 : java.type:"FieldAccessTest$A" = var.load %2;
280 %4 : java.type:"FieldAccessTest$B" = field.load %3 @java.ref:"FieldAccessTest$A::b:FieldAccessTest$B";
281 %5 : java.type:"FieldAccessTest$C" = field.load %4 @java.ref:"FieldAccessTest$B::c:FieldAccessTest$C";
282 %6 : java.type:"int" = field.load %5 @java.ref:"FieldAccessTest$C::f:int";
283 %7 : java.type:"int" = constant @1;
284 %8 : java.type:"int" = add %6 %7;
285 field.store %5 %8 @java.ref:"FieldAccessTest$C::f:int";
286 return;
287 };
288 """)
289 void test11(A a) {
290 a.b.c.f += 1;
291 }
292
293 @Reflect
294 @IR("""
295 func @"test12" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
296 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
297 %2 : java.type:"int" = constant @1;
298 %3 : java.type:"int" = add %1 %2;
299 field.store %0 %3 @java.ref:"FieldAccessTest::f:int";
300 %4 : Var<java.type:"int"> = var %1 @"x";
301 %5 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
302 %6 : java.type:"int" = constant @1;
303 %7 : java.type:"int" = sub %5 %6;
304 field.store %0 %7 @java.ref:"FieldAccessTest::f:int";
305 %8 : Var<java.type:"int"> = var %5 @"y";
306 return;
307 };
308 """)
309 void test12() {
310 int x = f++;
311 int y = f--;
312 }
313
314 @Reflect
315 @IR("""
316 func @"test13" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
317 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
318 %2 : java.type:"int" = constant @1;
319 %3 : java.type:"int" = add %1 %2;
320 field.store %0 %3 @java.ref:"FieldAccessTest::f:int";
321 %4 : Var<java.type:"int"> = var %1 @"x";
322 %5 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
323 %6 : java.type:"int" = constant @1;
324 %7 : java.type:"int" = sub %5 %6;
325 field.store %0 %7 @java.ref:"FieldAccessTest::f:int";
326 %8 : Var<java.type:"int"> = var %5 @"y";
327 return;
328 };
329 """)
330 void test13() {
331 int x = this.f++;
332 int y = this.f--;
333 }
334
335 @Reflect
336 @IR("""
337 func @"test14" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
338 %1 : java.type:"int" = field.load @java.ref:"FieldAccessTest::s_f:int";
339 %2 : java.type:"int" = constant @1;
340 %3 : java.type:"int" = add %1 %2;
341 field.store %3 @java.ref:"FieldAccessTest::s_f:int";
342 %4 : Var<java.type:"int"> = var %1 @"x";
343 %5 : java.type:"int" = field.load @java.ref:"FieldAccessTest::s_f:int";
344 %6 : java.type:"int" = constant @1;
345 %7 : java.type:"int" = sub %5 %6;
346 field.store %7 @java.ref:"FieldAccessTest::s_f:int";
347 %8 : Var<java.type:"int"> = var %5 @"y";
348 return;
349 };
350 """)
351 void test14() {
352 int x = s_f++;
353 int y = s_f--;
354 }
355
356 @Reflect
357 @IR("""
358 func @"test15" (%0 : java.type:"FieldAccessTest", %1 : java.type:"FieldAccessTest$X")java.type:"void" -> {
359 %2 : Var<java.type:"FieldAccessTest$X"> = var %1 @"h";
360 %3 : java.type:"FieldAccessTest$X" = var.load %2;
361 %4 : java.type:"int" = field.load %3 @java.ref:"FieldAccessTest$X::f:int";
362 %5 : java.type:"int" = constant @1;
363 %6 : java.type:"int" = add %4 %5;
364 field.store %3 %6 @java.ref:"FieldAccessTest$X::f:int";
365 %7 : Var<java.type:"int"> = var %4 @"x";
366 %8 : java.type:"FieldAccessTest$X" = var.load %2;
367 %9 : java.type:"int" = field.load %8 @java.ref:"FieldAccessTest$X::f:int";
368 %10 : java.type:"int" = constant @1;
369 %11 : java.type:"int" = sub %9 %10;
370 field.store %8 %11 @java.ref:"FieldAccessTest$X::f:int";
371 %12 : Var<java.type:"int"> = var %9 @"y";
372 return;
373 };
374 """)
375 void test15(X h) {
376 int x = h.f++;
377 int y = h.f--;
378 }
379
380
381
382
383 @Reflect
384 @IR("""
385 func @"test16" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
386 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
387 %2 : java.type:"int" = constant @1;
388 %3 : java.type:"int" = add %1 %2;
389 field.store %0 %3 @java.ref:"FieldAccessTest::f:int";
390 %4 : Var<java.type:"int"> = var %3 @"x";
391 %5 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
392 %6 : java.type:"int" = constant @1;
393 %7 : java.type:"int" = sub %5 %6;
394 field.store %0 %7 @java.ref:"FieldAccessTest::f:int";
395 %8 : Var<java.type:"int"> = var %7 @"y";
396 return;
397 };
398 """)
399 void test16() {
400 int x = ++f;
401 int y = --f;
402 }
403
404 @Reflect
405 @IR("""
406 func @"test17" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
407 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
408 %2 : java.type:"int" = constant @1;
409 %3 : java.type:"int" = add %1 %2;
410 field.store %0 %3 @java.ref:"FieldAccessTest::f:int";
411 %4 : Var<java.type:"int"> = var %3 @"x";
412 %5 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest::f:int";
413 %6 : java.type:"int" = constant @1;
414 %7 : java.type:"int" = sub %5 %6;
415 field.store %0 %7 @java.ref:"FieldAccessTest::f:int";
416 %8 : Var<java.type:"int"> = var %7 @"y";
417 return;
418 };
419 """)
420 void test17() {
421 int x = ++this.f;
422 int y = --this.f;
423 }
424
425 @Reflect
426 @IR("""
427 func @"test18" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
428 %1 : java.type:"int" = field.load @java.ref:"FieldAccessTest::s_f:int";
429 %2 : java.type:"int" = constant @1;
430 %3 : java.type:"int" = add %1 %2;
431 field.store %3 @java.ref:"FieldAccessTest::s_f:int";
432 %4 : Var<java.type:"int"> = var %3 @"x";
433 %5 : java.type:"int" = field.load @java.ref:"FieldAccessTest::s_f:int";
434 %6 : java.type:"int" = constant @1;
435 %7 : java.type:"int" = sub %5 %6;
436 field.store %7 @java.ref:"FieldAccessTest::s_f:int";
437 %8 : Var<java.type:"int"> = var %7 @"y";
438 return;
439 };
440 """)
441 void test18() {
442 int x = ++s_f;
443 int y = --s_f;
444 }
445
446 @Reflect
447 @IR("""
448 func @"test19" (%0 : java.type:"FieldAccessTest", %1 : java.type:"FieldAccessTest$X")java.type:"void" -> {
449 %2 : Var<java.type:"FieldAccessTest$X"> = var %1 @"h";
450 %3 : java.type:"FieldAccessTest$X" = var.load %2;
451 %4 : java.type:"int" = field.load %3 @java.ref:"FieldAccessTest$X::f:int";
452 %5 : java.type:"int" = constant @1;
453 %6 : java.type:"int" = add %4 %5;
454 field.store %3 %6 @java.ref:"FieldAccessTest$X::f:int";
455 %7 : Var<java.type:"int"> = var %6 @"x";
456 %8 : java.type:"FieldAccessTest$X" = var.load %2;
457 %9 : java.type:"int" = field.load %8 @java.ref:"FieldAccessTest$X::f:int";
458 %10 : java.type:"int" = constant @1;
459 %11 : java.type:"int" = sub %9 %10;
460 field.store %8 %11 @java.ref:"FieldAccessTest$X::f:int";
461 %12 : Var<java.type:"int"> = var %11 @"y";
462 return;
463 };
464 """)
465 void test19(X h) {
466 int x = ++h.f;
467 int y = --h.f;
468 }
469
470 static class Y extends X {
471 int yf;
472 static int s_yf;
473
474 @Reflect
475 @IR("""
476 func @"test" (%0 : java.type:"FieldAccessTest$Y")java.type:"void" -> {
477 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest$Y::f:int";
478 %2 : Var<java.type:"int"> = var %1 @"x";
479 %3 : java.type:"int" = field.load @java.ref:"FieldAccessTest$Y::s_f:int";
480 var.store %2 %3;
481 return;
482 };
483 """)
484 void test() {
485 int x = f;
486 x = s_f;
487 }
488
489 @Reflect
490 @IR("""
491 func @"test2" (%0 : java.type:"FieldAccessTest$Y")java.type:"void" -> {
492 %1 : java.type:"int" = constant @1;
493 field.store %0 %1 @java.ref:"FieldAccessTest$Y::f:int";
494 %2 : java.type:"int" = constant @1;
495 field.store %2 @java.ref:"FieldAccessTest$Y::s_f:int";
496 return;
497 };
498 """)
499 void test2() {
500 f = 1;
501 s_f = 1;
502 }
503
504 @Reflect
505 @IR("""
506 func @"test3" (%0 : java.type:"FieldAccessTest$Y")java.type:"void" -> {
507 %1 : java.type:"int" = field.load %0 @java.ref:"FieldAccessTest$Y::f:int";
508 %2 : java.type:"int" = constant @1;
509 %3 : java.type:"int" = add %1 %2;
510 field.store %0 %3 @java.ref:"FieldAccessTest$Y::f:int";
511 %4 : java.type:"int" = field.load @java.ref:"FieldAccessTest$Y::s_f:int";
512 %5 : java.type:"int" = constant @1;
513 %6 : java.type:"int" = add %4 %5;
514 field.store %6 @java.ref:"FieldAccessTest$Y::s_f:int";
515 return;
516 };
517 """)
518 void test3() {
519 f++;
520 s_f++;
521 }
522 }
523
524 static class Z<T extends X> {
525 T x;
526 }
527
528 static class ZZ extends Z<Y> {
529
530 @IR("""
531 func @"test1" (%0 : java.type:"FieldAccessTest$ZZ")java.type:"int" -> {
532 %1 : java.type:"FieldAccessTest$Y" = field.load %0 @java.ref:"FieldAccessTest$ZZ::x:FieldAccessTest$X";
533 %2 : java.type:"FieldAccessTest$Y" = cast %1 @java.type:"FieldAccessTest$Y";
534 %3 : java.type:"int" = field.load %2 @java.ref:"FieldAccessTest$Y::yf:int";
535 return %3;
536 };
537 """)
538 @Reflect
539 int test1() {
540 return x.yf;
541 }
542
543 @IR("""
544 func @"test2" (%0 : java.type:"FieldAccessTest$ZZ")java.type:"int" -> {
545 %1 : Var<java.type:"FieldAccessTest$ZZ"> = var %0 @"zz";
546 %2 : java.type:"FieldAccessTest$ZZ" = var.load %1;
547 %3 : java.type:"FieldAccessTest$Y" = field.load %2 @java.ref:"FieldAccessTest$ZZ::x:FieldAccessTest$X";
548 %4 : java.type:"FieldAccessTest$Y" = cast %3 @java.type:"FieldAccessTest$Y";
549 %5 : java.type:"int" = field.load %4 @java.ref:"FieldAccessTest$Y::yf:int";
550 return %5;
551 };
552 """)
553 @Reflect
554 static int test2(ZZ zz) {
555 return zz.x.yf;
556 }
557 }
558
559 static class W<T extends Number> {
560 T n;
561 }
562
563 static class WW extends W<Integer> {
564
565 @IR("""
566 func @"test1" (%0 : java.type:"FieldAccessTest$WW")java.type:"int" -> {
567 %1 : java.type:"java.lang.Integer" = field.load %0 @java.ref:"FieldAccessTest$WW::n:java.lang.Number";
568 %2 : java.type:"int" = invoke %1 @java.ref:"java.lang.Integer::intValue():int";
569 %3 : java.type:"int" = constant @1;
570 %4 : java.type:"int" = add %2 %3;
571 %5 : java.type:"java.lang.Integer" = invoke %4 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
572 field.store %0 %5 @java.ref:"FieldAccessTest$WW::n:java.lang.Number";
573 %6 : java.type:"int" = constant @0;
574 %7 : java.type:"java.lang.Integer" = invoke %6 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
575 %8 : java.type:"int" = invoke %1 %7 @java.ref:"java.lang.Integer::compareTo(java.lang.Integer):int";
576 return %8;
577 };
578 """)
579 @Reflect
580 int test1() {
581 return (n++).compareTo(0);
582 }
583
584 @IR("""
585 func @"test2" (%0 : java.type:"FieldAccessTest$WW")java.type:"int" -> {
586 %1 : Var<java.type:"FieldAccessTest$WW"> = var %0 @"w";
587 %2 : java.type:"FieldAccessTest$WW" = var.load %1;
588 %3 : java.type:"java.lang.Integer" = field.load %2 @java.ref:"FieldAccessTest$WW::n:java.lang.Number";
589 %4 : java.type:"int" = invoke %3 @java.ref:"java.lang.Integer::intValue():int";
590 %5 : java.type:"int" = constant @1;
591 %6 : java.type:"int" = add %4 %5;
592 %7 : java.type:"java.lang.Integer" = invoke %6 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
593 field.store %2 %7 @java.ref:"FieldAccessTest$WW::n:java.lang.Number";
594 %8 : java.type:"int" = constant @0;
595 %9 : java.type:"java.lang.Integer" = invoke %8 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
596 %10 : java.type:"int" = invoke %3 %9 @java.ref:"java.lang.Integer::compareTo(java.lang.Integer):int";
597 return %10;
598 };
599 """)
600 @Reflect
601 static int test2(WW w) {
602 return (w.n++).compareTo(0);
603 }
604 }
605
606 @Reflect
607 @IR("""
608 func @"test20" (%0 : java.type:"FieldAccessTest", %1 : java.type:"FieldAccessTest$Y")java.type:"void" -> {
609 %2 : Var<java.type:"FieldAccessTest$Y"> = var %1 @"y";
610 %3 : java.type:"FieldAccessTest$Y" = var.load %2;
611 %4 : java.type:"int" = field.load %3 @java.ref:"FieldAccessTest$Y::f:int";
612 %5 : Var<java.type:"int"> = var %4 @"x";
613 %6 : java.type:"FieldAccessTest$Y" = var.load %2;
614 %7 : java.type:"int" = field.load %6 @java.ref:"FieldAccessTest$Y::yf:int";
615 var.store %5 %7;
616 %8 : java.type:"FieldAccessTest$Y" = var.load %2;
617 %9 : java.type:"int" = field.load @java.ref:"FieldAccessTest$Y::s_yf:int";
618 var.store %5 %9;
619 %10 : java.type:"int" = field.load @java.ref:"FieldAccessTest$Y::s_yf:int";
620 var.store %5 %10;
621 %11 : java.type:"FieldAccessTest$Y" = var.load %2;
622 %12 : java.type:"int" = field.load @java.ref:"FieldAccessTest$Y::s_f:int";
623 var.store %5 %12;
624 %13 : java.type:"int" = field.load @java.ref:"FieldAccessTest$Y::s_f:int";
625 var.store %5 %13;
626 return;
627 };
628 """)
629 void test20(Y y) {
630 int x = y.f;
631 x = y.yf;
632 x = y.s_yf;
633 x = Y.s_yf;
634 x = y.s_f;
635 x = Y.s_f;
636 }
637
638 @Reflect
639 @IR("""
640 func @"test21" (%0 : java.type:"FieldAccessTest", %1 : java.type:"FieldAccessTest$Y")java.type:"void" -> {
641 %2 : Var<java.type:"FieldAccessTest$Y"> = var %1 @"y";
642 %3 : java.type:"FieldAccessTest$Y" = var.load %2;
643 %4 : java.type:"int" = constant @1;
644 field.store %3 %4 @java.ref:"FieldAccessTest$Y::f:int";
645 %5 : java.type:"FieldAccessTest$Y" = var.load %2;
646 %6 : java.type:"int" = constant @1;
647 field.store %5 %6 @java.ref:"FieldAccessTest$Y::yf:int";
648 %7 : java.type:"FieldAccessTest$Y" = var.load %2;
649 %8 : java.type:"int" = constant @1;
650 field.store %8 @java.ref:"FieldAccessTest$Y::s_yf:int";
651 %9 : java.type:"int" = constant @1;
652 field.store %9 @java.ref:"FieldAccessTest$Y::s_yf:int";
653 %10 : java.type:"FieldAccessTest$Y" = var.load %2;
654 %11 : java.type:"int" = constant @1;
655 field.store %11 @java.ref:"FieldAccessTest$Y::s_f:int";
656 %12 : java.type:"int" = constant @1;
657 field.store %12 @java.ref:"FieldAccessTest$Y::s_f:int";
658 return;
659 };
660 """)
661 void test21(Y y) {
662 y.f = 1;
663 y.yf = 1;
664 y.s_yf = 1;
665 Y.s_yf = 1;
666 y.s_f = 1;
667 Y.s_f = 1;
668 }
669
670 @Reflect
671 @IR("""
672 func @"test22" (%0 : java.type:"FieldAccessTest", %1 : java.type:"FieldAccessTest$Y")java.type:"void" -> {
673 %2 : Var<java.type:"FieldAccessTest$Y"> = var %1 @"y";
674 %3 : java.type:"FieldAccessTest$Y" = var.load %2;
675 %4 : java.type:"int" = field.load %3 @java.ref:"FieldAccessTest$Y::f:int";
676 %5 : java.type:"int" = constant @1;
677 %6 : java.type:"int" = add %4 %5;
678 field.store %3 %6 @java.ref:"FieldAccessTest$Y::f:int";
679 %7 : java.type:"FieldAccessTest$Y" = var.load %2;
680 %8 : java.type:"int" = field.load %7 @java.ref:"FieldAccessTest$Y::yf:int";
681 %9 : java.type:"int" = constant @1;
682 %10 : java.type:"int" = add %8 %9;
683 field.store %7 %10 @java.ref:"FieldAccessTest$Y::yf:int";
684 %11 : java.type:"FieldAccessTest$Y" = var.load %2;
685 %12 : java.type:"int" = field.load @java.ref:"FieldAccessTest$Y::s_yf:int";
686 %13 : java.type:"int" = constant @1;
687 %14 : java.type:"int" = add %12 %13;
688 field.store %14 @java.ref:"FieldAccessTest$Y::s_yf:int";
689 %15 : java.type:"int" = field.load @java.ref:"FieldAccessTest$Y::s_yf:int";
690 %16 : java.type:"int" = constant @1;
691 %17 : java.type:"int" = add %15 %16;
692 field.store %17 @java.ref:"FieldAccessTest$Y::s_yf:int";
693 %18 : java.type:"FieldAccessTest$Y" = var.load %2;
694 %19 : java.type:"int" = field.load @java.ref:"FieldAccessTest$Y::s_f:int";
695 %20 : java.type:"int" = constant @1;
696 %21 : java.type:"int" = add %19 %20;
697 field.store %21 @java.ref:"FieldAccessTest$Y::s_f:int";
698 %22 : java.type:"int" = field.load @java.ref:"FieldAccessTest$Y::s_f:int";
699 %23 : java.type:"int" = constant @1;
700 %24 : java.type:"int" = add %22 %23;
701 field.store %24 @java.ref:"FieldAccessTest$Y::s_f:int";
702 return;
703 };
704 """)
705 void test22(Y y) {
706 y.f++;
707 y.yf++;
708 y.s_yf++;
709 Y.s_yf++;
710 y.s_f++;
711 Y.s_f++;
712 }
713
714 // @@@ Should propagate as constant value?
715 @Reflect
716 @IR("""
717 func @"test23" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
718 %1 : java.type:"int" = field.load @java.ref:"java.util.Spliterator$OfInt::CONCURRENT:int";
719 %2 : Var<java.type:"int"> = var %1 @"x";
720 %3 : java.type:"int" = field.load @java.ref:"java.util.Spliterator$OfInt::CONCURRENT:int";
721 var.store %2 %3;
722 %4 : java.type:"int" = field.load @java.ref:"java.util.Spliterator$OfInt::CONCURRENT:int";
723 var.store %2 %4;
724 return;
725 };
726 """)
727 void test23() {
728 int x = Spliterator.OfInt.CONCURRENT;
729 x = OfInt.CONCURRENT;
730 x = CONCURRENT;
731 }
732
733 @Reflect
734 @IR("""
735 func @"test24" (%0 : java.type:"FieldAccessTest")java.type:"void" -> {
736 %1 : java.type:"java.io.PrintStream" = field.load @java.ref:"java.lang.System::out:java.io.PrintStream";
737 %2 : Var<java.type:"java.io.PrintStream"> = var %1 @"ps";
738 return;
739 };
740 """)
741 void test24() {
742 PrintStream ps = out;
743 }
744
745 static class Box<T> {
746 public T v;
747
748 public Box(T v) {
749 this.v = v;
750 }
751 }
752
753 @Reflect
754 @IR("""
755 func @"test25" ()java.type:"void" -> {
756 %0 : java.type:"java.lang.String" = constant @"abc";
757 %1 : java.type:"FieldAccessTest$Box<java.lang.String>" = new %0 @java.ref:"FieldAccessTest$Box::(java.lang.Object)";
758 %2 : Var<java.type:"FieldAccessTest$Box<java.lang.String>"> = var %1 @"b";
759 %3 : java.type:"FieldAccessTest$Box<java.lang.String>" = var.load %2;
760 %4 : java.type:"java.lang.String" = field.load %3 @java.ref:"FieldAccessTest$Box::v:java.lang.Object";
761 %5 : java.type:"java.lang.String" = cast %4 @java.type:"java.lang.String";
762 %6 : Var<java.type:"java.lang.String"> = var %5 @"s";
763 return;
764 };
765 """)
766 static void test25() {
767 Box<String> b = new Box<>("abc");
768 String s = b.v;
769 }
770
771 //@@@ unqualified access to field of generic type needs to be tested
772 // waiting for a new way of modeling types, so that type variables are captured in the IR
773 }