RFR 8170667: ClassReader assigns method parameters from MethodParameters incorrectly when long/double parameters are present
Vicente Romero
vicente.romero at oracle.com
Fri Dec 9 17:48:52 UTC 2016
On 12/09/2016 12:13 PM, Jan Lahoda wrote:
> Thanks Liam, Vicente!
>
> Pushed:
> http://hg.openjdk.java.net/jdk9/dev/langtools/rev/5d43af61155b
>
> Jan
thank you,
Vicente
>
> On 7.12.2016 21:10, Liam Miller-Cushon wrote:
>> Thanks for the review! I moved the entire test into one file, and fixed
>> the style issues.
>>
>> On Mon, Dec 5, 2016 at 3:36 PM, Vicente Romero
>> <vicente.romero at oracle.com <mailto:vicente.romero at oracle.com>> wrote:
>>
>> Hi Liam,
>>
>> Thanks for the patch. It's probably a question of style but it seems
>> to me like the number of classes used could be reduced. For example,
>> the annotation processor could define the annotated methods that it
>> will later discover and process. This is just a suggestion. Also
>> regarding indentation, it's preferable to use 4 spaces instead of 2.
>>
>> Thanks,
>> Vicente
>>
>>
>> On 12/02/2016 11:41 AM, Liam Miller-Cushon wrote:
>>> Thanks Jan, I've attached the full patch with a test.
>>>
>>> On Fri, Dec 2, 2016 at 5:31 AM, Jan Lahoda <jan.lahoda at oracle.com
>>> <mailto:jan.lahoda at oracle.com>> wrote:
>>>
>>> Hi Liam,
>>>
>>> Thanks for the report and patch, I've filled:
>>> https://bugs.openjdk.java.net/browse/JDK-8170667
>>> <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