diff --git a/src/java_tools/import_deps_checker/java/com/google/devtools/build/importdeps/DepsCheckerClassVisitor.java b/src/java_tools/import_deps_checker/java/com/google/devtools/build/importdeps/DepsCheckerClassVisitor.java index c941053337f1bf..bd5f31712fc486 100644 --- a/src/java_tools/import_deps_checker/java/com/google/devtools/build/importdeps/DepsCheckerClassVisitor.java +++ b/src/java_tools/import_deps_checker/java/com/google/devtools/build/importdeps/DepsCheckerClassVisitor.java @@ -340,7 +340,7 @@ public void visitFieldInsn(int opcode, String owner, String name, String desc) { @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { - if (!isMethodHandle(opcode, owner, name)) { + if (!isMethodHandle(opcode, owner, name) && !isVarHandle(opcode, owner, name)) { checkMember(owner, name, desc); } super.visitMethodInsn(opcode, owner, name, desc, itf); @@ -363,6 +363,52 @@ private boolean isMethodHandle(int opcode, String owner, String name) { return true; } + private boolean isVarHandle(int opcode, String owner, String name) { + if (opcode != Opcodes.INVOKEVIRTUAL) { + return false; + } + if (!owner.equals("java/lang/invoke/VarHandle")) { + return false; + } + switch (name) { + case "compareAndExchange": + case "compareAndExchangeAcquire": + case "compareAndExchangeRelease": + case "compareAndSet": + case "get": + case "getAcquire": + case "getAndAdd": + case "getAndAddAcquire": + case "getAndAddRelease": + case "getAndBitwiseAnd": + case "getAndBitwiseAndAcquire": + case "getAndBitwiseAndRelease": + case "getAndBitwiseOr": + case "getAndBitwiseOrAcquire": + case "getAndBitwiseOrRelease": + case "getAndBitwiseXor": + case "getAndBitwiseXorAcquire": + case "getAndBitwiseXorRelease": + case "getAndSet": + case "getAndSetAcquire": + case "getAndSetRelease": + case "getOpaque": + case "getVolatile": + case "set": + case "setOpaque": + case "setRelease": + case "setVolatile": + case "weakCompareAndSet": + case "weakCompareAndSetAcquire": + case "weakCompareAndSetPlain": + case "weakCompareAndSetRelease": + break; + default: + return false; + } + return true; + } + @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { checkDescriptor(desc); diff --git a/src/java_tools/import_deps_checker/javatests/com/google/devtools/build/importdeps/testdata/InvokePolymorphic.java b/src/java_tools/import_deps_checker/javatests/com/google/devtools/build/importdeps/testdata/InvokePolymorphic.java index 14665ae64a87b6..020faa853ac795 100644 --- a/src/java_tools/import_deps_checker/javatests/com/google/devtools/build/importdeps/testdata/InvokePolymorphic.java +++ b/src/java_tools/import_deps_checker/javatests/com/google/devtools/build/importdeps/testdata/InvokePolymorphic.java @@ -15,9 +15,11 @@ package com.google.devtools.build.importdeps.testdata; import java.lang.invoke.MethodHandle; +import java.lang.invoke.VarHandle; public class InvokePolymorphic { - void f(MethodHandle mh) throws Throwable { + void f(MethodHandle mh, VarHandle vh) throws Throwable { mh.invoke(true, "hello", 42); + vh.setRelease("foo", 1); } }