1 /*
   2  * Copyright (c) 2015, 2016 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 /*
  25  * @test
  26  * @bug 8156486
  27  * @run testng/othervm VarHandleTestMethodTypeString
  28  * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeString
  29  */
  30 
  31 import org.testng.annotations.BeforeClass;
  32 import org.testng.annotations.DataProvider;
  33 import org.testng.annotations.Test;
  34 
  35 import java.lang.invoke.MethodHandles;
  36 import java.lang.invoke.VarHandle;
  37 import java.util.ArrayList;
  38 import java.util.Arrays;
  39 import java.util.List;
  40 
  41 import static org.testng.Assert.*;
  42 
  43 import static java.lang.invoke.MethodType.*;
  44 
  45 public class VarHandleTestMethodTypeString extends VarHandleBaseTest {
  46     static final String static_final_v = "foo";
  47 
  48     static String static_v = "foo";
  49 
  50     final String final_v = "foo";
  51 
  52     String v = "foo";
  53 
  54     VarHandle vhFinalField;
  55 
  56     VarHandle vhField;
  57 
  58     VarHandle vhStaticField;
  59 
  60     VarHandle vhStaticFinalField;
  61 
  62     VarHandle vhArray;
  63 
  64     @BeforeClass
  65     public void setup() throws Exception {
  66         vhFinalField = MethodHandles.lookup().findVarHandle(
  67                 VarHandleTestMethodTypeString.class, "final_v", String.class);
  68 
  69         vhField = MethodHandles.lookup().findVarHandle(
  70                 VarHandleTestMethodTypeString.class, "v", String.class);
  71 
  72         vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
  73             VarHandleTestMethodTypeString.class, "static_final_v", String.class);
  74 
  75         vhStaticField = MethodHandles.lookup().findStaticVarHandle(
  76             VarHandleTestMethodTypeString.class, "static_v", String.class);
  77 
  78         vhArray = MethodHandles.arrayElementVarHandle(String[].class);
  79     }
  80 
  81     @DataProvider
  82     public Object[][] accessTestCaseProvider() throws Exception {
  83         List<AccessTestCase<?>> cases = new ArrayList<>();
  84 
  85         cases.add(new VarHandleAccessTestCase("Instance field",
  86                                               vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
  87                                               false));
  88 
  89         cases.add(new VarHandleAccessTestCase("Static field",
  90                                               vhStaticField, VarHandleTestMethodTypeString::testStaticFieldWrongMethodType,
  91                                               false));
  92 
  93         cases.add(new VarHandleAccessTestCase("Array",
  94                                               vhArray, VarHandleTestMethodTypeString::testArrayWrongMethodType,
  95                                               false));
  96 
  97         for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
  98             cases.add(new MethodHandleAccessTestCase("Instance field",
  99                                                      vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
 100                                                      false));
 101 
 102             cases.add(new MethodHandleAccessTestCase("Static field",
 103                                                      vhStaticField, f, VarHandleTestMethodTypeString::testStaticFieldWrongMethodType,
 104                                                      false));
 105 
 106             cases.add(new MethodHandleAccessTestCase("Array",
 107                                                      vhArray, f, VarHandleTestMethodTypeString::testArrayWrongMethodType,
 108                                                      false));
 109         }
 110         // Work around issue with jtreg summary reporting which truncates
 111         // the String result of Object.toString to 30 characters, hence
 112         // the first dummy argument
 113         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
 114     }
 115 
 116     @Test(dataProvider = "accessTestCaseProvider")
 117     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
 118         T t = atc.get();
 119         int iters = atc.requiresLoop() ? ITERS : 1;
 120         for (int c = 0; c < iters; c++) {
 121             atc.testAccess(t);
 122         }
 123     }
 124 
 125 
 126     static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeString recv, VarHandle vh) throws Throwable {
 127         // Get
 128         // Incorrect argument types
 129         checkNPE(() -> { // null receiver
 130             String x = (String) vh.get(null);
 131         });
 132         checkCCE(() -> { // receiver reference class
 133             String x = (String) vh.get(Void.class);
 134         });
 135         checkWMTE(() -> { // receiver primitive class
 136             String x = (String) vh.get(0);
 137         });
 138         // Incorrect return type
 139         checkCCE(() -> { // reference class
 140             Void x = (Void) vh.get(recv);
 141         });
 142         checkWMTE(() -> { // primitive class
 143             boolean x = (boolean) vh.get(recv);
 144         });
 145         // Incorrect arity
 146         checkWMTE(() -> { // 0
 147             String x = (String) vh.get();
 148         });
 149         checkWMTE(() -> { // >
 150             String x = (String) vh.get(recv, Void.class);
 151         });
 152 
 153 
 154         // Set
 155         // Incorrect argument types
 156         checkNPE(() -> { // null receiver
 157             vh.set(null, "foo");
 158         });
 159         checkCCE(() -> { // receiver reference class
 160             vh.set(Void.class, "foo");
 161         });
 162         checkCCE(() -> { // value reference class
 163             vh.set(recv, Void.class);
 164         });
 165         checkWMTE(() -> { // receiver primitive class
 166             vh.set(0, "foo");
 167         });
 168         // Incorrect arity
 169         checkWMTE(() -> { // 0
 170             vh.set();
 171         });
 172         checkWMTE(() -> { // >
 173             vh.set(recv, "foo", Void.class);
 174         });
 175 
 176 
 177         // GetVolatile
 178         // Incorrect argument types
 179         checkNPE(() -> { // null receiver
 180             String x = (String) vh.getVolatile(null);
 181         });
 182         checkCCE(() -> { // receiver reference class
 183             String x = (String) vh.getVolatile(Void.class);
 184         });
 185         checkWMTE(() -> { // receiver primitive class
 186             String x = (String) vh.getVolatile(0);
 187         });
 188         // Incorrect return type
 189         checkCCE(() -> { // reference class
 190             Void x = (Void) vh.getVolatile(recv);
 191         });
 192         checkWMTE(() -> { // primitive class
 193             boolean x = (boolean) vh.getVolatile(recv);
 194         });
 195         // Incorrect arity
 196         checkWMTE(() -> { // 0
 197             String x = (String) vh.getVolatile();
 198         });
 199         checkWMTE(() -> { // >
 200             String x = (String) vh.getVolatile(recv, Void.class);
 201         });
 202 
 203 
 204         // SetVolatile
 205         // Incorrect argument types
 206         checkNPE(() -> { // null receiver
 207             vh.setVolatile(null, "foo");
 208         });
 209         checkCCE(() -> { // receiver reference class
 210             vh.setVolatile(Void.class, "foo");
 211         });
 212         checkCCE(() -> { // value reference class
 213             vh.setVolatile(recv, Void.class);
 214         });
 215         checkWMTE(() -> { // receiver primitive class
 216             vh.setVolatile(0, "foo");
 217         });
 218         // Incorrect arity
 219         checkWMTE(() -> { // 0
 220             vh.setVolatile();
 221         });
 222         checkWMTE(() -> { // >
 223             vh.setVolatile(recv, "foo", Void.class);
 224         });
 225 
 226 
 227         // GetOpaque
 228         // Incorrect argument types
 229         checkNPE(() -> { // null receiver
 230             String x = (String) vh.getOpaque(null);
 231         });
 232         checkCCE(() -> { // receiver reference class
 233             String x = (String) vh.getOpaque(Void.class);
 234         });
 235         checkWMTE(() -> { // receiver primitive class
 236             String x = (String) vh.getOpaque(0);
 237         });
 238         // Incorrect return type
 239         checkCCE(() -> { // reference class
 240             Void x = (Void) vh.getOpaque(recv);
 241         });
 242         checkWMTE(() -> { // primitive class
 243             boolean x = (boolean) vh.getOpaque(recv);
 244         });
 245         // Incorrect arity
 246         checkWMTE(() -> { // 0
 247             String x = (String) vh.getOpaque();
 248         });
 249         checkWMTE(() -> { // >
 250             String x = (String) vh.getOpaque(recv, Void.class);
 251         });
 252 
 253 
 254         // SetOpaque
 255         // Incorrect argument types
 256         checkNPE(() -> { // null receiver
 257             vh.setOpaque(null, "foo");
 258         });
 259         checkCCE(() -> { // receiver reference class
 260             vh.setOpaque(Void.class, "foo");
 261         });
 262         checkCCE(() -> { // value reference class
 263             vh.setOpaque(recv, Void.class);
 264         });
 265         checkWMTE(() -> { // receiver primitive class
 266             vh.setOpaque(0, "foo");
 267         });
 268         // Incorrect arity
 269         checkWMTE(() -> { // 0
 270             vh.setOpaque();
 271         });
 272         checkWMTE(() -> { // >
 273             vh.setOpaque(recv, "foo", Void.class);
 274         });
 275 
 276 
 277         // GetAcquire
 278         // Incorrect argument types
 279         checkNPE(() -> { // null receiver
 280             String x = (String) vh.getAcquire(null);
 281         });
 282         checkCCE(() -> { // receiver reference class
 283             String x = (String) vh.getAcquire(Void.class);
 284         });
 285         checkWMTE(() -> { // receiver primitive class
 286             String x = (String) vh.getAcquire(0);
 287         });
 288         // Incorrect return type
 289         checkCCE(() -> { // reference class
 290             Void x = (Void) vh.getAcquire(recv);
 291         });
 292         checkWMTE(() -> { // primitive class
 293             boolean x = (boolean) vh.getAcquire(recv);
 294         });
 295         // Incorrect arity
 296         checkWMTE(() -> { // 0
 297             String x = (String) vh.getAcquire();
 298         });
 299         checkWMTE(() -> { // >
 300             String x = (String) vh.getAcquire(recv, Void.class);
 301         });
 302 
 303 
 304         // SetRelease
 305         // Incorrect argument types
 306         checkNPE(() -> { // null receiver
 307             vh.setRelease(null, "foo");
 308         });
 309         checkCCE(() -> { // receiver reference class
 310             vh.setRelease(Void.class, "foo");
 311         });
 312         checkCCE(() -> { // value reference class
 313             vh.setRelease(recv, Void.class);
 314         });
 315         checkWMTE(() -> { // receiver primitive class
 316             vh.setRelease(0, "foo");
 317         });
 318         // Incorrect arity
 319         checkWMTE(() -> { // 0
 320             vh.setRelease();
 321         });
 322         checkWMTE(() -> { // >
 323             vh.setRelease(recv, "foo", Void.class);
 324         });
 325 
 326 
 327         // CompareAndSet
 328         // Incorrect argument types
 329         checkNPE(() -> { // null receiver
 330             boolean r = vh.compareAndSet(null, "foo", "foo");
 331         });
 332         checkCCE(() -> { // receiver reference class
 333             boolean r = vh.compareAndSet(Void.class, "foo", "foo");
 334         });
 335         checkCCE(() -> { // expected reference class
 336             boolean r = vh.compareAndSet(recv, Void.class, "foo");
 337         });
 338         checkCCE(() -> { // actual reference class
 339             boolean r = vh.compareAndSet(recv, "foo", Void.class);
 340         });
 341         checkWMTE(() -> { // receiver primitive class
 342             boolean r = vh.compareAndSet(0, "foo", "foo");
 343         });
 344         // Incorrect arity
 345         checkWMTE(() -> { // 0
 346             boolean r = vh.compareAndSet();
 347         });
 348         checkWMTE(() -> { // >
 349             boolean r = vh.compareAndSet(recv, "foo", "foo", Void.class);
 350         });
 351 
 352 
 353         // WeakCompareAndSet
 354         // Incorrect argument types
 355         checkNPE(() -> { // null receiver
 356             boolean r = vh.weakCompareAndSet(null, "foo", "foo");
 357         });
 358         checkCCE(() -> { // receiver reference class
 359             boolean r = vh.weakCompareAndSet(Void.class, "foo", "foo");
 360         });
 361         checkCCE(() -> { // expected reference class
 362             boolean r = vh.weakCompareAndSet(recv, Void.class, "foo");
 363         });
 364         checkCCE(() -> { // actual reference class
 365             boolean r = vh.weakCompareAndSet(recv, "foo", Void.class);
 366         });
 367         checkWMTE(() -> { // receiver primitive class
 368             boolean r = vh.weakCompareAndSet(0, "foo", "foo");
 369         });
 370         // Incorrect arity
 371         checkWMTE(() -> { // 0
 372             boolean r = vh.weakCompareAndSet();
 373         });
 374         checkWMTE(() -> { // >
 375             boolean r = vh.weakCompareAndSet(recv, "foo", "foo", Void.class);
 376         });
 377 
 378 
 379         // WeakCompareAndSetVolatile
 380         // Incorrect argument types
 381         checkNPE(() -> { // null receiver
 382             boolean r = vh.weakCompareAndSetVolatile(null, "foo", "foo");
 383         });
 384         checkCCE(() -> { // receiver reference class
 385             boolean r = vh.weakCompareAndSetVolatile(Void.class, "foo", "foo");
 386         });
 387         checkCCE(() -> { // expected reference class
 388             boolean r = vh.weakCompareAndSetVolatile(recv, Void.class, "foo");
 389         });
 390         checkCCE(() -> { // actual reference class
 391             boolean r = vh.weakCompareAndSetVolatile(recv, "foo", Void.class);
 392         });
 393         checkWMTE(() -> { // receiver primitive class
 394             boolean r = vh.weakCompareAndSetVolatile(0, "foo", "foo");
 395         });
 396         // Incorrect arity
 397         checkWMTE(() -> { // 0
 398             boolean r = vh.weakCompareAndSetVolatile();
 399         });
 400         checkWMTE(() -> { // >
 401             boolean r = vh.weakCompareAndSetVolatile(recv, "foo", "foo", Void.class);
 402         });
 403 
 404 
 405         // WeakCompareAndSetAcquire
 406         // Incorrect argument types
 407         checkNPE(() -> { // null receiver
 408             boolean r = vh.weakCompareAndSetAcquire(null, "foo", "foo");
 409         });
 410         checkCCE(() -> { // receiver reference class
 411             boolean r = vh.weakCompareAndSetAcquire(Void.class, "foo", "foo");
 412         });
 413         checkCCE(() -> { // expected reference class
 414             boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, "foo");
 415         });
 416         checkCCE(() -> { // actual reference class
 417             boolean r = vh.weakCompareAndSetAcquire(recv, "foo", Void.class);
 418         });
 419         checkWMTE(() -> { // receiver primitive class
 420             boolean r = vh.weakCompareAndSetAcquire(0, "foo", "foo");
 421         });
 422         // Incorrect arity
 423         checkWMTE(() -> { // 0
 424             boolean r = vh.weakCompareAndSetAcquire();
 425         });
 426         checkWMTE(() -> { // >
 427             boolean r = vh.weakCompareAndSetAcquire(recv, "foo", "foo", Void.class);
 428         });
 429 
 430 
 431         // WeakCompareAndSetRelease
 432         // Incorrect argument types
 433         checkNPE(() -> { // null receiver
 434             boolean r = vh.weakCompareAndSetRelease(null, "foo", "foo");
 435         });
 436         checkCCE(() -> { // receiver reference class
 437             boolean r = vh.weakCompareAndSetRelease(Void.class, "foo", "foo");
 438         });
 439         checkCCE(() -> { // expected reference class
 440             boolean r = vh.weakCompareAndSetRelease(recv, Void.class, "foo");
 441         });
 442         checkCCE(() -> { // actual reference class
 443             boolean r = vh.weakCompareAndSetRelease(recv, "foo", Void.class);
 444         });
 445         checkWMTE(() -> { // receiver primitive class
 446             boolean r = vh.weakCompareAndSetRelease(0, "foo", "foo");
 447         });
 448         // Incorrect arity
 449         checkWMTE(() -> { // 0
 450             boolean r = vh.weakCompareAndSetRelease();
 451         });
 452         checkWMTE(() -> { // >
 453             boolean r = vh.weakCompareAndSetRelease(recv, "foo", "foo", Void.class);
 454         });
 455 
 456 
 457         // CompareAndExchange
 458         // Incorrect argument types
 459         checkNPE(() -> { // null receiver
 460             String x = (String) vh.compareAndExchange(null, "foo", "foo");
 461         });
 462         checkCCE(() -> { // receiver reference class
 463             String x = (String) vh.compareAndExchange(Void.class, "foo", "foo");
 464         });
 465         checkCCE(() -> { // expected reference class
 466             String x = (String) vh.compareAndExchange(recv, Void.class, "foo");
 467         });
 468         checkCCE(() -> { // actual reference class
 469             String x = (String) vh.compareAndExchange(recv, "foo", Void.class);
 470         });
 471         checkWMTE(() -> { // reciever primitive class
 472             String x = (String) vh.compareAndExchange(0, "foo", "foo");
 473         });
 474         // Incorrect return type
 475         checkCCE(() -> { // reference class
 476             Void r = (Void) vh.compareAndExchange(recv, "foo", "foo");
 477         });
 478         checkWMTE(() -> { // primitive class
 479             boolean x = (boolean) vh.compareAndExchange(recv, "foo", "foo");
 480         });
 481         // Incorrect arity
 482         checkWMTE(() -> { // 0
 483             String x = (String) vh.compareAndExchange();
 484         });
 485         checkWMTE(() -> { // >
 486             String x = (String) vh.compareAndExchange(recv, "foo", "foo", Void.class);
 487         });
 488 
 489 
 490         // CompareAndExchangeAcquire
 491         // Incorrect argument types
 492         checkNPE(() -> { // null receiver
 493             String x = (String) vh.compareAndExchangeAcquire(null, "foo", "foo");
 494         });
 495         checkCCE(() -> { // receiver reference class
 496             String x = (String) vh.compareAndExchangeAcquire(Void.class, "foo", "foo");
 497         });
 498         checkCCE(() -> { // expected reference class
 499             String x = (String) vh.compareAndExchangeAcquire(recv, Void.class, "foo");
 500         });
 501         checkCCE(() -> { // actual reference class
 502             String x = (String) vh.compareAndExchangeAcquire(recv, "foo", Void.class);
 503         });
 504         checkWMTE(() -> { // reciever primitive class
 505             String x = (String) vh.compareAndExchangeAcquire(0, "foo", "foo");
 506         });
 507         // Incorrect return type
 508         checkCCE(() -> { // reference class
 509             Void r = (Void) vh.compareAndExchangeAcquire(recv, "foo", "foo");
 510         });
 511         checkWMTE(() -> { // primitive class
 512             boolean x = (boolean) vh.compareAndExchangeAcquire(recv, "foo", "foo");
 513         });
 514         // Incorrect arity
 515         checkWMTE(() -> { // 0
 516             String x = (String) vh.compareAndExchangeAcquire();
 517         });
 518         checkWMTE(() -> { // >
 519             String x = (String) vh.compareAndExchangeAcquire(recv, "foo", "foo", Void.class);
 520         });
 521 
 522 
 523         // CompareAndExchangeRelease
 524         // Incorrect argument types
 525         checkNPE(() -> { // null receiver
 526             String x = (String) vh.compareAndExchangeRelease(null, "foo", "foo");
 527         });
 528         checkCCE(() -> { // receiver reference class
 529             String x = (String) vh.compareAndExchangeRelease(Void.class, "foo", "foo");
 530         });
 531         checkCCE(() -> { // expected reference class
 532             String x = (String) vh.compareAndExchangeRelease(recv, Void.class, "foo");
 533         });
 534         checkCCE(() -> { // actual reference class
 535             String x = (String) vh.compareAndExchangeRelease(recv, "foo", Void.class);
 536         });
 537         checkWMTE(() -> { // reciever primitive class
 538             String x = (String) vh.compareAndExchangeRelease(0, "foo", "foo");
 539         });
 540         // Incorrect return type
 541         checkCCE(() -> { // reference class
 542             Void r = (Void) vh.compareAndExchangeRelease(recv, "foo", "foo");
 543         });
 544         checkWMTE(() -> { // primitive class
 545             boolean x = (boolean) vh.compareAndExchangeRelease(recv, "foo", "foo");
 546         });
 547         // Incorrect arity
 548         checkWMTE(() -> { // 0
 549             String x = (String) vh.compareAndExchangeRelease();
 550         });
 551         checkWMTE(() -> { // >
 552             String x = (String) vh.compareAndExchangeRelease(recv, "foo", "foo", Void.class);
 553         });
 554 
 555 
 556         // GetAndSet
 557         // Incorrect argument types
 558         checkNPE(() -> { // null receiver
 559             String x = (String) vh.getAndSet(null, "foo");
 560         });
 561         checkCCE(() -> { // receiver reference class
 562             String x = (String) vh.getAndSet(Void.class, "foo");
 563         });
 564         checkCCE(() -> { // value reference class
 565             String x = (String) vh.getAndSet(recv, Void.class);
 566         });
 567         checkWMTE(() -> { // reciever primitive class
 568             String x = (String) vh.getAndSet(0, "foo");
 569         });
 570         // Incorrect return type
 571         checkCCE(() -> { // reference class
 572             Void r = (Void) vh.getAndSet(recv, "foo");
 573         });
 574         checkWMTE(() -> { // primitive class
 575             boolean x = (boolean) vh.getAndSet(recv, "foo");
 576         });
 577         // Incorrect arity
 578         checkWMTE(() -> { // 0
 579             String x = (String) vh.getAndSet();
 580         });
 581         checkWMTE(() -> { // >
 582             String x = (String) vh.getAndSet(recv, "foo", Void.class);
 583         });
 584 
 585     }
 586 
 587     static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeString recv, Handles hs) throws Throwable {
 588         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
 589             // Incorrect argument types
 590             checkNPE(() -> { // null receiver
 591                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class)).
 592                     invokeExact((VarHandleTestMethodTypeString) null);
 593             });
 594             hs.checkWMTEOrCCE(() -> { // receiver reference class
 595                 String x = (String) hs.get(am, methodType(String.class, Class.class)).
 596                     invokeExact(Void.class);
 597             });
 598             checkWMTE(() -> { // receiver primitive class
 599                 String x = (String) hs.get(am, methodType(String.class, int.class)).
 600                     invokeExact(0);
 601             });
 602             // Incorrect return type
 603             hs.checkWMTEOrCCE(() -> { // reference class
 604                 Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class)).
 605                     invokeExact(recv);
 606             });
 607             checkWMTE(() -> { // primitive class
 608                 boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class)).
 609                     invokeExact(recv);
 610             });
 611             // Incorrect arity
 612             checkWMTE(() -> { // 0
 613                 String x = (String) hs.get(am, methodType(String.class)).
 614                     invokeExact();
 615             });
 616             checkWMTE(() -> { // >
 617                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)).
 618                     invokeExact(recv, Void.class);
 619             });
 620         }
 621 
 622         for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
 623             // Incorrect argument types
 624             checkNPE(() -> { // null receiver
 625                 hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, String.class)).
 626                     invokeExact((VarHandleTestMethodTypeString) null, "foo");
 627             });
 628             hs.checkWMTEOrCCE(() -> { // receiver reference class
 629                 hs.get(am, methodType(void.class, Class.class, String.class)).
 630                     invokeExact(Void.class, "foo");
 631             });
 632             hs.checkWMTEOrCCE(() -> { // value reference class
 633                 hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, Class.class)).
 634                     invokeExact(recv, Void.class);
 635             });
 636             checkWMTE(() -> { // receiver primitive class
 637                 hs.get(am, methodType(void.class, int.class, String.class)).
 638                     invokeExact(0, "foo");
 639             });
 640             // Incorrect arity
 641             checkWMTE(() -> { // 0
 642                 hs.get(am, methodType(void.class)).
 643                     invokeExact();
 644             });
 645             checkWMTE(() -> { // >
 646                 hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
 647                     invokeExact(recv, "foo", Void.class);
 648             });
 649         }
 650 
 651         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
 652             // Incorrect argument types
 653             checkNPE(() -> { // null receiver
 654                 boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, String.class)).
 655                     invokeExact((VarHandleTestMethodTypeString) null, "foo", "foo");
 656             });
 657             hs.checkWMTEOrCCE(() -> { // receiver reference class
 658                 boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class, String.class)).
 659                     invokeExact(Void.class, "foo", "foo");
 660             });
 661             hs.checkWMTEOrCCE(() -> { // expected reference class
 662                 boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, Class.class, String.class)).
 663                     invokeExact(recv, Void.class, "foo");
 664             });
 665             hs.checkWMTEOrCCE(() -> { // actual reference class
 666                 boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
 667                     invokeExact(recv, "foo", Void.class);
 668             });
 669             checkWMTE(() -> { // receiver primitive class
 670                 boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , String.class, String.class)).
 671                     invokeExact(0, "foo", "foo");
 672             });
 673             // Incorrect arity
 674             checkWMTE(() -> { // 0
 675                 boolean r = (boolean) hs.get(am, methodType(boolean.class)).
 676                     invokeExact();
 677             });
 678             checkWMTE(() -> { // >
 679                 boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)).
 680                     invokeExact(recv, "foo", "foo", Void.class);
 681             });
 682         }
 683 
 684         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
 685             checkNPE(() -> { // null receiver
 686                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, String.class)).
 687                     invokeExact((VarHandleTestMethodTypeString) null, "foo", "foo");
 688             });
 689             hs.checkWMTEOrCCE(() -> { // receiver reference class
 690                 String x = (String) hs.get(am, methodType(String.class, Class.class, String.class, String.class)).
 691                     invokeExact(Void.class, "foo", "foo");
 692             });
 693             hs.checkWMTEOrCCE(() -> { // expected reference class
 694                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class, String.class)).
 695                     invokeExact(recv, Void.class, "foo");
 696             });
 697             hs.checkWMTEOrCCE(() -> { // actual reference class
 698                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
 699                     invokeExact(recv, "foo", Void.class);
 700             });
 701             checkWMTE(() -> { // reciever primitive class
 702                 String x = (String) hs.get(am, methodType(String.class, int.class , String.class, String.class)).
 703                     invokeExact(0, "foo", "foo");
 704             });
 705             // Incorrect return type
 706             hs.checkWMTEOrCCE(() -> { // reference class
 707                 Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class , String.class, String.class)).
 708                     invokeExact(recv, "foo", "foo");
 709             });
 710             checkWMTE(() -> { // primitive class
 711                 boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class , String.class, String.class)).
 712                     invokeExact(recv, "foo", "foo");
 713             });
 714             // Incorrect arity
 715             checkWMTE(() -> { // 0
 716                 String x = (String) hs.get(am, methodType(String.class)).
 717                     invokeExact();
 718             });
 719             checkWMTE(() -> { // >
 720                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)).
 721                     invokeExact(recv, "foo", "foo", Void.class);
 722             });
 723         }
 724 
 725         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
 726             checkNPE(() -> { // null receiver
 727                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class)).
 728                     invokeExact((VarHandleTestMethodTypeString) null, "foo");
 729             });
 730             hs.checkWMTEOrCCE(() -> { // receiver reference class
 731                 String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)).
 732                     invokeExact(Void.class, "foo");
 733             });
 734             hs.checkWMTEOrCCE(() -> { // value reference class
 735                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)).
 736                     invokeExact(recv, Void.class);
 737             });
 738             checkWMTE(() -> { // reciever primitive class
 739                 String x = (String) hs.get(am, methodType(String.class, int.class, String.class)).
 740                     invokeExact(0, "foo");
 741             });
 742             // Incorrect return type
 743             hs.checkWMTEOrCCE(() -> { // reference class
 744                 Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class, String.class)).
 745                     invokeExact(recv, "foo");
 746             });
 747             checkWMTE(() -> { // primitive class
 748                 boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class)).
 749                     invokeExact(recv, "foo");
 750             });
 751             // Incorrect arity
 752             checkWMTE(() -> { // 0
 753                 String x = (String) hs.get(am, methodType(String.class)).
 754                     invokeExact();
 755             });
 756             checkWMTE(() -> { // >
 757                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class)).
 758                     invokeExact(recv, "foo", Void.class);
 759             });
 760         }
 761 
 762     }
 763 
 764 
 765     static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
 766         // Get
 767         // Incorrect return type
 768         checkCCE(() -> { // reference class
 769             Void x = (Void) vh.get();
 770         });
 771         checkWMTE(() -> { // primitive class
 772             boolean x = (boolean) vh.get();
 773         });
 774         // Incorrect arity
 775         checkWMTE(() -> { // >
 776             String x = (String) vh.get(Void.class);
 777         });
 778 
 779 
 780         // Set
 781         // Incorrect argument types
 782         checkCCE(() -> { // value reference class
 783             vh.set(Void.class);
 784         });
 785         // Incorrect arity
 786         checkWMTE(() -> { // 0
 787             vh.set();
 788         });
 789         checkWMTE(() -> { // >
 790             vh.set("foo", Void.class);
 791         });
 792 
 793 
 794         // GetVolatile
 795         // Incorrect return type
 796         checkCCE(() -> { // reference class
 797             Void x = (Void) vh.getVolatile();
 798         });
 799         checkWMTE(() -> { // primitive class
 800             boolean x = (boolean) vh.getVolatile();
 801         });
 802         checkWMTE(() -> { // >
 803             String x = (String) vh.getVolatile(Void.class);
 804         });
 805 
 806 
 807         // SetVolatile
 808         // Incorrect argument types
 809         checkCCE(() -> { // value reference class
 810             vh.setVolatile(Void.class);
 811         });
 812         // Incorrect arity
 813         checkWMTE(() -> { // 0
 814             vh.setVolatile();
 815         });
 816         checkWMTE(() -> { // >
 817             vh.setVolatile("foo", Void.class);
 818         });
 819 
 820 
 821         // GetOpaque
 822         // Incorrect return type
 823         checkCCE(() -> { // reference class
 824             Void x = (Void) vh.getOpaque();
 825         });
 826         checkWMTE(() -> { // primitive class
 827             boolean x = (boolean) vh.getOpaque();
 828         });
 829         checkWMTE(() -> { // >
 830             String x = (String) vh.getOpaque(Void.class);
 831         });
 832 
 833 
 834         // SetOpaque
 835         // Incorrect argument types
 836         checkCCE(() -> { // value reference class
 837             vh.setOpaque(Void.class);
 838         });
 839         // Incorrect arity
 840         checkWMTE(() -> { // 0
 841             vh.setOpaque();
 842         });
 843         checkWMTE(() -> { // >
 844             vh.setOpaque("foo", Void.class);
 845         });
 846 
 847 
 848         // GetAcquire
 849         // Incorrect return type
 850         checkCCE(() -> { // reference class
 851             Void x = (Void) vh.getAcquire();
 852         });
 853         checkWMTE(() -> { // primitive class
 854             boolean x = (boolean) vh.getAcquire();
 855         });
 856         checkWMTE(() -> { // >
 857             String x = (String) vh.getAcquire(Void.class);
 858         });
 859 
 860 
 861         // SetRelease
 862         // Incorrect argument types
 863         checkCCE(() -> { // value reference class
 864             vh.setRelease(Void.class);
 865         });
 866         // Incorrect arity
 867         checkWMTE(() -> { // 0
 868             vh.setRelease();
 869         });
 870         checkWMTE(() -> { // >
 871             vh.setRelease("foo", Void.class);
 872         });
 873 
 874 
 875         // CompareAndSet
 876         // Incorrect argument types
 877         checkCCE(() -> { // expected reference class
 878             boolean r = vh.compareAndSet(Void.class, "foo");
 879         });
 880         checkCCE(() -> { // actual reference class
 881             boolean r = vh.compareAndSet("foo", Void.class);
 882         });
 883         // Incorrect arity
 884         checkWMTE(() -> { // 0
 885             boolean r = vh.compareAndSet();
 886         });
 887         checkWMTE(() -> { // >
 888             boolean r = vh.compareAndSet("foo", "foo", Void.class);
 889         });
 890 
 891 
 892         // WeakCompareAndSet
 893         // Incorrect argument types
 894         checkCCE(() -> { // expected reference class
 895             boolean r = vh.weakCompareAndSet(Void.class, "foo");
 896         });
 897         checkCCE(() -> { // actual reference class
 898             boolean r = vh.weakCompareAndSet("foo", Void.class);
 899         });
 900         // Incorrect arity
 901         checkWMTE(() -> { // 0
 902             boolean r = vh.weakCompareAndSet();
 903         });
 904         checkWMTE(() -> { // >
 905             boolean r = vh.weakCompareAndSet("foo", "foo", Void.class);
 906         });
 907 
 908 
 909         // WeakCompareAndSetVolatile
 910         // Incorrect argument types
 911         checkCCE(() -> { // expected reference class
 912             boolean r = vh.weakCompareAndSetVolatile(Void.class, "foo");
 913         });
 914         checkCCE(() -> { // actual reference class
 915             boolean r = vh.weakCompareAndSetVolatile("foo", Void.class);
 916         });
 917         // Incorrect arity
 918         checkWMTE(() -> { // 0
 919             boolean r = vh.weakCompareAndSetVolatile();
 920         });
 921         checkWMTE(() -> { // >
 922             boolean r = vh.weakCompareAndSetVolatile("foo", "foo", Void.class);
 923         });
 924 
 925 
 926         // WeakCompareAndSetAcquire
 927         // Incorrect argument types
 928         checkCCE(() -> { // expected reference class
 929             boolean r = vh.weakCompareAndSetAcquire(Void.class, "foo");
 930         });
 931         checkCCE(() -> { // actual reference class
 932             boolean r = vh.weakCompareAndSetAcquire("foo", Void.class);
 933         });
 934         // Incorrect arity
 935         checkWMTE(() -> { // 0
 936             boolean r = vh.weakCompareAndSetAcquire();
 937         });
 938         checkWMTE(() -> { // >
 939             boolean r = vh.weakCompareAndSetAcquire("foo", "foo", Void.class);
 940         });
 941 
 942 
 943         // WeakCompareAndSetRelease
 944         // Incorrect argument types
 945         checkCCE(() -> { // expected reference class
 946             boolean r = vh.weakCompareAndSetRelease(Void.class, "foo");
 947         });
 948         checkCCE(() -> { // actual reference class
 949             boolean r = vh.weakCompareAndSetRelease("foo", Void.class);
 950         });
 951         // Incorrect arity
 952         checkWMTE(() -> { // 0
 953             boolean r = vh.weakCompareAndSetRelease();
 954         });
 955         checkWMTE(() -> { // >
 956             boolean r = vh.weakCompareAndSetRelease("foo", "foo", Void.class);
 957         });
 958 
 959 
 960         // CompareAndExchange
 961         // Incorrect argument types
 962         checkCCE(() -> { // expected reference class
 963             String x = (String) vh.compareAndExchange(Void.class, "foo");
 964         });
 965         checkCCE(() -> { // actual reference class
 966             String x = (String) vh.compareAndExchange("foo", Void.class);
 967         });
 968         // Incorrect return type
 969         checkCCE(() -> { // reference class
 970             Void r = (Void) vh.compareAndExchange("foo", "foo");
 971         });
 972         checkWMTE(() -> { // primitive class
 973             boolean x = (boolean) vh.compareAndExchange("foo", "foo");
 974         });
 975         // Incorrect arity
 976         checkWMTE(() -> { // 0
 977             String x = (String) vh.compareAndExchange();
 978         });
 979         checkWMTE(() -> { // >
 980             String x = (String) vh.compareAndExchange("foo", "foo", Void.class);
 981         });
 982 
 983 
 984         // CompareAndExchangeAcquire
 985         // Incorrect argument types
 986         checkCCE(() -> { // expected reference class
 987             String x = (String) vh.compareAndExchangeAcquire(Void.class, "foo");
 988         });
 989         checkCCE(() -> { // actual reference class
 990             String x = (String) vh.compareAndExchangeAcquire("foo", Void.class);
 991         });
 992         // Incorrect return type
 993         checkCCE(() -> { // reference class
 994             Void r = (Void) vh.compareAndExchangeAcquire("foo", "foo");
 995         });
 996         checkWMTE(() -> { // primitive class
 997             boolean x = (boolean) vh.compareAndExchangeAcquire("foo", "foo");
 998         });
 999         // Incorrect arity
1000         checkWMTE(() -> { // 0
1001             String x = (String) vh.compareAndExchangeAcquire();
1002         });
1003         checkWMTE(() -> { // >
1004             String x = (String) vh.compareAndExchangeAcquire("foo", "foo", Void.class);
1005         });
1006 
1007 
1008         // CompareAndExchangeRelease
1009         // Incorrect argument types
1010         checkCCE(() -> { // expected reference class
1011             String x = (String) vh.compareAndExchangeRelease(Void.class, "foo");
1012         });
1013         checkCCE(() -> { // actual reference class
1014             String x = (String) vh.compareAndExchangeRelease("foo", Void.class);
1015         });
1016         // Incorrect return type
1017         checkCCE(() -> { // reference class
1018             Void r = (Void) vh.compareAndExchangeRelease("foo", "foo");
1019         });
1020         checkWMTE(() -> { // primitive class
1021             boolean x = (boolean) vh.compareAndExchangeRelease("foo", "foo");
1022         });
1023         // Incorrect arity
1024         checkWMTE(() -> { // 0
1025             String x = (String) vh.compareAndExchangeRelease();
1026         });
1027         checkWMTE(() -> { // >
1028             String x = (String) vh.compareAndExchangeRelease("foo", "foo", Void.class);
1029         });
1030 
1031 
1032         // GetAndSet
1033         // Incorrect argument types
1034         checkCCE(() -> { // value reference class
1035             String x = (String) vh.getAndSet(Void.class);
1036         });
1037         // Incorrect return type
1038         checkCCE(() -> { // reference class
1039             Void r = (Void) vh.getAndSet("foo");
1040         });
1041         checkWMTE(() -> { // primitive class
1042             boolean x = (boolean) vh.getAndSet("foo");
1043         });
1044         // Incorrect arity
1045         checkWMTE(() -> { // 0
1046             String x = (String) vh.getAndSet();
1047         });
1048         checkWMTE(() -> { // >
1049             String x = (String) vh.getAndSet("foo", Void.class);
1050         });
1051 
1052     }
1053 
1054     static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
1055         int i = 0;
1056 
1057         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
1058             // Incorrect return type
1059             hs.checkWMTEOrCCE(() -> { // reference class
1060                 Void x = (Void) hs.get(am, methodType(Void.class)).
1061                     invokeExact();
1062             });
1063             checkWMTE(() -> { // primitive class
1064                 boolean x = (boolean) hs.get(am, methodType(boolean.class)).
1065                     invokeExact();
1066             });
1067             // Incorrect arity
1068             checkWMTE(() -> { // >
1069                 String x = (String) hs.get(am, methodType(Class.class)).
1070                     invokeExact(Void.class);
1071             });
1072         }
1073 
1074         for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
1075             hs.checkWMTEOrCCE(() -> { // value reference class
1076                 hs.get(am, methodType(void.class, Class.class)).
1077                     invokeExact(Void.class);
1078             });
1079             // Incorrect arity
1080             checkWMTE(() -> { // 0
1081                 hs.get(am, methodType(void.class)).
1082                     invokeExact();
1083             });
1084             checkWMTE(() -> { // >
1085                 hs.get(am, methodType(void.class, String.class, Class.class)).
1086                     invokeExact("foo", Void.class);
1087             });
1088         }
1089         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
1090             // Incorrect argument types
1091             hs.checkWMTEOrCCE(() -> { // expected reference class
1092                 boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class)).
1093                     invokeExact(Void.class, "foo");
1094             });
1095             hs.checkWMTEOrCCE(() -> { // actual reference class
1096                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, Class.class)).
1097                     invokeExact("foo", Void.class);
1098             });
1099             // Incorrect arity
1100             checkWMTE(() -> { // 0
1101                 boolean r = (boolean) hs.get(am, methodType(boolean.class)).
1102                     invokeExact();
1103             });
1104             checkWMTE(() -> { // >
1105                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class, Class.class)).
1106                     invokeExact("foo", "foo", Void.class);
1107             });
1108         }
1109 
1110         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
1111             // Incorrect argument types
1112             hs.checkWMTEOrCCE(() -> { // expected reference class
1113                 String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)).
1114                     invokeExact(Void.class, "foo");
1115             });
1116             hs.checkWMTEOrCCE(() -> { // actual reference class
1117                 String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)).
1118                     invokeExact("foo", Void.class);
1119             });
1120             // Incorrect return type
1121             hs.checkWMTEOrCCE(() -> { // reference class
1122                 Void r = (Void) hs.get(am, methodType(Void.class, String.class, String.class)).
1123                     invokeExact("foo", "foo");
1124             });
1125             checkWMTE(() -> { // primitive class
1126                 boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class)).
1127                     invokeExact("foo", "foo");
1128             });
1129             // Incorrect arity
1130             checkWMTE(() -> { // 0
1131                 String x = (String) hs.get(am, methodType(String.class)).
1132                     invokeExact();
1133             });
1134             checkWMTE(() -> { // >
1135                 String x = (String) hs.get(am, methodType(String.class, String.class, String.class, Class.class)).
1136                     invokeExact("foo", "foo", Void.class);
1137             });
1138         }
1139 
1140         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
1141             // Incorrect argument types
1142             hs.checkWMTEOrCCE(() -> { // value reference class
1143                 String x = (String) hs.get(am, methodType(String.class, Class.class)).
1144                     invokeExact(Void.class);
1145             });
1146             // Incorrect return type
1147             hs.checkWMTEOrCCE(() -> { // reference class
1148                 Void r = (Void) hs.get(am, methodType(Void.class, String.class)).
1149                     invokeExact("foo");
1150             });
1151             checkWMTE(() -> { // primitive class
1152                 boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class)).
1153                     invokeExact("foo");
1154             });
1155             // Incorrect arity
1156             checkWMTE(() -> { // 0
1157                 String x = (String) hs.get(am, methodType(String.class)).
1158                     invokeExact();
1159             });
1160             checkWMTE(() -> { // >
1161                 String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)).
1162                     invokeExact("foo", Void.class);
1163             });
1164         }
1165 
1166     }
1167 
1168 
1169     static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
1170         String[] array = new String[10];
1171         Arrays.fill(array, "foo");
1172 
1173         // Get
1174         // Incorrect argument types
1175         checkNPE(() -> { // null array
1176             String x = (String) vh.get(null, 0);
1177         });
1178         checkCCE(() -> { // array reference class
1179             String x = (String) vh.get(Void.class, 0);
1180         });
1181         checkWMTE(() -> { // array primitive class
1182             String x = (String) vh.get(0, 0);
1183         });
1184         checkWMTE(() -> { // index reference class
1185             String x = (String) vh.get(array, Void.class);
1186         });
1187         // Incorrect return type
1188         checkCCE(() -> { // reference class
1189             Void x = (Void) vh.get(array, 0);
1190         });
1191         checkWMTE(() -> { // primitive class
1192             boolean x = (boolean) vh.get(array, 0);
1193         });
1194         // Incorrect arity
1195         checkWMTE(() -> { // 0
1196             String x = (String) vh.get();
1197         });
1198         checkWMTE(() -> { // >
1199             String x = (String) vh.get(array, 0, Void.class);
1200         });
1201 
1202 
1203         // Set
1204         // Incorrect argument types
1205         checkNPE(() -> { // null array
1206             vh.set(null, 0, "foo");
1207         });
1208         checkCCE(() -> { // array reference class
1209             vh.set(Void.class, 0, "foo");
1210         });
1211         checkCCE(() -> { // value reference class
1212             vh.set(array, 0, Void.class);
1213         });
1214         checkWMTE(() -> { // receiver primitive class
1215             vh.set(0, 0, "foo");
1216         });
1217         checkWMTE(() -> { // index reference class
1218             vh.set(array, Void.class, "foo");
1219         });
1220         // Incorrect arity
1221         checkWMTE(() -> { // 0
1222             vh.set();
1223         });
1224         checkWMTE(() -> { // >
1225             vh.set(array, 0, "foo", Void.class);
1226         });
1227 
1228 
1229         // GetVolatile
1230         // Incorrect argument types
1231         checkNPE(() -> { // null array
1232             String x = (String) vh.getVolatile(null, 0);
1233         });
1234         checkCCE(() -> { // array reference class
1235             String x = (String) vh.getVolatile(Void.class, 0);
1236         });
1237         checkWMTE(() -> { // array primitive class
1238             String x = (String) vh.getVolatile(0, 0);
1239         });
1240         checkWMTE(() -> { // index reference class
1241             String x = (String) vh.getVolatile(array, Void.class);
1242         });
1243         // Incorrect return type
1244         checkCCE(() -> { // reference class
1245             Void x = (Void) vh.getVolatile(array, 0);
1246         });
1247         checkWMTE(() -> { // primitive class
1248             boolean x = (boolean) vh.getVolatile(array, 0);
1249         });
1250         // Incorrect arity
1251         checkWMTE(() -> { // 0
1252             String x = (String) vh.getVolatile();
1253         });
1254         checkWMTE(() -> { // >
1255             String x = (String) vh.getVolatile(array, 0, Void.class);
1256         });
1257 
1258 
1259         // SetVolatile
1260         // Incorrect argument types
1261         checkNPE(() -> { // null array
1262             vh.setVolatile(null, 0, "foo");
1263         });
1264         checkCCE(() -> { // array reference class
1265             vh.setVolatile(Void.class, 0, "foo");
1266         });
1267         checkCCE(() -> { // value reference class
1268             vh.setVolatile(array, 0, Void.class);
1269         });
1270         checkWMTE(() -> { // receiver primitive class
1271             vh.setVolatile(0, 0, "foo");
1272         });
1273         checkWMTE(() -> { // index reference class
1274             vh.setVolatile(array, Void.class, "foo");
1275         });
1276         // Incorrect arity
1277         checkWMTE(() -> { // 0
1278             vh.setVolatile();
1279         });
1280         checkWMTE(() -> { // >
1281             vh.setVolatile(array, 0, "foo", Void.class);
1282         });
1283 
1284 
1285         // GetOpaque
1286         // Incorrect argument types
1287         checkNPE(() -> { // null array
1288             String x = (String) vh.getOpaque(null, 0);
1289         });
1290         checkCCE(() -> { // array reference class
1291             String x = (String) vh.getOpaque(Void.class, 0);
1292         });
1293         checkWMTE(() -> { // array primitive class
1294             String x = (String) vh.getOpaque(0, 0);
1295         });
1296         checkWMTE(() -> { // index reference class
1297             String x = (String) vh.getOpaque(array, Void.class);
1298         });
1299         // Incorrect return type
1300         checkCCE(() -> { // reference class
1301             Void x = (Void) vh.getOpaque(array, 0);
1302         });
1303         checkWMTE(() -> { // primitive class
1304             boolean x = (boolean) vh.getOpaque(array, 0);
1305         });
1306         // Incorrect arity
1307         checkWMTE(() -> { // 0
1308             String x = (String) vh.getOpaque();
1309         });
1310         checkWMTE(() -> { // >
1311             String x = (String) vh.getOpaque(array, 0, Void.class);
1312         });
1313 
1314 
1315         // SetOpaque
1316         // Incorrect argument types
1317         checkNPE(() -> { // null array
1318             vh.setOpaque(null, 0, "foo");
1319         });
1320         checkCCE(() -> { // array reference class
1321             vh.setOpaque(Void.class, 0, "foo");
1322         });
1323         checkCCE(() -> { // value reference class
1324             vh.setOpaque(array, 0, Void.class);
1325         });
1326         checkWMTE(() -> { // receiver primitive class
1327             vh.setOpaque(0, 0, "foo");
1328         });
1329         checkWMTE(() -> { // index reference class
1330             vh.setOpaque(array, Void.class, "foo");
1331         });
1332         // Incorrect arity
1333         checkWMTE(() -> { // 0
1334             vh.setOpaque();
1335         });
1336         checkWMTE(() -> { // >
1337             vh.setOpaque(array, 0, "foo", Void.class);
1338         });
1339 
1340 
1341         // GetAcquire
1342         // Incorrect argument types
1343         checkNPE(() -> { // null array
1344             String x = (String) vh.getAcquire(null, 0);
1345         });
1346         checkCCE(() -> { // array reference class
1347             String x = (String) vh.getAcquire(Void.class, 0);
1348         });
1349         checkWMTE(() -> { // array primitive class
1350             String x = (String) vh.getAcquire(0, 0);
1351         });
1352         checkWMTE(() -> { // index reference class
1353             String x = (String) vh.getAcquire(array, Void.class);
1354         });
1355         // Incorrect return type
1356         checkCCE(() -> { // reference class
1357             Void x = (Void) vh.getAcquire(array, 0);
1358         });
1359         checkWMTE(() -> { // primitive class
1360             boolean x = (boolean) vh.getAcquire(array, 0);
1361         });
1362         // Incorrect arity
1363         checkWMTE(() -> { // 0
1364             String x = (String) vh.getAcquire();
1365         });
1366         checkWMTE(() -> { // >
1367             String x = (String) vh.getAcquire(array, 0, Void.class);
1368         });
1369 
1370 
1371         // SetRelease
1372         // Incorrect argument types
1373         checkNPE(() -> { // null array
1374             vh.setRelease(null, 0, "foo");
1375         });
1376         checkCCE(() -> { // array reference class
1377             vh.setRelease(Void.class, 0, "foo");
1378         });
1379         checkCCE(() -> { // value reference class
1380             vh.setRelease(array, 0, Void.class);
1381         });
1382         checkWMTE(() -> { // receiver primitive class
1383             vh.setRelease(0, 0, "foo");
1384         });
1385         checkWMTE(() -> { // index reference class
1386             vh.setRelease(array, Void.class, "foo");
1387         });
1388         // Incorrect arity
1389         checkWMTE(() -> { // 0
1390             vh.setRelease();
1391         });
1392         checkWMTE(() -> { // >
1393             vh.setRelease(array, 0, "foo", Void.class);
1394         });
1395 
1396 
1397         // CompareAndSet
1398         // Incorrect argument types
1399         checkNPE(() -> { // null receiver
1400             boolean r = vh.compareAndSet(null, 0, "foo", "foo");
1401         });
1402         checkCCE(() -> { // receiver reference class
1403             boolean r = vh.compareAndSet(Void.class, 0, "foo", "foo");
1404         });
1405         checkCCE(() -> { // expected reference class
1406             boolean r = vh.compareAndSet(array, 0, Void.class, "foo");
1407         });
1408         checkCCE(() -> { // actual reference class
1409             boolean r = vh.compareAndSet(array, 0, "foo", Void.class);
1410         });
1411         checkWMTE(() -> { // receiver primitive class
1412             boolean r = vh.compareAndSet(0, 0, "foo", "foo");
1413         });
1414         checkWMTE(() -> { // index reference class
1415             boolean r = vh.compareAndSet(array, Void.class, "foo", "foo");
1416         });
1417         // Incorrect arity
1418         checkWMTE(() -> { // 0
1419             boolean r = vh.compareAndSet();
1420         });
1421         checkWMTE(() -> { // >
1422             boolean r = vh.compareAndSet(array, 0, "foo", "foo", Void.class);
1423         });
1424 
1425 
1426         // WeakCompareAndSet
1427         // Incorrect argument types
1428         checkNPE(() -> { // null receiver
1429             boolean r = vh.weakCompareAndSet(null, 0, "foo", "foo");
1430         });
1431         checkCCE(() -> { // receiver reference class
1432             boolean r = vh.weakCompareAndSet(Void.class, 0, "foo", "foo");
1433         });
1434         checkCCE(() -> { // expected reference class
1435             boolean r = vh.weakCompareAndSet(array, 0, Void.class, "foo");
1436         });
1437         checkCCE(() -> { // actual reference class
1438             boolean r = vh.weakCompareAndSet(array, 0, "foo", Void.class);
1439         });
1440         checkWMTE(() -> { // receiver primitive class
1441             boolean r = vh.weakCompareAndSet(0, 0, "foo", "foo");
1442         });
1443         checkWMTE(() -> { // index reference class
1444             boolean r = vh.weakCompareAndSet(array, Void.class, "foo", "foo");
1445         });
1446         // Incorrect arity
1447         checkWMTE(() -> { // 0
1448             boolean r = vh.weakCompareAndSet();
1449         });
1450         checkWMTE(() -> { // >
1451             boolean r = vh.weakCompareAndSet(array, 0, "foo", "foo", Void.class);
1452         });
1453 
1454 
1455         // WeakCompareAndSetVolatile
1456         // Incorrect argument types
1457         checkNPE(() -> { // null receiver
1458             boolean r = vh.weakCompareAndSetVolatile(null, 0, "foo", "foo");
1459         });
1460         checkCCE(() -> { // receiver reference class
1461             boolean r = vh.weakCompareAndSetVolatile(Void.class, 0, "foo", "foo");
1462         });
1463         checkCCE(() -> { // expected reference class
1464             boolean r = vh.weakCompareAndSetVolatile(array, 0, Void.class, "foo");
1465         });
1466         checkCCE(() -> { // actual reference class
1467             boolean r = vh.weakCompareAndSetVolatile(array, 0, "foo", Void.class);
1468         });
1469         checkWMTE(() -> { // receiver primitive class
1470             boolean r = vh.weakCompareAndSetVolatile(0, 0, "foo", "foo");
1471         });
1472         checkWMTE(() -> { // index reference class
1473             boolean r = vh.weakCompareAndSetVolatile(array, Void.class, "foo", "foo");
1474         });
1475         // Incorrect arity
1476         checkWMTE(() -> { // 0
1477             boolean r = vh.weakCompareAndSetVolatile();
1478         });
1479         checkWMTE(() -> { // >
1480             boolean r = vh.weakCompareAndSetVolatile(array, 0, "foo", "foo", Void.class);
1481         });
1482 
1483 
1484         // WeakCompareAndSetAcquire
1485         // Incorrect argument types
1486         checkNPE(() -> { // null receiver
1487             boolean r = vh.weakCompareAndSetAcquire(null, 0, "foo", "foo");
1488         });
1489         checkCCE(() -> { // receiver reference class
1490             boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, "foo", "foo");
1491         });
1492         checkCCE(() -> { // expected reference class
1493             boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, "foo");
1494         });
1495         checkCCE(() -> { // actual reference class
1496             boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", Void.class);
1497         });
1498         checkWMTE(() -> { // receiver primitive class
1499             boolean r = vh.weakCompareAndSetAcquire(0, 0, "foo", "foo");
1500         });
1501         checkWMTE(() -> { // index reference class
1502             boolean r = vh.weakCompareAndSetAcquire(array, Void.class, "foo", "foo");
1503         });
1504         // Incorrect arity
1505         checkWMTE(() -> { // 0
1506             boolean r = vh.weakCompareAndSetAcquire();
1507         });
1508         checkWMTE(() -> { // >
1509             boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", "foo", Void.class);
1510         });
1511 
1512 
1513         // WeakCompareAndSetRelease
1514         // Incorrect argument types
1515         checkNPE(() -> { // null receiver
1516             boolean r = vh.weakCompareAndSetRelease(null, 0, "foo", "foo");
1517         });
1518         checkCCE(() -> { // receiver reference class
1519             boolean r = vh.weakCompareAndSetRelease(Void.class, 0, "foo", "foo");
1520         });
1521         checkCCE(() -> { // expected reference class
1522             boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, "foo");
1523         });
1524         checkCCE(() -> { // actual reference class
1525             boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", Void.class);
1526         });
1527         checkWMTE(() -> { // receiver primitive class
1528             boolean r = vh.weakCompareAndSetRelease(0, 0, "foo", "foo");
1529         });
1530         checkWMTE(() -> { // index reference class
1531             boolean r = vh.weakCompareAndSetRelease(array, Void.class, "foo", "foo");
1532         });
1533         // Incorrect arity
1534         checkWMTE(() -> { // 0
1535             boolean r = vh.weakCompareAndSetRelease();
1536         });
1537         checkWMTE(() -> { // >
1538             boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", "foo", Void.class);
1539         });
1540 
1541 
1542         // CompareAndExchange
1543         // Incorrect argument types
1544         checkNPE(() -> { // null receiver
1545             String x = (String) vh.compareAndExchange(null, 0, "foo", "foo");
1546         });
1547         checkCCE(() -> { // array reference class
1548             String x = (String) vh.compareAndExchange(Void.class, 0, "foo", "foo");
1549         });
1550         checkCCE(() -> { // expected reference class
1551             String x = (String) vh.compareAndExchange(array, 0, Void.class, "foo");
1552         });
1553         checkCCE(() -> { // actual reference class
1554             String x = (String) vh.compareAndExchange(array, 0, "foo", Void.class);
1555         });
1556         checkWMTE(() -> { // array primitive class
1557             String x = (String) vh.compareAndExchange(0, 0, "foo", "foo");
1558         });
1559         checkWMTE(() -> { // index reference class
1560             String x = (String) vh.compareAndExchange(array, Void.class, "foo", "foo");
1561         });
1562         // Incorrect return type
1563         checkCCE(() -> { // reference class
1564             Void r = (Void) vh.compareAndExchange(array, 0, "foo", "foo");
1565         });
1566         checkWMTE(() -> { // primitive class
1567             boolean x = (boolean) vh.compareAndExchange(array, 0, "foo", "foo");
1568         });
1569         // Incorrect arity
1570         checkWMTE(() -> { // 0
1571             String x = (String) vh.compareAndExchange();
1572         });
1573         checkWMTE(() -> { // >
1574             String x = (String) vh.compareAndExchange(array, 0, "foo", "foo", Void.class);
1575         });
1576 
1577 
1578         // CompareAndExchangeAcquire
1579         // Incorrect argument types
1580         checkNPE(() -> { // null receiver
1581             String x = (String) vh.compareAndExchangeAcquire(null, 0, "foo", "foo");
1582         });
1583         checkCCE(() -> { // array reference class
1584             String x = (String) vh.compareAndExchangeAcquire(Void.class, 0, "foo", "foo");
1585         });
1586         checkCCE(() -> { // expected reference class
1587             String x = (String) vh.compareAndExchangeAcquire(array, 0, Void.class, "foo");
1588         });
1589         checkCCE(() -> { // actual reference class
1590             String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", Void.class);
1591         });
1592         checkWMTE(() -> { // array primitive class
1593             String x = (String) vh.compareAndExchangeAcquire(0, 0, "foo", "foo");
1594         });
1595         checkWMTE(() -> { // index reference class
1596             String x = (String) vh.compareAndExchangeAcquire(array, Void.class, "foo", "foo");
1597         });
1598         // Incorrect return type
1599         checkCCE(() -> { // reference class
1600             Void r = (Void) vh.compareAndExchangeAcquire(array, 0, "foo", "foo");
1601         });
1602         checkWMTE(() -> { // primitive class
1603             boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, "foo", "foo");
1604         });
1605         // Incorrect arity
1606         checkWMTE(() -> { // 0
1607             String x = (String) vh.compareAndExchangeAcquire();
1608         });
1609         checkWMTE(() -> { // >
1610             String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", "foo", Void.class);
1611         });
1612 
1613 
1614         // CompareAndExchangeRelease
1615         // Incorrect argument types
1616         checkNPE(() -> { // null receiver
1617             String x = (String) vh.compareAndExchangeRelease(null, 0, "foo", "foo");
1618         });
1619         checkCCE(() -> { // array reference class
1620             String x = (String) vh.compareAndExchangeRelease(Void.class, 0, "foo", "foo");
1621         });
1622         checkCCE(() -> { // expected reference class
1623             String x = (String) vh.compareAndExchangeRelease(array, 0, Void.class, "foo");
1624         });
1625         checkCCE(() -> { // actual reference class
1626             String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", Void.class);
1627         });
1628         checkWMTE(() -> { // array primitive class
1629             String x = (String) vh.compareAndExchangeRelease(0, 0, "foo", "foo");
1630         });
1631         checkWMTE(() -> { // index reference class
1632             String x = (String) vh.compareAndExchangeRelease(array, Void.class, "foo", "foo");
1633         });
1634         // Incorrect return type
1635         checkCCE(() -> { // reference class
1636             Void r = (Void) vh.compareAndExchangeRelease(array, 0, "foo", "foo");
1637         });
1638         checkWMTE(() -> { // primitive class
1639             boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, "foo", "foo");
1640         });
1641         // Incorrect arity
1642         checkWMTE(() -> { // 0
1643             String x = (String) vh.compareAndExchangeRelease();
1644         });
1645         checkWMTE(() -> { // >
1646             String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", "foo", Void.class);
1647         });
1648 
1649 
1650         // GetAndSet
1651         // Incorrect argument types
1652         checkNPE(() -> { // null array
1653             String x = (String) vh.getAndSet(null, 0, "foo");
1654         });
1655         checkCCE(() -> { // array reference class
1656             String x = (String) vh.getAndSet(Void.class, 0, "foo");
1657         });
1658         checkCCE(() -> { // value reference class
1659             String x = (String) vh.getAndSet(array, 0, Void.class);
1660         });
1661         checkWMTE(() -> { // reciarrayever primitive class
1662             String x = (String) vh.getAndSet(0, 0, "foo");
1663         });
1664         checkWMTE(() -> { // index reference class
1665             String x = (String) vh.getAndSet(array, Void.class, "foo");
1666         });
1667         // Incorrect return type
1668         checkCCE(() -> { // reference class
1669             Void r = (Void) vh.getAndSet(array, 0, "foo");
1670         });
1671         checkWMTE(() -> { // primitive class
1672             boolean x = (boolean) vh.getAndSet(array, 0, "foo");
1673         });
1674         // Incorrect arity
1675         checkWMTE(() -> { // 0
1676             String x = (String) vh.getAndSet();
1677         });
1678         checkWMTE(() -> { // >
1679             String x = (String) vh.getAndSet(array, 0, "foo", Void.class);
1680         });
1681 
1682     }
1683 
1684     static void testArrayWrongMethodType(Handles hs) throws Throwable {
1685         String[] array = new String[10];
1686         Arrays.fill(array, "foo");
1687 
1688         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
1689             // Incorrect argument types
1690             checkNPE(() -> { // null array
1691                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class)).
1692                     invokeExact((String[]) null, 0);
1693             });
1694             hs.checkWMTEOrCCE(() -> { // array reference class
1695                 String x = (String) hs.get(am, methodType(String.class, Class.class, int.class)).
1696                     invokeExact(Void.class, 0);
1697             });
1698             checkWMTE(() -> { // array primitive class
1699                 String x = (String) hs.get(am, methodType(String.class, int.class, int.class)).
1700                     invokeExact(0, 0);
1701             });
1702             checkWMTE(() -> { // index reference class
1703                 String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class)).
1704                     invokeExact(array, Void.class);
1705             });
1706             // Incorrect return type
1707             hs.checkWMTEOrCCE(() -> { // reference class
1708                 Void x = (Void) hs.get(am, methodType(Void.class, String[].class, int.class)).
1709                     invokeExact(array, 0);
1710             });
1711             checkWMTE(() -> { // primitive class
1712                 boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class)).
1713                     invokeExact(array, 0);
1714             });
1715             // Incorrect arity
1716             checkWMTE(() -> { // 0
1717                 String x = (String) hs.get(am, methodType(String.class)).
1718                     invokeExact();
1719             });
1720             checkWMTE(() -> { // >
1721                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)).
1722                     invokeExact(array, 0, Void.class);
1723             });
1724         }
1725 
1726         for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
1727             // Incorrect argument types
1728             checkNPE(() -> { // null array
1729                 hs.get(am, methodType(void.class, String[].class, int.class, String.class)).
1730                     invokeExact((String[]) null, 0, "foo");
1731             });
1732             hs.checkWMTEOrCCE(() -> { // array reference class
1733                 hs.get(am, methodType(void.class, Class.class, int.class, String.class)).
1734                     invokeExact(Void.class, 0, "foo");
1735             });
1736             hs.checkWMTEOrCCE(() -> { // value reference class
1737                 hs.get(am, methodType(void.class, String[].class, int.class, Class.class)).
1738                     invokeExact(array, 0, Void.class);
1739             });
1740             checkWMTE(() -> { // receiver primitive class
1741                 hs.get(am, methodType(void.class, int.class, int.class, String.class)).
1742                     invokeExact(0, 0, "foo");
1743             });
1744             checkWMTE(() -> { // index reference class
1745                 hs.get(am, methodType(void.class, String[].class, Class.class, String.class)).
1746                     invokeExact(array, Void.class, "foo");
1747             });
1748             // Incorrect arity
1749             checkWMTE(() -> { // 0
1750                 hs.get(am, methodType(void.class)).
1751                     invokeExact();
1752             });
1753             checkWMTE(() -> { // >
1754                 hs.get(am, methodType(void.class, String[].class, int.class, Class.class)).
1755                     invokeExact(array, 0, "foo", Void.class);
1756             });
1757         }
1758         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
1759             // Incorrect argument types
1760             checkNPE(() -> { // null receiver
1761                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class)).
1762                     invokeExact((String[]) null, 0, "foo", "foo");
1763             });
1764             hs.checkWMTEOrCCE(() -> { // receiver reference class
1765                 boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, String.class, String.class)).
1766                     invokeExact(Void.class, 0, "foo", "foo");
1767             });
1768             hs.checkWMTEOrCCE(() -> { // expected reference class
1769                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, Class.class, String.class)).
1770                     invokeExact(array, 0, Void.class, "foo");
1771             });
1772             hs.checkWMTEOrCCE(() -> { // actual reference class
1773                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, Class.class)).
1774                     invokeExact(array, 0, "foo", Void.class);
1775             });
1776             checkWMTE(() -> { // receiver primitive class
1777                 boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, String.class, String.class)).
1778                     invokeExact(0, 0, "foo", "foo");
1779             });
1780             checkWMTE(() -> { // index reference class
1781                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, Class.class, String.class, String.class)).
1782                     invokeExact(array, Void.class, "foo", "foo");
1783             });
1784             // Incorrect arity
1785             checkWMTE(() -> { // 0
1786                 boolean r = (boolean) hs.get(am, methodType(boolean.class)).
1787                     invokeExact();
1788             });
1789             checkWMTE(() -> { // >
1790                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class, Class.class)).
1791                     invokeExact(array, 0, "foo", "foo", Void.class);
1792             });
1793         }
1794 
1795         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
1796             // Incorrect argument types
1797             checkNPE(() -> { // null receiver
1798                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, String.class)).
1799                     invokeExact((String[]) null, 0, "foo", "foo");
1800             });
1801             hs.checkWMTEOrCCE(() -> { // array reference class
1802                 String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class, String.class)).
1803                     invokeExact(Void.class, 0, "foo", "foo");
1804             });
1805             hs.checkWMTEOrCCE(() -> { // expected reference class
1806                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class, String.class)).
1807                     invokeExact(array, 0, Void.class, "foo");
1808             });
1809             hs.checkWMTEOrCCE(() -> { // actual reference class
1810                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)).
1811                     invokeExact(array, 0, "foo", Void.class);
1812             });
1813             checkWMTE(() -> { // array primitive class
1814                 String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class, String.class)).
1815                     invokeExact(0, 0, "foo", "foo");
1816             });
1817             checkWMTE(() -> { // index reference class
1818                 String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class, String.class)).
1819                     invokeExact(array, Void.class, "foo", "foo");
1820             });
1821             // Incorrect return type
1822             hs.checkWMTEOrCCE(() -> { // reference class
1823                 Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class, String.class)).
1824                     invokeExact(array, 0, "foo", "foo");
1825             });
1826             checkWMTE(() -> { // primitive class
1827                 boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class)).
1828                     invokeExact(array, 0, "foo", "foo");
1829             });
1830             // Incorrect arity
1831             checkWMTE(() -> { // 0
1832                 String x = (String) hs.get(am, methodType(String.class)).
1833                     invokeExact();
1834             });
1835             checkWMTE(() -> { // >
1836                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, String.class, Class.class)).
1837                     invokeExact(array, 0, "foo", "foo", Void.class);
1838             });
1839         }
1840 
1841         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
1842             // Incorrect argument types
1843             checkNPE(() -> { // null array
1844                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class)).
1845                     invokeExact((String[]) null, 0, "foo");
1846             });
1847             hs.checkWMTEOrCCE(() -> { // array reference class
1848                 String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class)).
1849                     invokeExact(Void.class, 0, "foo");
1850             });
1851             hs.checkWMTEOrCCE(() -> { // value reference class
1852                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)).
1853                     invokeExact(array, 0, Void.class);
1854             });
1855             checkWMTE(() -> { // array primitive class
1856                 String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class)).
1857                     invokeExact(0, 0, "foo");
1858             });
1859             checkWMTE(() -> { // index reference class
1860                 String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class)).
1861                     invokeExact(array, Void.class, "foo");
1862             });
1863             // Incorrect return type
1864             hs.checkWMTEOrCCE(() -> { // reference class
1865                 Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class)).
1866                     invokeExact(array, 0, "foo");
1867             });
1868             checkWMTE(() -> { // primitive class
1869                 boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class)).
1870                     invokeExact(array, 0, "foo");
1871             });
1872             // Incorrect arity
1873             checkWMTE(() -> { // 0
1874                 String x = (String) hs.get(am, methodType(String.class)).
1875                     invokeExact();
1876             });
1877             checkWMTE(() -> { // >
1878                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)).
1879                     invokeExact(array, 0, "foo", Void.class);
1880             });
1881         }
1882 
1883     }
1884 }
1885