1 /* 2 * Copyright (c) 2024, 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.CodeReflection; 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 @CodeReflection 46 @IR(""" 47 func @"test1" (%0 : FieldAccessTest)void -> { 48 %1 : int = constant @"1"; 49 field.store %1 @"FieldAccessTest::s_f()int"; 50 %2 : int = constant @"1"; 51 field.store %0 %2 @"FieldAccessTest::f()int"; 52 return; 53 }; 54 """) 55 void test1() { 56 s_f = 1; 57 f = 1; 58 } 59 60 @CodeReflection 61 @IR(""" 62 func @"test1_1" (%0 : FieldAccessTest)void -> { 63 %1 : int = field.load %0 @"FieldAccessTest::f()int"; 64 %2 : int = constant @"1"; 65 %3 : int = add %1 %2; 66 field.store %0 %3 @"FieldAccessTest::f()int"; 67 %4 : int = field.load @"FieldAccessTest::s_f()int"; 68 %5 : int = constant @"1"; 69 %6 : int = add %4 %5; 70 field.store %6 @"FieldAccessTest::s_f()int"; 71 return; 72 }; 73 """) 74 void test1_1() { 75 f += 1; 76 s_f += 1; 77 } 78 79 @CodeReflection 80 @IR(""" 81 func @"test2" (%0 : FieldAccessTest)void -> { 82 %1 : int = constant @"1"; 83 field.store %0 %1 @"FieldAccessTest::f()int"; 84 field.store %1 @"FieldAccessTest::s_f()int"; 85 return; 86 }; 87 """) 88 void test2() { 89 s_f = f = 1; 90 } 91 92 @CodeReflection 93 @IR(""" 94 func @"test2_1" (%0 : FieldAccessTest)void -> { 95 %1 : int = constant @"1"; 96 field.store %0 %1 @"FieldAccessTest::f()int"; 97 return; 98 }; 99 """) 100 void test2_1() { 101 this.f = 1; 102 } 103 104 @CodeReflection 105 @IR(""" 106 func @"test2_2" (%0 : FieldAccessTest)int -> { 107 %1 : int = field.load %0 @"FieldAccessTest::f()int"; 108 return %1; 109 }; 110 """) 111 int test2_2() { 112 return this.f; 113 } 114 115 @CodeReflection 116 @IR(""" 117 func @"test2_3" (%0 : FieldAccessTest)void -> { 118 %1 : int = constant @"1"; 119 field.store %0 %1 @"FieldAccessTest::f()int"; 120 return; 121 }; 122 """) 123 void test2_3() { 124 FieldAccessTest.this.f = 1; 125 } 126 127 @CodeReflection 128 @IR(""" 129 func @"test2_4" (%0 : FieldAccessTest)int -> { 130 %1 : int = field.load %0 @"FieldAccessTest::f()int"; 131 return %1; 132 }; 133 """) 134 int test2_4() { 135 return FieldAccessTest.this.f; 136 } 137 138 @CodeReflection 139 @IR(""" 140 func @"test3" (%0 : FieldAccessTest)int -> { 141 %1 : int = field.load @"FieldAccessTest::s_f()int"; 142 %2 : int = field.load %0 @"FieldAccessTest::f()int"; 143 %3 : 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 @CodeReflection 164 @IR(""" 165 func @"test4" (%0 : FieldAccessTest, %1 : FieldAccessTest$A)void -> { 166 %2 : Var<FieldAccessTest$A> = var %1 @"a"; 167 %3 : FieldAccessTest$A = var.load %2; 168 %4 : FieldAccessTest$B = field.load %3 @"FieldAccessTest$A::b()FieldAccessTest$B"; 169 %5 : FieldAccessTest$C = field.load %4 @"FieldAccessTest$B::c()FieldAccessTest$C"; 170 %6 : int = constant @"1"; 171 field.store %5 %6 @"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 @CodeReflection 185 @IR(""" 186 func @"test5" (%0 : FieldAccessTest)int -> { 187 %1 : int = field.load @"FieldAccessTest$X::s_f()int"; 188 return %1; 189 }; 190 """) 191 int test5() { 192 return X.s_f; 193 } 194 195 @CodeReflection 196 @IR(""" 197 func @"test6" (%0 : FieldAccessTest)void -> { 198 %1 : int = constant @"1"; 199 field.store %1 @"FieldAccessTest$X::s_f()int"; 200 return; 201 }; 202 """) 203 void test6() { 204 X.s_f = 1; 205 } 206 207 208 @CodeReflection 209 @IR(""" 210 func @"test7" (%0 : FieldAccessTest)void -> { 211 %1 : int = field.load %0 @"FieldAccessTest::f()int"; 212 %2 : int = constant @"1"; 213 %3 : int = add %1 %2; 214 field.store %0 %3 @"FieldAccessTest::f()int"; 215 %4 : int = field.load @"FieldAccessTest::s_f()int"; 216 %5 : int = constant @"1"; 217 %6 : int = add %4 %5; 218 field.store %6 @"FieldAccessTest::s_f()int"; 219 return; 220 }; 221 """) 222 void test7() { 223 f += 1; 224 s_f += 1; 225 } 226 227 @CodeReflection 228 @IR(""" 229 func @"test8" (%0 : FieldAccessTest)void -> { 230 %1 : int = field.load %0 @"FieldAccessTest::f()int"; 231 %2 : int = constant @"1"; 232 %3 : int = add %1 %2; 233 field.store %0 %3 @"FieldAccessTest::f()int"; 234 %4 : int = field.load @"FieldAccessTest::s_f()int"; 235 %5 : int = constant @"1"; 236 %6 : int = add %4 %5; 237 field.store %6 @"FieldAccessTest::s_f()int"; 238 return; 239 }; 240 """) 241 void test8() { 242 this.f += 1; 243 this.s_f += 1; 244 } 245 246 @CodeReflection 247 @IR(""" 248 func @"test9" (%0 : FieldAccessTest)void -> { 249 %1 : int = field.load @"FieldAccessTest$X::s_f()int"; 250 %2 : int = constant @"1"; 251 %3 : int = add %1 %2; 252 field.store %3 @"FieldAccessTest$X::s_f()int"; 253 return; 254 }; 255 """) 256 void test9() { 257 X.s_f += 1; 258 } 259 260 @CodeReflection 261 @IR(""" 262 func @"test10" (%0 : FieldAccessTest)void -> { 263 %1 : int = field.load %0 @"FieldAccessTest::f()int"; 264 %2 : int = constant @"1"; 265 %3 : int = add %1 %2; 266 field.store %0 %3 @"FieldAccessTest::f()int"; 267 field.store %3 @"FieldAccessTest::s_f()int"; 268 return; 269 }; 270 """) 271 void test10() { 272 s_f = f += 1; 273 } 274 275 @CodeReflection 276 @IR(""" 277 func @"test11" (%0 : FieldAccessTest, %1 : FieldAccessTest$A)void -> { 278 %2 : Var<FieldAccessTest$A> = var %1 @"a"; 279 %3 : FieldAccessTest$A = var.load %2; 280 %4 : FieldAccessTest$B = field.load %3 @"FieldAccessTest$A::b()FieldAccessTest$B"; 281 %5 : FieldAccessTest$C = field.load %4 @"FieldAccessTest$B::c()FieldAccessTest$C"; 282 %6 : int = field.load %5 @"FieldAccessTest$C::f()int"; 283 %7 : int = constant @"1"; 284 %8 : int = add %6 %7; 285 field.store %5 %8 @"FieldAccessTest$C::f()int"; 286 return; 287 }; 288 """) 289 void test11(A a) { 290 a.b.c.f += 1; 291 } 292 293 @CodeReflection 294 @IR(""" 295 func @"test12" (%0 : FieldAccessTest)void -> { 296 %1 : int = field.load %0 @"FieldAccessTest::f()int"; 297 %2 : int = constant @"1"; 298 %3 : int = add %1 %2; 299 field.store %0 %3 @"FieldAccessTest::f()int"; 300 %4 : Var<int> = var %1 @"x"; 301 %5 : int = field.load %0 @"FieldAccessTest::f()int"; 302 %6 : int = constant @"1"; 303 %7 : int = sub %5 %6; 304 field.store %0 %7 @"FieldAccessTest::f()int"; 305 %8 : Var<int> = var %5 @"y"; 306 return; 307 }; 308 """) 309 void test12() { 310 int x = f++; 311 int y = f--; 312 } 313 314 @CodeReflection 315 @IR(""" 316 func @"test13" (%0 : FieldAccessTest)void -> { 317 %1 : int = field.load %0 @"FieldAccessTest::f()int"; 318 %2 : int = constant @"1"; 319 %3 : int = add %1 %2; 320 field.store %0 %3 @"FieldAccessTest::f()int"; 321 %4 : Var<int> = var %1 @"x"; 322 %5 : int = field.load %0 @"FieldAccessTest::f()int"; 323 %6 : int = constant @"1"; 324 %7 : int = sub %5 %6; 325 field.store %0 %7 @"FieldAccessTest::f()int"; 326 %8 : Var<int> = var %5 @"y"; 327 return; 328 }; 329 """) 330 void test13() { 331 int x = this.f++; 332 int y = this.f--; 333 } 334 335 @CodeReflection 336 @IR(""" 337 func @"test14" (%0 : FieldAccessTest)void -> { 338 %1 : int = field.load @"FieldAccessTest::s_f()int"; 339 %2 : int = constant @"1"; 340 %3 : int = add %1 %2; 341 field.store %3 @"FieldAccessTest::s_f()int"; 342 %4 : Var<int> = var %1 @"x"; 343 %5 : int = field.load @"FieldAccessTest::s_f()int"; 344 %6 : int = constant @"1"; 345 %7 : int = sub %5 %6; 346 field.store %7 @"FieldAccessTest::s_f()int"; 347 %8 : Var<int> = var %5 @"y"; 348 return; 349 }; 350 """) 351 void test14() { 352 int x = s_f++; 353 int y = s_f--; 354 } 355 356 @CodeReflection 357 @IR(""" 358 func @"test15" (%0 : FieldAccessTest, %1 : FieldAccessTest$X)void -> { 359 %2 : Var<FieldAccessTest$X> = var %1 @"h"; 360 %3 : FieldAccessTest$X = var.load %2; 361 %4 : int = field.load %3 @"FieldAccessTest$X::f()int"; 362 %5 : int = constant @"1"; 363 %6 : int = add %4 %5; 364 field.store %3 %6 @"FieldAccessTest$X::f()int"; 365 %7 : Var<int> = var %4 @"x"; 366 %8 : FieldAccessTest$X = var.load %2; 367 %9 : int = field.load %8 @"FieldAccessTest$X::f()int"; 368 %10 : int = constant @"1"; 369 %11 : int = sub %9 %10; 370 field.store %8 %11 @"FieldAccessTest$X::f()int"; 371 %12 : Var<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 @CodeReflection 384 @IR(""" 385 func @"test16" (%0 : FieldAccessTest)void -> { 386 %1 : int = field.load %0 @"FieldAccessTest::f()int"; 387 %2 : int = constant @"1"; 388 %3 : int = add %1 %2; 389 field.store %0 %3 @"FieldAccessTest::f()int"; 390 %4 : Var<int> = var %3 @"x"; 391 %5 : int = field.load %0 @"FieldAccessTest::f()int"; 392 %6 : int = constant @"1"; 393 %7 : int = sub %5 %6; 394 field.store %0 %7 @"FieldAccessTest::f()int"; 395 %8 : Var<int> = var %7 @"y"; 396 return; 397 }; 398 """) 399 void test16() { 400 int x = ++f; 401 int y = --f; 402 } 403 404 @CodeReflection 405 @IR(""" 406 func @"test17" (%0 : FieldAccessTest)void -> { 407 %1 : int = field.load %0 @"FieldAccessTest::f()int"; 408 %2 : int = constant @"1"; 409 %3 : int = add %1 %2; 410 field.store %0 %3 @"FieldAccessTest::f()int"; 411 %4 : Var<int> = var %3 @"x"; 412 %5 : int = field.load %0 @"FieldAccessTest::f()int"; 413 %6 : int = constant @"1"; 414 %7 : int = sub %5 %6; 415 field.store %0 %7 @"FieldAccessTest::f()int"; 416 %8 : Var<int> = var %7 @"y"; 417 return; 418 }; 419 """) 420 void test17() { 421 int x = ++this.f; 422 int y = --this.f; 423 } 424 425 @CodeReflection 426 @IR(""" 427 func @"test18" (%0 : FieldAccessTest)void -> { 428 %1 : int = field.load @"FieldAccessTest::s_f()int"; 429 %2 : int = constant @"1"; 430 %3 : int = add %1 %2; 431 field.store %3 @"FieldAccessTest::s_f()int"; 432 %4 : Var<int> = var %3 @"x"; 433 %5 : int = field.load @"FieldAccessTest::s_f()int"; 434 %6 : int = constant @"1"; 435 %7 : int = sub %5 %6; 436 field.store %7 @"FieldAccessTest::s_f()int"; 437 %8 : Var<int> = var %7 @"y"; 438 return; 439 }; 440 """) 441 void test18() { 442 int x = ++s_f; 443 int y = --s_f; 444 } 445 446 @CodeReflection 447 @IR(""" 448 func @"test19" (%0 : FieldAccessTest, %1 : FieldAccessTest$X)void -> { 449 %2 : Var<FieldAccessTest$X> = var %1 @"h"; 450 %3 : FieldAccessTest$X = var.load %2; 451 %4 : int = field.load %3 @"FieldAccessTest$X::f()int"; 452 %5 : int = constant @"1"; 453 %6 : int = add %4 %5; 454 field.store %3 %6 @"FieldAccessTest$X::f()int"; 455 %7 : Var<int> = var %6 @"x"; 456 %8 : FieldAccessTest$X = var.load %2; 457 %9 : int = field.load %8 @"FieldAccessTest$X::f()int"; 458 %10 : int = constant @"1"; 459 %11 : int = sub %9 %10; 460 field.store %8 %11 @"FieldAccessTest$X::f()int"; 461 %12 : Var<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 @CodeReflection 475 @IR(""" 476 func @"test" (%0 : FieldAccessTest$Y)void -> { 477 %1 : int = field.load %0 @"FieldAccessTest$Y::f()int"; 478 %2 : Var<int> = var %1 @"x"; 479 %3 : int = field.load @"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 @CodeReflection 490 @IR(""" 491 func @"test2" (%0 : FieldAccessTest$Y)void -> { 492 %1 : int = constant @"1"; 493 field.store %0 %1 @"FieldAccessTest$Y::f()int"; 494 %2 : int = constant @"1"; 495 field.store %2 @"FieldAccessTest$Y::s_f()int"; 496 return; 497 }; 498 """) 499 void test2() { 500 f = 1; 501 s_f = 1; 502 } 503 504 @CodeReflection 505 @IR(""" 506 func @"test3" (%0 : FieldAccessTest$Y)void -> { 507 %1 : int = field.load %0 @"FieldAccessTest$Y::f()int"; 508 %2 : int = constant @"1"; 509 %3 : int = add %1 %2; 510 field.store %0 %3 @"FieldAccessTest$Y::f()int"; 511 %4 : int = field.load @"FieldAccessTest$Y::s_f()int"; 512 %5 : int = constant @"1"; 513 %6 : int = add %4 %5; 514 field.store %6 @"FieldAccessTest$Y::s_f()int"; 515 return; 516 }; 517 """) 518 void test3() { 519 f++; 520 s_f++; 521 } 522 } 523 524 @CodeReflection 525 @IR(""" 526 func @"test20" (%0 : FieldAccessTest, %1 : FieldAccessTest$Y)void -> { 527 %2 : Var<FieldAccessTest$Y> = var %1 @"y"; 528 %3 : FieldAccessTest$Y = var.load %2; 529 %4 : int = field.load %3 @"FieldAccessTest$Y::f()int"; 530 %5 : Var<int> = var %4 @"x"; 531 %6 : FieldAccessTest$Y = var.load %2; 532 %7 : int = field.load %6 @"FieldAccessTest$Y::yf()int"; 533 var.store %5 %7; 534 %8 : FieldAccessTest$Y = var.load %2; 535 %9 : int = field.load @"FieldAccessTest$Y::s_yf()int"; 536 var.store %5 %9; 537 %10 : int = field.load @"FieldAccessTest$Y::s_yf()int"; 538 var.store %5 %10; 539 %11 : FieldAccessTest$Y = var.load %2; 540 %12 : int = field.load @"FieldAccessTest$Y::s_f()int"; 541 var.store %5 %12; 542 %13 : int = field.load @"FieldAccessTest$Y::s_f()int"; 543 var.store %5 %13; 544 return; 545 }; 546 """) 547 void test20(Y y) { 548 int x = y.f; 549 x = y.yf; 550 x = y.s_yf; 551 x = Y.s_yf; 552 x = y.s_f; 553 x = Y.s_f; 554 } 555 556 @CodeReflection 557 @IR(""" 558 func @"test21" (%0 : FieldAccessTest, %1 : FieldAccessTest$Y)void -> { 559 %2 : Var<FieldAccessTest$Y> = var %1 @"y"; 560 %3 : FieldAccessTest$Y = var.load %2; 561 %4 : int = constant @"1"; 562 field.store %3 %4 @"FieldAccessTest$Y::f()int"; 563 %5 : FieldAccessTest$Y = var.load %2; 564 %6 : int = constant @"1"; 565 field.store %5 %6 @"FieldAccessTest$Y::yf()int"; 566 %7 : FieldAccessTest$Y = var.load %2; 567 %8 : int = constant @"1"; 568 field.store %8 @"FieldAccessTest$Y::s_yf()int"; 569 %9 : int = constant @"1"; 570 field.store %9 @"FieldAccessTest$Y::s_yf()int"; 571 %10 : FieldAccessTest$Y = var.load %2; 572 %11 : int = constant @"1"; 573 field.store %11 @"FieldAccessTest$Y::s_f()int"; 574 %12 : int = constant @"1"; 575 field.store %12 @"FieldAccessTest$Y::s_f()int"; 576 return; 577 }; 578 """) 579 void test21(Y y) { 580 y.f = 1; 581 y.yf = 1; 582 y.s_yf = 1; 583 Y.s_yf = 1; 584 y.s_f = 1; 585 Y.s_f = 1; 586 } 587 588 @CodeReflection 589 @IR(""" 590 func @"test22" (%0 : FieldAccessTest, %1 : FieldAccessTest$Y)void -> { 591 %2 : Var<FieldAccessTest$Y> = var %1 @"y"; 592 %3 : FieldAccessTest$Y = var.load %2; 593 %4 : int = field.load %3 @"FieldAccessTest$Y::f()int"; 594 %5 : int = constant @"1"; 595 %6 : int = add %4 %5; 596 field.store %3 %6 @"FieldAccessTest$Y::f()int"; 597 %7 : FieldAccessTest$Y = var.load %2; 598 %8 : int = field.load %7 @"FieldAccessTest$Y::yf()int"; 599 %9 : int = constant @"1"; 600 %10 : int = add %8 %9; 601 field.store %7 %10 @"FieldAccessTest$Y::yf()int"; 602 %11 : FieldAccessTest$Y = var.load %2; 603 %12 : int = field.load @"FieldAccessTest$Y::s_yf()int"; 604 %13 : int = constant @"1"; 605 %14 : int = add %12 %13; 606 field.store %14 @"FieldAccessTest$Y::s_yf()int"; 607 %15 : int = field.load @"FieldAccessTest$Y::s_yf()int"; 608 %16 : int = constant @"1"; 609 %17 : int = add %15 %16; 610 field.store %17 @"FieldAccessTest$Y::s_yf()int"; 611 %18 : FieldAccessTest$Y = var.load %2; 612 %19 : int = field.load @"FieldAccessTest$Y::s_f()int"; 613 %20 : int = constant @"1"; 614 %21 : int = add %19 %20; 615 field.store %21 @"FieldAccessTest$Y::s_f()int"; 616 %22 : int = field.load @"FieldAccessTest$Y::s_f()int"; 617 %23 : int = constant @"1"; 618 %24 : int = add %22 %23; 619 field.store %24 @"FieldAccessTest$Y::s_f()int"; 620 return; 621 }; 622 """) 623 void test22(Y y) { 624 y.f++; 625 y.yf++; 626 y.s_yf++; 627 Y.s_yf++; 628 y.s_f++; 629 Y.s_f++; 630 } 631 632 // @@@ Should propagate as constant value? 633 @CodeReflection 634 @IR(""" 635 func @"test23" (%0 : FieldAccessTest)void -> { 636 %1 : int = field.load @"java.util.Spliterator$OfInt::CONCURRENT()int"; 637 %2 : Var<int> = var %1 @"x"; 638 %3 : int = field.load @"java.util.Spliterator$OfInt::CONCURRENT()int"; 639 var.store %2 %3; 640 %4 : int = field.load @"java.util.Spliterator$OfInt::CONCURRENT()int"; 641 var.store %2 %4; 642 return; 643 }; 644 """) 645 void test23() { 646 int x = Spliterator.OfInt.CONCURRENT; 647 x = OfInt.CONCURRENT; 648 x = CONCURRENT; 649 } 650 651 @CodeReflection 652 @IR(""" 653 func @"test24" (%0 : FieldAccessTest)void -> { 654 %1 : java.io.PrintStream = field.load @"java.lang.System::out()java.io.PrintStream"; 655 %2 : Var<java.io.PrintStream> = var %1 @"ps"; 656 return; 657 }; 658 """) 659 void test24() { 660 PrintStream ps = out; 661 } 662 663 static class Box<T> { 664 public T v; 665 666 public Box(T v) { 667 this.v = v; 668 } 669 } 670 671 @CodeReflection 672 @IR(""" 673 func @"test25" ()void -> { 674 %0 : java.lang.String = constant @"abc"; 675 %1 : FieldAccessTest$Box<java.lang.String> = new %0 @"func<FieldAccessTest$Box, java.lang.Object>"; 676 %2 : Var<FieldAccessTest$Box<java.lang.String>> = var %1 @"b"; 677 %3 : FieldAccessTest$Box<java.lang.String> = var.load %2; 678 %4 : java.lang.String = field.load %3 @"FieldAccessTest$Box::v()java.lang.Object"; 679 %5 : Var<java.lang.String> = var %4 @"s"; 680 return; 681 }; 682 """) 683 static void test25() { 684 Box<String> b = new Box<>("abc"); 685 String s = b.v; 686 } 687 688 //@@@ unqualified access to field of generic type needs to be tested 689 // waiting for a new way of modeling types, so that type variables are captured in the IR 690 }