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.weakCompareAndSetPlain(null, "foo", "foo");
 357         });
 358         checkCCE(() -> { // receiver reference class
 359             boolean r = vh.weakCompareAndSetPlain(Void.class, "foo", "foo");
 360         });
 361         checkCCE(() -> { // expected reference class
 362             boolean r = vh.weakCompareAndSetPlain(recv, Void.class, "foo");
 363         });
 364         checkCCE(() -> { // actual reference class
 365             boolean r = vh.weakCompareAndSetPlain(recv, "foo", Void.class);
 366         });
 367         checkWMTE(() -> { // receiver primitive class
 368             boolean r = vh.weakCompareAndSetPlain(0, "foo", "foo");
 369         });
 370         // Incorrect arity
 371         checkWMTE(() -> { // 0
 372             boolean r = vh.weakCompareAndSetPlain();
 373         });
 374         checkWMTE(() -> { // >
 375             boolean r = vh.weakCompareAndSetPlain(recv, "foo", "foo", Void.class);
 376         });
 377 
 378 
 379         // WeakCompareAndSetVolatile
 380         // Incorrect argument types
 381         checkNPE(() -> { // null receiver
 382             boolean r = vh.weakCompareAndSet(null, "foo", "foo");
 383         });
 384         checkCCE(() -> { // receiver reference class
 385             boolean r = vh.weakCompareAndSet(Void.class, "foo", "foo");
 386         });
 387         checkCCE(() -> { // expected reference class
 388             boolean r = vh.weakCompareAndSet(recv, Void.class, "foo");
 389         });
 390         checkCCE(() -> { // actual reference class
 391             boolean r = vh.weakCompareAndSet(recv, "foo", Void.class);
 392         });
 393         checkWMTE(() -> { // receiver primitive class
 394             boolean r = vh.weakCompareAndSet(0, "foo", "foo");
 395         });
 396         // Incorrect arity
 397         checkWMTE(() -> { // 0
 398             boolean r = vh.weakCompareAndSet();
 399         });
 400         checkWMTE(() -> { // >
 401             boolean r = vh.weakCompareAndSet(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         // GetAndSetAcquire
 586         // Incorrect argument types
 587         checkNPE(() -> { // null receiver
 588             String x = (String) vh.getAndSetAcquire(null, "foo");
 589         });
 590         checkCCE(() -> { // receiver reference class
 591             String x = (String) vh.getAndSetAcquire(Void.class, "foo");
 592         });
 593         checkCCE(() -> { // value reference class
 594             String x = (String) vh.getAndSetAcquire(recv, Void.class);
 595         });
 596         checkWMTE(() -> { // reciever primitive class
 597             String x = (String) vh.getAndSetAcquire(0, "foo");
 598         });
 599         // Incorrect return type
 600         checkCCE(() -> { // reference class
 601             Void r = (Void) vh.getAndSetAcquire(recv, "foo");
 602         });
 603         checkWMTE(() -> { // primitive class
 604             boolean x = (boolean) vh.getAndSetAcquire(recv, "foo");
 605         });
 606         // Incorrect arity
 607         checkWMTE(() -> { // 0
 608             String x = (String) vh.getAndSetAcquire();
 609         });
 610         checkWMTE(() -> { // >
 611             String x = (String) vh.getAndSetAcquire(recv, "foo", Void.class);
 612         });
 613 
 614         // GetAndSetRelease
 615         // Incorrect argument types
 616         checkNPE(() -> { // null receiver
 617             String x = (String) vh.getAndSetRelease(null, "foo");
 618         });
 619         checkCCE(() -> { // receiver reference class
 620             String x = (String) vh.getAndSetRelease(Void.class, "foo");
 621         });
 622         checkCCE(() -> { // value reference class
 623             String x = (String) vh.getAndSetRelease(recv, Void.class);
 624         });
 625         checkWMTE(() -> { // reciever primitive class
 626             String x = (String) vh.getAndSetRelease(0, "foo");
 627         });
 628         // Incorrect return type
 629         checkCCE(() -> { // reference class
 630             Void r = (Void) vh.getAndSetRelease(recv, "foo");
 631         });
 632         checkWMTE(() -> { // primitive class
 633             boolean x = (boolean) vh.getAndSetRelease(recv, "foo");
 634         });
 635         // Incorrect arity
 636         checkWMTE(() -> { // 0
 637             String x = (String) vh.getAndSetRelease();
 638         });
 639         checkWMTE(() -> { // >
 640             String x = (String) vh.getAndSetRelease(recv, "foo", Void.class);
 641         });
 642 
 643 
 644     }
 645 
 646     static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeString recv, Handles hs) throws Throwable {
 647         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
 648             // Incorrect argument types
 649             checkNPE(() -> { // null receiver
 650                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class)).
 651                     invokeExact((VarHandleTestMethodTypeString) null);
 652             });
 653             hs.checkWMTEOrCCE(() -> { // receiver reference class
 654                 String x = (String) hs.get(am, methodType(String.class, Class.class)).
 655                     invokeExact(Void.class);
 656             });
 657             checkWMTE(() -> { // receiver primitive class
 658                 String x = (String) hs.get(am, methodType(String.class, int.class)).
 659                     invokeExact(0);
 660             });
 661             // Incorrect return type
 662             hs.checkWMTEOrCCE(() -> { // reference class
 663                 Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class)).
 664                     invokeExact(recv);
 665             });
 666             checkWMTE(() -> { // primitive class
 667                 boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class)).
 668                     invokeExact(recv);
 669             });
 670             // Incorrect arity
 671             checkWMTE(() -> { // 0
 672                 String x = (String) hs.get(am, methodType(String.class)).
 673                     invokeExact();
 674             });
 675             checkWMTE(() -> { // >
 676                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)).
 677                     invokeExact(recv, Void.class);
 678             });
 679         }
 680 
 681         for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
 682             // Incorrect argument types
 683             checkNPE(() -> { // null receiver
 684                 hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, String.class)).
 685                     invokeExact((VarHandleTestMethodTypeString) null, "foo");
 686             });
 687             hs.checkWMTEOrCCE(() -> { // receiver reference class
 688                 hs.get(am, methodType(void.class, Class.class, String.class)).
 689                     invokeExact(Void.class, "foo");
 690             });
 691             hs.checkWMTEOrCCE(() -> { // value reference class
 692                 hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, Class.class)).
 693                     invokeExact(recv, Void.class);
 694             });
 695             checkWMTE(() -> { // receiver primitive class
 696                 hs.get(am, methodType(void.class, int.class, String.class)).
 697                     invokeExact(0, "foo");
 698             });
 699             // Incorrect arity
 700             checkWMTE(() -> { // 0
 701                 hs.get(am, methodType(void.class)).
 702                     invokeExact();
 703             });
 704             checkWMTE(() -> { // >
 705                 hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
 706                     invokeExact(recv, "foo", Void.class);
 707             });
 708         }
 709 
 710         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
 711             // Incorrect argument types
 712             checkNPE(() -> { // null receiver
 713                 boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, String.class)).
 714                     invokeExact((VarHandleTestMethodTypeString) null, "foo", "foo");
 715             });
 716             hs.checkWMTEOrCCE(() -> { // receiver reference class
 717                 boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class, String.class)).
 718                     invokeExact(Void.class, "foo", "foo");
 719             });
 720             hs.checkWMTEOrCCE(() -> { // expected reference class
 721                 boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, Class.class, String.class)).
 722                     invokeExact(recv, Void.class, "foo");
 723             });
 724             hs.checkWMTEOrCCE(() -> { // actual reference class
 725                 boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
 726                     invokeExact(recv, "foo", Void.class);
 727             });
 728             checkWMTE(() -> { // receiver primitive class
 729                 boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , String.class, String.class)).
 730                     invokeExact(0, "foo", "foo");
 731             });
 732             // Incorrect arity
 733             checkWMTE(() -> { // 0
 734                 boolean r = (boolean) hs.get(am, methodType(boolean.class)).
 735                     invokeExact();
 736             });
 737             checkWMTE(() -> { // >
 738                 boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)).
 739                     invokeExact(recv, "foo", "foo", Void.class);
 740             });
 741         }
 742 
 743         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
 744             checkNPE(() -> { // null receiver
 745                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, String.class)).
 746                     invokeExact((VarHandleTestMethodTypeString) null, "foo", "foo");
 747             });
 748             hs.checkWMTEOrCCE(() -> { // receiver reference class
 749                 String x = (String) hs.get(am, methodType(String.class, Class.class, String.class, String.class)).
 750                     invokeExact(Void.class, "foo", "foo");
 751             });
 752             hs.checkWMTEOrCCE(() -> { // expected reference class
 753                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class, String.class)).
 754                     invokeExact(recv, Void.class, "foo");
 755             });
 756             hs.checkWMTEOrCCE(() -> { // actual reference class
 757                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
 758                     invokeExact(recv, "foo", Void.class);
 759             });
 760             checkWMTE(() -> { // reciever primitive class
 761                 String x = (String) hs.get(am, methodType(String.class, int.class , String.class, String.class)).
 762                     invokeExact(0, "foo", "foo");
 763             });
 764             // Incorrect return type
 765             hs.checkWMTEOrCCE(() -> { // reference class
 766                 Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class , String.class, String.class)).
 767                     invokeExact(recv, "foo", "foo");
 768             });
 769             checkWMTE(() -> { // primitive class
 770                 boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class , String.class, String.class)).
 771                     invokeExact(recv, "foo", "foo");
 772             });
 773             // Incorrect arity
 774             checkWMTE(() -> { // 0
 775                 String x = (String) hs.get(am, methodType(String.class)).
 776                     invokeExact();
 777             });
 778             checkWMTE(() -> { // >
 779                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)).
 780                     invokeExact(recv, "foo", "foo", Void.class);
 781             });
 782         }
 783 
 784         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
 785             checkNPE(() -> { // null receiver
 786                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class)).
 787                     invokeExact((VarHandleTestMethodTypeString) null, "foo");
 788             });
 789             hs.checkWMTEOrCCE(() -> { // receiver reference class
 790                 String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)).
 791                     invokeExact(Void.class, "foo");
 792             });
 793             hs.checkWMTEOrCCE(() -> { // value reference class
 794                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)).
 795                     invokeExact(recv, Void.class);
 796             });
 797             checkWMTE(() -> { // reciever primitive class
 798                 String x = (String) hs.get(am, methodType(String.class, int.class, String.class)).
 799                     invokeExact(0, "foo");
 800             });
 801             // Incorrect return type
 802             hs.checkWMTEOrCCE(() -> { // reference class
 803                 Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class, String.class)).
 804                     invokeExact(recv, "foo");
 805             });
 806             checkWMTE(() -> { // primitive class
 807                 boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class)).
 808                     invokeExact(recv, "foo");
 809             });
 810             // Incorrect arity
 811             checkWMTE(() -> { // 0
 812                 String x = (String) hs.get(am, methodType(String.class)).
 813                     invokeExact();
 814             });
 815             checkWMTE(() -> { // >
 816                 String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class)).
 817                     invokeExact(recv, "foo", Void.class);
 818             });
 819         }
 820 
 821 
 822     }
 823 
 824 
 825     static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
 826         // Get
 827         // Incorrect return type
 828         checkCCE(() -> { // reference class
 829             Void x = (Void) vh.get();
 830         });
 831         checkWMTE(() -> { // primitive class
 832             boolean x = (boolean) vh.get();
 833         });
 834         // Incorrect arity
 835         checkWMTE(() -> { // >
 836             String x = (String) vh.get(Void.class);
 837         });
 838 
 839 
 840         // Set
 841         // Incorrect argument types
 842         checkCCE(() -> { // value reference class
 843             vh.set(Void.class);
 844         });
 845         // Incorrect arity
 846         checkWMTE(() -> { // 0
 847             vh.set();
 848         });
 849         checkWMTE(() -> { // >
 850             vh.set("foo", Void.class);
 851         });
 852 
 853 
 854         // GetVolatile
 855         // Incorrect return type
 856         checkCCE(() -> { // reference class
 857             Void x = (Void) vh.getVolatile();
 858         });
 859         checkWMTE(() -> { // primitive class
 860             boolean x = (boolean) vh.getVolatile();
 861         });
 862         checkWMTE(() -> { // >
 863             String x = (String) vh.getVolatile(Void.class);
 864         });
 865 
 866 
 867         // SetVolatile
 868         // Incorrect argument types
 869         checkCCE(() -> { // value reference class
 870             vh.setVolatile(Void.class);
 871         });
 872         // Incorrect arity
 873         checkWMTE(() -> { // 0
 874             vh.setVolatile();
 875         });
 876         checkWMTE(() -> { // >
 877             vh.setVolatile("foo", Void.class);
 878         });
 879 
 880 
 881         // GetOpaque
 882         // Incorrect return type
 883         checkCCE(() -> { // reference class
 884             Void x = (Void) vh.getOpaque();
 885         });
 886         checkWMTE(() -> { // primitive class
 887             boolean x = (boolean) vh.getOpaque();
 888         });
 889         checkWMTE(() -> { // >
 890             String x = (String) vh.getOpaque(Void.class);
 891         });
 892 
 893 
 894         // SetOpaque
 895         // Incorrect argument types
 896         checkCCE(() -> { // value reference class
 897             vh.setOpaque(Void.class);
 898         });
 899         // Incorrect arity
 900         checkWMTE(() -> { // 0
 901             vh.setOpaque();
 902         });
 903         checkWMTE(() -> { // >
 904             vh.setOpaque("foo", Void.class);
 905         });
 906 
 907 
 908         // GetAcquire
 909         // Incorrect return type
 910         checkCCE(() -> { // reference class
 911             Void x = (Void) vh.getAcquire();
 912         });
 913         checkWMTE(() -> { // primitive class
 914             boolean x = (boolean) vh.getAcquire();
 915         });
 916         checkWMTE(() -> { // >
 917             String x = (String) vh.getAcquire(Void.class);
 918         });
 919 
 920 
 921         // SetRelease
 922         // Incorrect argument types
 923         checkCCE(() -> { // value reference class
 924             vh.setRelease(Void.class);
 925         });
 926         // Incorrect arity
 927         checkWMTE(() -> { // 0
 928             vh.setRelease();
 929         });
 930         checkWMTE(() -> { // >
 931             vh.setRelease("foo", Void.class);
 932         });
 933 
 934 
 935         // CompareAndSet
 936         // Incorrect argument types
 937         checkCCE(() -> { // expected reference class
 938             boolean r = vh.compareAndSet(Void.class, "foo");
 939         });
 940         checkCCE(() -> { // actual reference class
 941             boolean r = vh.compareAndSet("foo", Void.class);
 942         });
 943         // Incorrect arity
 944         checkWMTE(() -> { // 0
 945             boolean r = vh.compareAndSet();
 946         });
 947         checkWMTE(() -> { // >
 948             boolean r = vh.compareAndSet("foo", "foo", Void.class);
 949         });
 950 
 951 
 952         // WeakCompareAndSet
 953         // Incorrect argument types
 954         checkCCE(() -> { // expected reference class
 955             boolean r = vh.weakCompareAndSetPlain(Void.class, "foo");
 956         });
 957         checkCCE(() -> { // actual reference class
 958             boolean r = vh.weakCompareAndSetPlain("foo", Void.class);
 959         });
 960         // Incorrect arity
 961         checkWMTE(() -> { // 0
 962             boolean r = vh.weakCompareAndSetPlain();
 963         });
 964         checkWMTE(() -> { // >
 965             boolean r = vh.weakCompareAndSetPlain("foo", "foo", Void.class);
 966         });
 967 
 968 
 969         // WeakCompareAndSetVolatile
 970         // Incorrect argument types
 971         checkCCE(() -> { // expected reference class
 972             boolean r = vh.weakCompareAndSet(Void.class, "foo");
 973         });
 974         checkCCE(() -> { // actual reference class
 975             boolean r = vh.weakCompareAndSet("foo", Void.class);
 976         });
 977         // Incorrect arity
 978         checkWMTE(() -> { // 0
 979             boolean r = vh.weakCompareAndSet();
 980         });
 981         checkWMTE(() -> { // >
 982             boolean r = vh.weakCompareAndSet("foo", "foo", Void.class);
 983         });
 984 
 985 
 986         // WeakCompareAndSetAcquire
 987         // Incorrect argument types
 988         checkCCE(() -> { // expected reference class
 989             boolean r = vh.weakCompareAndSetAcquire(Void.class, "foo");
 990         });
 991         checkCCE(() -> { // actual reference class
 992             boolean r = vh.weakCompareAndSetAcquire("foo", Void.class);
 993         });
 994         // Incorrect arity
 995         checkWMTE(() -> { // 0
 996             boolean r = vh.weakCompareAndSetAcquire();
 997         });
 998         checkWMTE(() -> { // >
 999             boolean r = vh.weakCompareAndSetAcquire("foo", "foo", Void.class);
1000         });
1001 
1002 
1003         // WeakCompareAndSetRelease
1004         // Incorrect argument types
1005         checkCCE(() -> { // expected reference class
1006             boolean r = vh.weakCompareAndSetRelease(Void.class, "foo");
1007         });
1008         checkCCE(() -> { // actual reference class
1009             boolean r = vh.weakCompareAndSetRelease("foo", Void.class);
1010         });
1011         // Incorrect arity
1012         checkWMTE(() -> { // 0
1013             boolean r = vh.weakCompareAndSetRelease();
1014         });
1015         checkWMTE(() -> { // >
1016             boolean r = vh.weakCompareAndSetRelease("foo", "foo", Void.class);
1017         });
1018 
1019 
1020         // CompareAndExchange
1021         // Incorrect argument types
1022         checkCCE(() -> { // expected reference class
1023             String x = (String) vh.compareAndExchange(Void.class, "foo");
1024         });
1025         checkCCE(() -> { // actual reference class
1026             String x = (String) vh.compareAndExchange("foo", Void.class);
1027         });
1028         // Incorrect return type
1029         checkCCE(() -> { // reference class
1030             Void r = (Void) vh.compareAndExchange("foo", "foo");
1031         });
1032         checkWMTE(() -> { // primitive class
1033             boolean x = (boolean) vh.compareAndExchange("foo", "foo");
1034         });
1035         // Incorrect arity
1036         checkWMTE(() -> { // 0
1037             String x = (String) vh.compareAndExchange();
1038         });
1039         checkWMTE(() -> { // >
1040             String x = (String) vh.compareAndExchange("foo", "foo", Void.class);
1041         });
1042 
1043 
1044         // CompareAndExchangeAcquire
1045         // Incorrect argument types
1046         checkCCE(() -> { // expected reference class
1047             String x = (String) vh.compareAndExchangeAcquire(Void.class, "foo");
1048         });
1049         checkCCE(() -> { // actual reference class
1050             String x = (String) vh.compareAndExchangeAcquire("foo", Void.class);
1051         });
1052         // Incorrect return type
1053         checkCCE(() -> { // reference class
1054             Void r = (Void) vh.compareAndExchangeAcquire("foo", "foo");
1055         });
1056         checkWMTE(() -> { // primitive class
1057             boolean x = (boolean) vh.compareAndExchangeAcquire("foo", "foo");
1058         });
1059         // Incorrect arity
1060         checkWMTE(() -> { // 0
1061             String x = (String) vh.compareAndExchangeAcquire();
1062         });
1063         checkWMTE(() -> { // >
1064             String x = (String) vh.compareAndExchangeAcquire("foo", "foo", Void.class);
1065         });
1066 
1067 
1068         // CompareAndExchangeRelease
1069         // Incorrect argument types
1070         checkCCE(() -> { // expected reference class
1071             String x = (String) vh.compareAndExchangeRelease(Void.class, "foo");
1072         });
1073         checkCCE(() -> { // actual reference class
1074             String x = (String) vh.compareAndExchangeRelease("foo", Void.class);
1075         });
1076         // Incorrect return type
1077         checkCCE(() -> { // reference class
1078             Void r = (Void) vh.compareAndExchangeRelease("foo", "foo");
1079         });
1080         checkWMTE(() -> { // primitive class
1081             boolean x = (boolean) vh.compareAndExchangeRelease("foo", "foo");
1082         });
1083         // Incorrect arity
1084         checkWMTE(() -> { // 0
1085             String x = (String) vh.compareAndExchangeRelease();
1086         });
1087         checkWMTE(() -> { // >
1088             String x = (String) vh.compareAndExchangeRelease("foo", "foo", Void.class);
1089         });
1090 
1091 
1092         // GetAndSet
1093         // Incorrect argument types
1094         checkCCE(() -> { // value reference class
1095             String x = (String) vh.getAndSet(Void.class);
1096         });
1097         // Incorrect return type
1098         checkCCE(() -> { // reference class
1099             Void r = (Void) vh.getAndSet("foo");
1100         });
1101         checkWMTE(() -> { // primitive class
1102             boolean x = (boolean) vh.getAndSet("foo");
1103         });
1104         // Incorrect arity
1105         checkWMTE(() -> { // 0
1106             String x = (String) vh.getAndSet();
1107         });
1108         checkWMTE(() -> { // >
1109             String x = (String) vh.getAndSet("foo", Void.class);
1110         });
1111 
1112 
1113         // GetAndSetAcquire
1114         // Incorrect argument types
1115         checkCCE(() -> { // value reference class
1116             String x = (String) vh.getAndSetAcquire(Void.class);
1117         });
1118         // Incorrect return type
1119         checkCCE(() -> { // reference class
1120             Void r = (Void) vh.getAndSetAcquire("foo");
1121         });
1122         checkWMTE(() -> { // primitive class
1123             boolean x = (boolean) vh.getAndSetAcquire("foo");
1124         });
1125         // Incorrect arity
1126         checkWMTE(() -> { // 0
1127             String x = (String) vh.getAndSetAcquire();
1128         });
1129         checkWMTE(() -> { // >
1130             String x = (String) vh.getAndSetAcquire("foo", Void.class);
1131         });
1132 
1133 
1134         // GetAndSetRelease
1135         // Incorrect argument types
1136         checkCCE(() -> { // value reference class
1137             String x = (String) vh.getAndSetRelease(Void.class);
1138         });
1139         // Incorrect return type
1140         checkCCE(() -> { // reference class
1141             Void r = (Void) vh.getAndSetRelease("foo");
1142         });
1143         checkWMTE(() -> { // primitive class
1144             boolean x = (boolean) vh.getAndSetRelease("foo");
1145         });
1146         // Incorrect arity
1147         checkWMTE(() -> { // 0
1148             String x = (String) vh.getAndSetRelease();
1149         });
1150         checkWMTE(() -> { // >
1151             String x = (String) vh.getAndSetRelease("foo", Void.class);
1152         });
1153 
1154 
1155     }
1156 
1157     static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
1158         int i = 0;
1159 
1160         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
1161             // Incorrect return type
1162             hs.checkWMTEOrCCE(() -> { // reference class
1163                 Void x = (Void) hs.get(am, methodType(Void.class)).
1164                     invokeExact();
1165             });
1166             checkWMTE(() -> { // primitive class
1167                 boolean x = (boolean) hs.get(am, methodType(boolean.class)).
1168                     invokeExact();
1169             });
1170             // Incorrect arity
1171             checkWMTE(() -> { // >
1172                 String x = (String) hs.get(am, methodType(Class.class)).
1173                     invokeExact(Void.class);
1174             });
1175         }
1176 
1177         for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
1178             hs.checkWMTEOrCCE(() -> { // value reference class
1179                 hs.get(am, methodType(void.class, Class.class)).
1180                     invokeExact(Void.class);
1181             });
1182             // Incorrect arity
1183             checkWMTE(() -> { // 0
1184                 hs.get(am, methodType(void.class)).
1185                     invokeExact();
1186             });
1187             checkWMTE(() -> { // >
1188                 hs.get(am, methodType(void.class, String.class, Class.class)).
1189                     invokeExact("foo", Void.class);
1190             });
1191         }
1192         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
1193             // Incorrect argument types
1194             hs.checkWMTEOrCCE(() -> { // expected reference class
1195                 boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class)).
1196                     invokeExact(Void.class, "foo");
1197             });
1198             hs.checkWMTEOrCCE(() -> { // actual reference class
1199                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, Class.class)).
1200                     invokeExact("foo", Void.class);
1201             });
1202             // Incorrect arity
1203             checkWMTE(() -> { // 0
1204                 boolean r = (boolean) hs.get(am, methodType(boolean.class)).
1205                     invokeExact();
1206             });
1207             checkWMTE(() -> { // >
1208                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class, Class.class)).
1209                     invokeExact("foo", "foo", Void.class);
1210             });
1211         }
1212 
1213         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
1214             // Incorrect argument types
1215             hs.checkWMTEOrCCE(() -> { // expected reference class
1216                 String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)).
1217                     invokeExact(Void.class, "foo");
1218             });
1219             hs.checkWMTEOrCCE(() -> { // actual reference class
1220                 String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)).
1221                     invokeExact("foo", Void.class);
1222             });
1223             // Incorrect return type
1224             hs.checkWMTEOrCCE(() -> { // reference class
1225                 Void r = (Void) hs.get(am, methodType(Void.class, String.class, String.class)).
1226                     invokeExact("foo", "foo");
1227             });
1228             checkWMTE(() -> { // primitive class
1229                 boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class)).
1230                     invokeExact("foo", "foo");
1231             });
1232             // Incorrect arity
1233             checkWMTE(() -> { // 0
1234                 String x = (String) hs.get(am, methodType(String.class)).
1235                     invokeExact();
1236             });
1237             checkWMTE(() -> { // >
1238                 String x = (String) hs.get(am, methodType(String.class, String.class, String.class, Class.class)).
1239                     invokeExact("foo", "foo", Void.class);
1240             });
1241         }
1242 
1243         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
1244             // Incorrect argument types
1245             hs.checkWMTEOrCCE(() -> { // value reference class
1246                 String x = (String) hs.get(am, methodType(String.class, Class.class)).
1247                     invokeExact(Void.class);
1248             });
1249             // Incorrect return type
1250             hs.checkWMTEOrCCE(() -> { // reference class
1251                 Void r = (Void) hs.get(am, methodType(Void.class, String.class)).
1252                     invokeExact("foo");
1253             });
1254             checkWMTE(() -> { // primitive class
1255                 boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class)).
1256                     invokeExact("foo");
1257             });
1258             // Incorrect arity
1259             checkWMTE(() -> { // 0
1260                 String x = (String) hs.get(am, methodType(String.class)).
1261                     invokeExact();
1262             });
1263             checkWMTE(() -> { // >
1264                 String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)).
1265                     invokeExact("foo", Void.class);
1266             });
1267         }
1268 
1269 
1270     }
1271 
1272 
1273     static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
1274         String[] array = new String[10];
1275         Arrays.fill(array, "foo");
1276 
1277         // Get
1278         // Incorrect argument types
1279         checkNPE(() -> { // null array
1280             String x = (String) vh.get(null, 0);
1281         });
1282         checkCCE(() -> { // array reference class
1283             String x = (String) vh.get(Void.class, 0);
1284         });
1285         checkWMTE(() -> { // array primitive class
1286             String x = (String) vh.get(0, 0);
1287         });
1288         checkWMTE(() -> { // index reference class
1289             String x = (String) vh.get(array, Void.class);
1290         });
1291         // Incorrect return type
1292         checkCCE(() -> { // reference class
1293             Void x = (Void) vh.get(array, 0);
1294         });
1295         checkWMTE(() -> { // primitive class
1296             boolean x = (boolean) vh.get(array, 0);
1297         });
1298         // Incorrect arity
1299         checkWMTE(() -> { // 0
1300             String x = (String) vh.get();
1301         });
1302         checkWMTE(() -> { // >
1303             String x = (String) vh.get(array, 0, Void.class);
1304         });
1305 
1306 
1307         // Set
1308         // Incorrect argument types
1309         checkNPE(() -> { // null array
1310             vh.set(null, 0, "foo");
1311         });
1312         checkCCE(() -> { // array reference class
1313             vh.set(Void.class, 0, "foo");
1314         });
1315         checkCCE(() -> { // value reference class
1316             vh.set(array, 0, Void.class);
1317         });
1318         checkWMTE(() -> { // receiver primitive class
1319             vh.set(0, 0, "foo");
1320         });
1321         checkWMTE(() -> { // index reference class
1322             vh.set(array, Void.class, "foo");
1323         });
1324         // Incorrect arity
1325         checkWMTE(() -> { // 0
1326             vh.set();
1327         });
1328         checkWMTE(() -> { // >
1329             vh.set(array, 0, "foo", Void.class);
1330         });
1331 
1332 
1333         // GetVolatile
1334         // Incorrect argument types
1335         checkNPE(() -> { // null array
1336             String x = (String) vh.getVolatile(null, 0);
1337         });
1338         checkCCE(() -> { // array reference class
1339             String x = (String) vh.getVolatile(Void.class, 0);
1340         });
1341         checkWMTE(() -> { // array primitive class
1342             String x = (String) vh.getVolatile(0, 0);
1343         });
1344         checkWMTE(() -> { // index reference class
1345             String x = (String) vh.getVolatile(array, Void.class);
1346         });
1347         // Incorrect return type
1348         checkCCE(() -> { // reference class
1349             Void x = (Void) vh.getVolatile(array, 0);
1350         });
1351         checkWMTE(() -> { // primitive class
1352             boolean x = (boolean) vh.getVolatile(array, 0);
1353         });
1354         // Incorrect arity
1355         checkWMTE(() -> { // 0
1356             String x = (String) vh.getVolatile();
1357         });
1358         checkWMTE(() -> { // >
1359             String x = (String) vh.getVolatile(array, 0, Void.class);
1360         });
1361 
1362 
1363         // SetVolatile
1364         // Incorrect argument types
1365         checkNPE(() -> { // null array
1366             vh.setVolatile(null, 0, "foo");
1367         });
1368         checkCCE(() -> { // array reference class
1369             vh.setVolatile(Void.class, 0, "foo");
1370         });
1371         checkCCE(() -> { // value reference class
1372             vh.setVolatile(array, 0, Void.class);
1373         });
1374         checkWMTE(() -> { // receiver primitive class
1375             vh.setVolatile(0, 0, "foo");
1376         });
1377         checkWMTE(() -> { // index reference class
1378             vh.setVolatile(array, Void.class, "foo");
1379         });
1380         // Incorrect arity
1381         checkWMTE(() -> { // 0
1382             vh.setVolatile();
1383         });
1384         checkWMTE(() -> { // >
1385             vh.setVolatile(array, 0, "foo", Void.class);
1386         });
1387 
1388 
1389         // GetOpaque
1390         // Incorrect argument types
1391         checkNPE(() -> { // null array
1392             String x = (String) vh.getOpaque(null, 0);
1393         });
1394         checkCCE(() -> { // array reference class
1395             String x = (String) vh.getOpaque(Void.class, 0);
1396         });
1397         checkWMTE(() -> { // array primitive class
1398             String x = (String) vh.getOpaque(0, 0);
1399         });
1400         checkWMTE(() -> { // index reference class
1401             String x = (String) vh.getOpaque(array, Void.class);
1402         });
1403         // Incorrect return type
1404         checkCCE(() -> { // reference class
1405             Void x = (Void) vh.getOpaque(array, 0);
1406         });
1407         checkWMTE(() -> { // primitive class
1408             boolean x = (boolean) vh.getOpaque(array, 0);
1409         });
1410         // Incorrect arity
1411         checkWMTE(() -> { // 0
1412             String x = (String) vh.getOpaque();
1413         });
1414         checkWMTE(() -> { // >
1415             String x = (String) vh.getOpaque(array, 0, Void.class);
1416         });
1417 
1418 
1419         // SetOpaque
1420         // Incorrect argument types
1421         checkNPE(() -> { // null array
1422             vh.setOpaque(null, 0, "foo");
1423         });
1424         checkCCE(() -> { // array reference class
1425             vh.setOpaque(Void.class, 0, "foo");
1426         });
1427         checkCCE(() -> { // value reference class
1428             vh.setOpaque(array, 0, Void.class);
1429         });
1430         checkWMTE(() -> { // receiver primitive class
1431             vh.setOpaque(0, 0, "foo");
1432         });
1433         checkWMTE(() -> { // index reference class
1434             vh.setOpaque(array, Void.class, "foo");
1435         });
1436         // Incorrect arity
1437         checkWMTE(() -> { // 0
1438             vh.setOpaque();
1439         });
1440         checkWMTE(() -> { // >
1441             vh.setOpaque(array, 0, "foo", Void.class);
1442         });
1443 
1444 
1445         // GetAcquire
1446         // Incorrect argument types
1447         checkNPE(() -> { // null array
1448             String x = (String) vh.getAcquire(null, 0);
1449         });
1450         checkCCE(() -> { // array reference class
1451             String x = (String) vh.getAcquire(Void.class, 0);
1452         });
1453         checkWMTE(() -> { // array primitive class
1454             String x = (String) vh.getAcquire(0, 0);
1455         });
1456         checkWMTE(() -> { // index reference class
1457             String x = (String) vh.getAcquire(array, Void.class);
1458         });
1459         // Incorrect return type
1460         checkCCE(() -> { // reference class
1461             Void x = (Void) vh.getAcquire(array, 0);
1462         });
1463         checkWMTE(() -> { // primitive class
1464             boolean x = (boolean) vh.getAcquire(array, 0);
1465         });
1466         // Incorrect arity
1467         checkWMTE(() -> { // 0
1468             String x = (String) vh.getAcquire();
1469         });
1470         checkWMTE(() -> { // >
1471             String x = (String) vh.getAcquire(array, 0, Void.class);
1472         });
1473 
1474 
1475         // SetRelease
1476         // Incorrect argument types
1477         checkNPE(() -> { // null array
1478             vh.setRelease(null, 0, "foo");
1479         });
1480         checkCCE(() -> { // array reference class
1481             vh.setRelease(Void.class, 0, "foo");
1482         });
1483         checkCCE(() -> { // value reference class
1484             vh.setRelease(array, 0, Void.class);
1485         });
1486         checkWMTE(() -> { // receiver primitive class
1487             vh.setRelease(0, 0, "foo");
1488         });
1489         checkWMTE(() -> { // index reference class
1490             vh.setRelease(array, Void.class, "foo");
1491         });
1492         // Incorrect arity
1493         checkWMTE(() -> { // 0
1494             vh.setRelease();
1495         });
1496         checkWMTE(() -> { // >
1497             vh.setRelease(array, 0, "foo", Void.class);
1498         });
1499 
1500 
1501         // CompareAndSet
1502         // Incorrect argument types
1503         checkNPE(() -> { // null receiver
1504             boolean r = vh.compareAndSet(null, 0, "foo", "foo");
1505         });
1506         checkCCE(() -> { // receiver reference class
1507             boolean r = vh.compareAndSet(Void.class, 0, "foo", "foo");
1508         });
1509         checkCCE(() -> { // expected reference class
1510             boolean r = vh.compareAndSet(array, 0, Void.class, "foo");
1511         });
1512         checkCCE(() -> { // actual reference class
1513             boolean r = vh.compareAndSet(array, 0, "foo", Void.class);
1514         });
1515         checkWMTE(() -> { // receiver primitive class
1516             boolean r = vh.compareAndSet(0, 0, "foo", "foo");
1517         });
1518         checkWMTE(() -> { // index reference class
1519             boolean r = vh.compareAndSet(array, Void.class, "foo", "foo");
1520         });
1521         // Incorrect arity
1522         checkWMTE(() -> { // 0
1523             boolean r = vh.compareAndSet();
1524         });
1525         checkWMTE(() -> { // >
1526             boolean r = vh.compareAndSet(array, 0, "foo", "foo", Void.class);
1527         });
1528 
1529 
1530         // WeakCompareAndSet
1531         // Incorrect argument types
1532         checkNPE(() -> { // null receiver
1533             boolean r = vh.weakCompareAndSetPlain(null, 0, "foo", "foo");
1534         });
1535         checkCCE(() -> { // receiver reference class
1536             boolean r = vh.weakCompareAndSetPlain(Void.class, 0, "foo", "foo");
1537         });
1538         checkCCE(() -> { // expected reference class
1539             boolean r = vh.weakCompareAndSetPlain(array, 0, Void.class, "foo");
1540         });
1541         checkCCE(() -> { // actual reference class
1542             boolean r = vh.weakCompareAndSetPlain(array, 0, "foo", Void.class);
1543         });
1544         checkWMTE(() -> { // receiver primitive class
1545             boolean r = vh.weakCompareAndSetPlain(0, 0, "foo", "foo");
1546         });
1547         checkWMTE(() -> { // index reference class
1548             boolean r = vh.weakCompareAndSetPlain(array, Void.class, "foo", "foo");
1549         });
1550         // Incorrect arity
1551         checkWMTE(() -> { // 0
1552             boolean r = vh.weakCompareAndSetPlain();
1553         });
1554         checkWMTE(() -> { // >
1555             boolean r = vh.weakCompareAndSetPlain(array, 0, "foo", "foo", Void.class);
1556         });
1557 
1558 
1559         // WeakCompareAndSetVolatile
1560         // Incorrect argument types
1561         checkNPE(() -> { // null receiver
1562             boolean r = vh.weakCompareAndSet(null, 0, "foo", "foo");
1563         });
1564         checkCCE(() -> { // receiver reference class
1565             boolean r = vh.weakCompareAndSet(Void.class, 0, "foo", "foo");
1566         });
1567         checkCCE(() -> { // expected reference class
1568             boolean r = vh.weakCompareAndSet(array, 0, Void.class, "foo");
1569         });
1570         checkCCE(() -> { // actual reference class
1571             boolean r = vh.weakCompareAndSet(array, 0, "foo", Void.class);
1572         });
1573         checkWMTE(() -> { // receiver primitive class
1574             boolean r = vh.weakCompareAndSet(0, 0, "foo", "foo");
1575         });
1576         checkWMTE(() -> { // index reference class
1577             boolean r = vh.weakCompareAndSet(array, Void.class, "foo", "foo");
1578         });
1579         // Incorrect arity
1580         checkWMTE(() -> { // 0
1581             boolean r = vh.weakCompareAndSet();
1582         });
1583         checkWMTE(() -> { // >
1584             boolean r = vh.weakCompareAndSet(array, 0, "foo", "foo", Void.class);
1585         });
1586 
1587 
1588         // WeakCompareAndSetAcquire
1589         // Incorrect argument types
1590         checkNPE(() -> { // null receiver
1591             boolean r = vh.weakCompareAndSetAcquire(null, 0, "foo", "foo");
1592         });
1593         checkCCE(() -> { // receiver reference class
1594             boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, "foo", "foo");
1595         });
1596         checkCCE(() -> { // expected reference class
1597             boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, "foo");
1598         });
1599         checkCCE(() -> { // actual reference class
1600             boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", Void.class);
1601         });
1602         checkWMTE(() -> { // receiver primitive class
1603             boolean r = vh.weakCompareAndSetAcquire(0, 0, "foo", "foo");
1604         });
1605         checkWMTE(() -> { // index reference class
1606             boolean r = vh.weakCompareAndSetAcquire(array, Void.class, "foo", "foo");
1607         });
1608         // Incorrect arity
1609         checkWMTE(() -> { // 0
1610             boolean r = vh.weakCompareAndSetAcquire();
1611         });
1612         checkWMTE(() -> { // >
1613             boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", "foo", Void.class);
1614         });
1615 
1616 
1617         // WeakCompareAndSetRelease
1618         // Incorrect argument types
1619         checkNPE(() -> { // null receiver
1620             boolean r = vh.weakCompareAndSetRelease(null, 0, "foo", "foo");
1621         });
1622         checkCCE(() -> { // receiver reference class
1623             boolean r = vh.weakCompareAndSetRelease(Void.class, 0, "foo", "foo");
1624         });
1625         checkCCE(() -> { // expected reference class
1626             boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, "foo");
1627         });
1628         checkCCE(() -> { // actual reference class
1629             boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", Void.class);
1630         });
1631         checkWMTE(() -> { // receiver primitive class
1632             boolean r = vh.weakCompareAndSetRelease(0, 0, "foo", "foo");
1633         });
1634         checkWMTE(() -> { // index reference class
1635             boolean r = vh.weakCompareAndSetRelease(array, Void.class, "foo", "foo");
1636         });
1637         // Incorrect arity
1638         checkWMTE(() -> { // 0
1639             boolean r = vh.weakCompareAndSetRelease();
1640         });
1641         checkWMTE(() -> { // >
1642             boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", "foo", Void.class);
1643         });
1644 
1645 
1646         // CompareAndExchange
1647         // Incorrect argument types
1648         checkNPE(() -> { // null receiver
1649             String x = (String) vh.compareAndExchange(null, 0, "foo", "foo");
1650         });
1651         checkCCE(() -> { // array reference class
1652             String x = (String) vh.compareAndExchange(Void.class, 0, "foo", "foo");
1653         });
1654         checkCCE(() -> { // expected reference class
1655             String x = (String) vh.compareAndExchange(array, 0, Void.class, "foo");
1656         });
1657         checkCCE(() -> { // actual reference class
1658             String x = (String) vh.compareAndExchange(array, 0, "foo", Void.class);
1659         });
1660         checkWMTE(() -> { // array primitive class
1661             String x = (String) vh.compareAndExchange(0, 0, "foo", "foo");
1662         });
1663         checkWMTE(() -> { // index reference class
1664             String x = (String) vh.compareAndExchange(array, Void.class, "foo", "foo");
1665         });
1666         // Incorrect return type
1667         checkCCE(() -> { // reference class
1668             Void r = (Void) vh.compareAndExchange(array, 0, "foo", "foo");
1669         });
1670         checkWMTE(() -> { // primitive class
1671             boolean x = (boolean) vh.compareAndExchange(array, 0, "foo", "foo");
1672         });
1673         // Incorrect arity
1674         checkWMTE(() -> { // 0
1675             String x = (String) vh.compareAndExchange();
1676         });
1677         checkWMTE(() -> { // >
1678             String x = (String) vh.compareAndExchange(array, 0, "foo", "foo", Void.class);
1679         });
1680 
1681 
1682         // CompareAndExchangeAcquire
1683         // Incorrect argument types
1684         checkNPE(() -> { // null receiver
1685             String x = (String) vh.compareAndExchangeAcquire(null, 0, "foo", "foo");
1686         });
1687         checkCCE(() -> { // array reference class
1688             String x = (String) vh.compareAndExchangeAcquire(Void.class, 0, "foo", "foo");
1689         });
1690         checkCCE(() -> { // expected reference class
1691             String x = (String) vh.compareAndExchangeAcquire(array, 0, Void.class, "foo");
1692         });
1693         checkCCE(() -> { // actual reference class
1694             String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", Void.class);
1695         });
1696         checkWMTE(() -> { // array primitive class
1697             String x = (String) vh.compareAndExchangeAcquire(0, 0, "foo", "foo");
1698         });
1699         checkWMTE(() -> { // index reference class
1700             String x = (String) vh.compareAndExchangeAcquire(array, Void.class, "foo", "foo");
1701         });
1702         // Incorrect return type
1703         checkCCE(() -> { // reference class
1704             Void r = (Void) vh.compareAndExchangeAcquire(array, 0, "foo", "foo");
1705         });
1706         checkWMTE(() -> { // primitive class
1707             boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, "foo", "foo");
1708         });
1709         // Incorrect arity
1710         checkWMTE(() -> { // 0
1711             String x = (String) vh.compareAndExchangeAcquire();
1712         });
1713         checkWMTE(() -> { // >
1714             String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", "foo", Void.class);
1715         });
1716 
1717 
1718         // CompareAndExchangeRelease
1719         // Incorrect argument types
1720         checkNPE(() -> { // null receiver
1721             String x = (String) vh.compareAndExchangeRelease(null, 0, "foo", "foo");
1722         });
1723         checkCCE(() -> { // array reference class
1724             String x = (String) vh.compareAndExchangeRelease(Void.class, 0, "foo", "foo");
1725         });
1726         checkCCE(() -> { // expected reference class
1727             String x = (String) vh.compareAndExchangeRelease(array, 0, Void.class, "foo");
1728         });
1729         checkCCE(() -> { // actual reference class
1730             String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", Void.class);
1731         });
1732         checkWMTE(() -> { // array primitive class
1733             String x = (String) vh.compareAndExchangeRelease(0, 0, "foo", "foo");
1734         });
1735         checkWMTE(() -> { // index reference class
1736             String x = (String) vh.compareAndExchangeRelease(array, Void.class, "foo", "foo");
1737         });
1738         // Incorrect return type
1739         checkCCE(() -> { // reference class
1740             Void r = (Void) vh.compareAndExchangeRelease(array, 0, "foo", "foo");
1741         });
1742         checkWMTE(() -> { // primitive class
1743             boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, "foo", "foo");
1744         });
1745         // Incorrect arity
1746         checkWMTE(() -> { // 0
1747             String x = (String) vh.compareAndExchangeRelease();
1748         });
1749         checkWMTE(() -> { // >
1750             String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", "foo", Void.class);
1751         });
1752 
1753 
1754         // GetAndSet
1755         // Incorrect argument types
1756         checkNPE(() -> { // null array
1757             String x = (String) vh.getAndSet(null, 0, "foo");
1758         });
1759         checkCCE(() -> { // array reference class
1760             String x = (String) vh.getAndSet(Void.class, 0, "foo");
1761         });
1762         checkCCE(() -> { // value reference class
1763             String x = (String) vh.getAndSet(array, 0, Void.class);
1764         });
1765         checkWMTE(() -> { // reciarrayever primitive class
1766             String x = (String) vh.getAndSet(0, 0, "foo");
1767         });
1768         checkWMTE(() -> { // index reference class
1769             String x = (String) vh.getAndSet(array, Void.class, "foo");
1770         });
1771         // Incorrect return type
1772         checkCCE(() -> { // reference class
1773             Void r = (Void) vh.getAndSet(array, 0, "foo");
1774         });
1775         checkWMTE(() -> { // primitive class
1776             boolean x = (boolean) vh.getAndSet(array, 0, "foo");
1777         });
1778         // Incorrect arity
1779         checkWMTE(() -> { // 0
1780             String x = (String) vh.getAndSet();
1781         });
1782         checkWMTE(() -> { // >
1783             String x = (String) vh.getAndSet(array, 0, "foo", Void.class);
1784         });
1785 
1786 
1787         // GetAndSetAcquire
1788         // Incorrect argument types
1789         checkNPE(() -> { // null array
1790             String x = (String) vh.getAndSetAcquire(null, 0, "foo");
1791         });
1792         checkCCE(() -> { // array reference class
1793             String x = (String) vh.getAndSetAcquire(Void.class, 0, "foo");
1794         });
1795         checkCCE(() -> { // value reference class
1796             String x = (String) vh.getAndSetAcquire(array, 0, Void.class);
1797         });
1798         checkWMTE(() -> { // reciarrayever primitive class
1799             String x = (String) vh.getAndSetAcquire(0, 0, "foo");
1800         });
1801         checkWMTE(() -> { // index reference class
1802             String x = (String) vh.getAndSetAcquire(array, Void.class, "foo");
1803         });
1804         // Incorrect return type
1805         checkCCE(() -> { // reference class
1806             Void r = (Void) vh.getAndSetAcquire(array, 0, "foo");
1807         });
1808         checkWMTE(() -> { // primitive class
1809             boolean x = (boolean) vh.getAndSetAcquire(array, 0, "foo");
1810         });
1811         // Incorrect arity
1812         checkWMTE(() -> { // 0
1813             String x = (String) vh.getAndSetAcquire();
1814         });
1815         checkWMTE(() -> { // >
1816             String x = (String) vh.getAndSetAcquire(array, 0, "foo", Void.class);
1817         });
1818 
1819 
1820         // GetAndSetRelease
1821         // Incorrect argument types
1822         checkNPE(() -> { // null array
1823             String x = (String) vh.getAndSetRelease(null, 0, "foo");
1824         });
1825         checkCCE(() -> { // array reference class
1826             String x = (String) vh.getAndSetRelease(Void.class, 0, "foo");
1827         });
1828         checkCCE(() -> { // value reference class
1829             String x = (String) vh.getAndSetRelease(array, 0, Void.class);
1830         });
1831         checkWMTE(() -> { // reciarrayever primitive class
1832             String x = (String) vh.getAndSetRelease(0, 0, "foo");
1833         });
1834         checkWMTE(() -> { // index reference class
1835             String x = (String) vh.getAndSetRelease(array, Void.class, "foo");
1836         });
1837         // Incorrect return type
1838         checkCCE(() -> { // reference class
1839             Void r = (Void) vh.getAndSetRelease(array, 0, "foo");
1840         });
1841         checkWMTE(() -> { // primitive class
1842             boolean x = (boolean) vh.getAndSetRelease(array, 0, "foo");
1843         });
1844         // Incorrect arity
1845         checkWMTE(() -> { // 0
1846             String x = (String) vh.getAndSetRelease();
1847         });
1848         checkWMTE(() -> { // >
1849             String x = (String) vh.getAndSetRelease(array, 0, "foo", Void.class);
1850         });
1851 
1852 
1853     }
1854 
1855     static void testArrayWrongMethodType(Handles hs) throws Throwable {
1856         String[] array = new String[10];
1857         Arrays.fill(array, "foo");
1858 
1859         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
1860             // Incorrect argument types
1861             checkNPE(() -> { // null array
1862                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class)).
1863                     invokeExact((String[]) null, 0);
1864             });
1865             hs.checkWMTEOrCCE(() -> { // array reference class
1866                 String x = (String) hs.get(am, methodType(String.class, Class.class, int.class)).
1867                     invokeExact(Void.class, 0);
1868             });
1869             checkWMTE(() -> { // array primitive class
1870                 String x = (String) hs.get(am, methodType(String.class, int.class, int.class)).
1871                     invokeExact(0, 0);
1872             });
1873             checkWMTE(() -> { // index reference class
1874                 String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class)).
1875                     invokeExact(array, Void.class);
1876             });
1877             // Incorrect return type
1878             hs.checkWMTEOrCCE(() -> { // reference class
1879                 Void x = (Void) hs.get(am, methodType(Void.class, String[].class, int.class)).
1880                     invokeExact(array, 0);
1881             });
1882             checkWMTE(() -> { // primitive class
1883                 boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class)).
1884                     invokeExact(array, 0);
1885             });
1886             // Incorrect arity
1887             checkWMTE(() -> { // 0
1888                 String x = (String) hs.get(am, methodType(String.class)).
1889                     invokeExact();
1890             });
1891             checkWMTE(() -> { // >
1892                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)).
1893                     invokeExact(array, 0, Void.class);
1894             });
1895         }
1896 
1897         for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
1898             // Incorrect argument types
1899             checkNPE(() -> { // null array
1900                 hs.get(am, methodType(void.class, String[].class, int.class, String.class)).
1901                     invokeExact((String[]) null, 0, "foo");
1902             });
1903             hs.checkWMTEOrCCE(() -> { // array reference class
1904                 hs.get(am, methodType(void.class, Class.class, int.class, String.class)).
1905                     invokeExact(Void.class, 0, "foo");
1906             });
1907             hs.checkWMTEOrCCE(() -> { // value reference class
1908                 hs.get(am, methodType(void.class, String[].class, int.class, Class.class)).
1909                     invokeExact(array, 0, Void.class);
1910             });
1911             checkWMTE(() -> { // receiver primitive class
1912                 hs.get(am, methodType(void.class, int.class, int.class, String.class)).
1913                     invokeExact(0, 0, "foo");
1914             });
1915             checkWMTE(() -> { // index reference class
1916                 hs.get(am, methodType(void.class, String[].class, Class.class, String.class)).
1917                     invokeExact(array, Void.class, "foo");
1918             });
1919             // Incorrect arity
1920             checkWMTE(() -> { // 0
1921                 hs.get(am, methodType(void.class)).
1922                     invokeExact();
1923             });
1924             checkWMTE(() -> { // >
1925                 hs.get(am, methodType(void.class, String[].class, int.class, Class.class)).
1926                     invokeExact(array, 0, "foo", Void.class);
1927             });
1928         }
1929         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
1930             // Incorrect argument types
1931             checkNPE(() -> { // null receiver
1932                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class)).
1933                     invokeExact((String[]) null, 0, "foo", "foo");
1934             });
1935             hs.checkWMTEOrCCE(() -> { // receiver reference class
1936                 boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, String.class, String.class)).
1937                     invokeExact(Void.class, 0, "foo", "foo");
1938             });
1939             hs.checkWMTEOrCCE(() -> { // expected reference class
1940                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, Class.class, String.class)).
1941                     invokeExact(array, 0, Void.class, "foo");
1942             });
1943             hs.checkWMTEOrCCE(() -> { // actual reference class
1944                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, Class.class)).
1945                     invokeExact(array, 0, "foo", Void.class);
1946             });
1947             checkWMTE(() -> { // receiver primitive class
1948                 boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, String.class, String.class)).
1949                     invokeExact(0, 0, "foo", "foo");
1950             });
1951             checkWMTE(() -> { // index reference class
1952                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, Class.class, String.class, String.class)).
1953                     invokeExact(array, Void.class, "foo", "foo");
1954             });
1955             // Incorrect arity
1956             checkWMTE(() -> { // 0
1957                 boolean r = (boolean) hs.get(am, methodType(boolean.class)).
1958                     invokeExact();
1959             });
1960             checkWMTE(() -> { // >
1961                 boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class, Class.class)).
1962                     invokeExact(array, 0, "foo", "foo", Void.class);
1963             });
1964         }
1965 
1966         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
1967             // Incorrect argument types
1968             checkNPE(() -> { // null receiver
1969                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, String.class)).
1970                     invokeExact((String[]) null, 0, "foo", "foo");
1971             });
1972             hs.checkWMTEOrCCE(() -> { // array reference class
1973                 String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class, String.class)).
1974                     invokeExact(Void.class, 0, "foo", "foo");
1975             });
1976             hs.checkWMTEOrCCE(() -> { // expected reference class
1977                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class, String.class)).
1978                     invokeExact(array, 0, Void.class, "foo");
1979             });
1980             hs.checkWMTEOrCCE(() -> { // actual reference class
1981                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)).
1982                     invokeExact(array, 0, "foo", Void.class);
1983             });
1984             checkWMTE(() -> { // array primitive class
1985                 String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class, String.class)).
1986                     invokeExact(0, 0, "foo", "foo");
1987             });
1988             checkWMTE(() -> { // index reference class
1989                 String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class, String.class)).
1990                     invokeExact(array, Void.class, "foo", "foo");
1991             });
1992             // Incorrect return type
1993             hs.checkWMTEOrCCE(() -> { // reference class
1994                 Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class, String.class)).
1995                     invokeExact(array, 0, "foo", "foo");
1996             });
1997             checkWMTE(() -> { // primitive class
1998                 boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class)).
1999                     invokeExact(array, 0, "foo", "foo");
2000             });
2001             // Incorrect arity
2002             checkWMTE(() -> { // 0
2003                 String x = (String) hs.get(am, methodType(String.class)).
2004                     invokeExact();
2005             });
2006             checkWMTE(() -> { // >
2007                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, String.class, Class.class)).
2008                     invokeExact(array, 0, "foo", "foo", Void.class);
2009             });
2010         }
2011 
2012         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
2013             // Incorrect argument types
2014             checkNPE(() -> { // null array
2015                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class)).
2016                     invokeExact((String[]) null, 0, "foo");
2017             });
2018             hs.checkWMTEOrCCE(() -> { // array reference class
2019                 String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class)).
2020                     invokeExact(Void.class, 0, "foo");
2021             });
2022             hs.checkWMTEOrCCE(() -> { // value reference class
2023                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)).
2024                     invokeExact(array, 0, Void.class);
2025             });
2026             checkWMTE(() -> { // array primitive class
2027                 String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class)).
2028                     invokeExact(0, 0, "foo");
2029             });
2030             checkWMTE(() -> { // index reference class
2031                 String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class)).
2032                     invokeExact(array, Void.class, "foo");
2033             });
2034             // Incorrect return type
2035             hs.checkWMTEOrCCE(() -> { // reference class
2036                 Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class)).
2037                     invokeExact(array, 0, "foo");
2038             });
2039             checkWMTE(() -> { // primitive class
2040                 boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class)).
2041                     invokeExact(array, 0, "foo");
2042             });
2043             // Incorrect arity
2044             checkWMTE(() -> { // 0
2045                 String x = (String) hs.get(am, methodType(String.class)).
2046                     invokeExact();
2047             });
2048             checkWMTE(() -> { // >
2049                 String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)).
2050                     invokeExact(array, 0, "foo", Void.class);
2051             });
2052         }
2053 
2054 
2055     }
2056 }