MethodParameters class reading bug

Jan Lahoda jan.lahoda at oracle.com
Fri Dec 2 13:31:52 UTC 2016


Hi Liam,

Thanks for the report and patch, I've filled:
https://bugs.openjdk.java.net/browse/JDK-8170667

I think you are right about the problem, and the fix seems very 
reasonable to me.

Jan

On 2.12.2016 03:09, Liam Miller-Cushon wrote:
> I think I found a MethodParameters class reading bug that affects
> annotation processing.
>
> If MethodParameters attributes are not available parameter names are
> inferred from the LVT, which uses two slots for doubles and longs. The
> logic for skipping the extra slot is used even if the data was read from
> a MethodParameters attribute, where the indices are always contiguous.
> So if javac sees a parameter of type double or long it skips the next
> entry in the MethodParameters table.
>
> There's a simple fix:
>
> diff -r 775a385c4af6
> src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java
> ---
> a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.javaThu
> Dec 01 17:25:45 2016 -0800
> +++
> b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.javaThu
> Dec 01 18:05:14 2016 -0800
> @@ -2321,7 +2321,7 @@
>                       ? parameterNameIndices[index] : 0);
>               Name name = nameIdx == 0 ? names.empty : readName(nameIdx);
>               paramNames = paramNames.prepend(name);
> -            index += Code.width(t);
> +            index += sawMethodParameters ? 1 : Code.width(t);
>           }
>           sym.savedParameterNames = paramNames.reverse();
>       }
>
> If my diagnosis sounds correct, I can clean up the patch and add a test.
>
> Here's the full repro:
>
> === Lib.java
> class Lib {
>    void f(int a, long b, int c, int d) {}
> }
> === Test.java
> @Deprecated
> class Test {}
> === ParameterProcessor.java
> import java.util.Set;
> import javax.annotation.processing.*;
> import javax.lang.model.SourceVersion;
> import javax.lang.model.element.*;
>
> @SupportedAnnotationTypes("*")
> public class ParameterProcessor extends AbstractProcessor {
>    @Override
>    public boolean process(Set<? extends TypeElement> annotations,
> RoundEnvironment roundEnv) {
>      if (roundEnv.processingOver()) {
>        return false;
>      }
>      TypeElement s = processingEnv.getElementUtils().getTypeElement("Lib");
>      for (Element e : s.getEnclosedElements()) {
>        if (e instanceof ExecutableElement) {
>          for (VariableElement v : ((ExecutableElement) e).getParameters()) {
>            System.err.printf("  %s %s\n", v.asType(), v.getSimpleName());
>          }
>        }
>      }
>      return false;
>    }
>
>    @Override
>    public SourceVersion getSupportedSourceVersion() {
>      return SourceVersion.latest();
>    }
> }
>
> $ javac -parameters Lib.java
> $ javac ParameterProcessor.java
> $ javac -processor ParameterProcessor Test.java
>    int a
>    long b
>    int d
>    int arg3
>
> Note that the third parameter is given the fourth parameter's name, and
> the fourth parameter's name is unknown.
>
> Thanks,
>
> Liam


More information about the compiler-dev mailing list