javac 9: Tainting Test

40 views
Skip to first unread message

Ravi Roshan

unread,
Jun 11, 2018, 5:30:31 PM6/11/18
to Werner Dietl, Checker Framework GSOC, Jeff Yucong Luo
Hi Werner, Jeff,
I was working on the errors in Tainting test. The error was :
1 expected diagnostic was not found:
Issue1111.java:15: error: (argument.type.incompatible)
2 unexpected diagnostics were found:
Issue1942.java:14: error: (override.param.invalid)
:-1: other: error: AsSuperVisitor: type is not an erased subtype of supertype.
  type: @Untainted Object
  superType: @Tainted Integer
  Compilation unit: tests/tainting/Issue1111.java
I think the error is in the use of the function isSameType() at line 245 of AsSuperVisitor.java :
return types.isSameType(underlyingTypeA, underlyingTypeB);
I did make some changes there but was not able to solve the issue. I am currently looking indepth into the code of AsSuperVisitor.java and also looking into similar errors while running other tests.
Regards,
Ravi

Werner Dietl

unread,
Jun 11, 2018, 8:58:01 PM6/11/18
to Ravi Roshan, Checker Framework GSOC, Jeff Yucong Luo

Hi Ravi,


thanks for the update!

Did you minimize the failure in tests/tainting/Issue1111.java ?

Why do you think it is caused by isSameType?

Did you make progress in comparing javac 8 vs javac 9 executions?

Did the list of steps to follow for debugging help?


BTW, I fixed one of the other exceptions that kept occurring in the Nullness Checker tests:


https://github.com/eisop/checker-framework/commit/2fce5fb0018a4a10f21b614da46553d8ef374018

Best,

cu, WMD.



From: Ravi Roshan <rrosh...@gmail.com>
Sent: Monday, June 11, 2018 5:30:18 PM
To: Werner Dietl
Cc: Checker Framework GSOC; Jeff Yucong Luo
Subject: javac 9: Tainting Test
 

Ravi Roshan

unread,
Jun 13, 2018, 1:29:32 PM6/13/18
to Checker Framework GSOC


---------- Forwarded message ---------
From: Ravi Roshan <rrosh...@gmail.com>
Date: Wed, Jun 13, 2018 at 7:22 PM
Subject: Re: javac 9: Tainting Test
To: Werner Dietl <werner...@uwaterloo.ca>
Cc: Jeff Yucong Luo <jeff...@uwaterloo.ca>


Hi Werner,
Sorry for the late reply. There was a mistake in the previous error reported by me. I had failed to check the arguments being passed to isSameType() in :
return types.isSameType(underlyingTypeA, underlyingTypeB);
They were infact : 
underlyingTypeA : java.lang.Object
underlyingTypeB : java.lang.Integer
In java8 execution, there was never a case were they were different or when underlyingTypeA was not a subtype of underlyingTypeB.
So, I think isSameType() was supposed to give an error. When I traced back the call to the function using stacktrace and added a print statement in BaseTypeVisitor.java : 
public boolean validateTypeOf(Tree tree) {
        AnnotatedTypeMirror type;
        // It's quite annoying that there is no TypeTree.
        switch (tree.getKind()) {
            case PRIMITIVE_TYPE:
            case PARAMETERIZED_TYPE:
            case TYPE_PARAMETER:
            case ARRAY_TYPE:
            case UNBOUNDED_WILDCARD:
            case EXTENDS_WILDCARD:
            case SUPER_WILDCARD:
            case ANNOTATED_TYPE:
                type = atypeFactory.getAnnotatedTypeFromTypeTree(tree);
                break;
            case METHOD:
                type = atypeFactory.getMethodReturnType((MethodTree) tree);
                if (type == null || type.getKind() == TypeKind.VOID) {
                    // Nothing to do for void methods.
                    // Note that for a constructor the AnnotatedExecutableType does
                    // not use void as return type.
                    return true;
                }
                break;
            default:
                type = atypeFactory.getAnnotatedType(tree);
        }
        System.out.println(type);//THIS LINE WAS ADDED
        return validateType(tree, type);
    }
In the java9 execution, I get the output as : 
@Tainted Issue1111.@Tainted Box<? extends @Untainted Object super @Untainted Integer>
While in java8 execution,  I suppose the output to be(multiple outputs were present) : 
@Tainted Issue1111.@Tainted Box<? extends @Untainted Number super @Untainted Integer>
Further they diverge subsequently in the different calls of the methods as in the stack trace. So I was trying to verify why was there this change. I wanted to make sure of this error before reporting. Sorry for being late.

Regards, 
Ravi

On Wed, Jun 13, 2018 at 6:54 PM Werner Dietl <werner...@uwaterloo.ca> wrote:
Hi Ravi,

Can you please send me an update?
I'm quite concerned about the progress you're making and would like to better understand what you're spending your time on.

Thanks,
cu, WMD.
Sent: June 11, 2018 20:57
Subject: Re: javac 9: Tainting Test

Ravi Roshan

unread,
Jun 14, 2018, 2:27:46 AM6/14/18
to Werner Dietl, Checker Framework GSOC, Jeff Yucong Luo
Hi Werner, Jeff,
So as suggested, I reduced the test case in Issue1111.java to :
public class Issue1111 {
void foo2(Box<@Untainted ? super Integer> box) {
}
class Box<T extends Number> {}
}
While compiling in java8 CF, this passes well but in java9 CF, it gives the error :
error: AsSuperVisitor: type is not an erased subtype of supertype.
  type: @Untainted Object
  superType: @Tainted Integer
 
I checked it for different annotations too  like @Nullable in the place of @Untainted. It seems like while using annotations '? super Integer' goes all the way to Object which it shouldn't and hence the error. Now I am looking for the probable cause of this.
Regards,
Ravi

Ravi Roshan

unread,
Jun 14, 2018, 9:02:35 AM6/14/18
to Werner Dietl, Checker Framework GSOC, Jeff Yucong Luo
Hi Werner, Jeff,
I further reduced the test case to :
public class Issue1111 {
Box<@Untainted ? super Integer> box;
class Box<T extends Number> {}
}
Currently I have finally reached at the following point. The statement : 
final AnnotatedTypeMirror type = memberVisitor.visit(tree, typeFactory);
in the method :
public static AnnotatedTypeMirror fromMember(
            final AnnotatedTypeFactory typeFactory, final Tree tree){}
    in TypeFromTree.java changes the execution. Before this statement is executed, the value of tree in both java8 and java9 is :
    Box<@Untainted() ? super Integer> box
    After the execution of the statement, in java8 we get :
    Issue1111.Box<? extends @Untainted Number super Integer>
    and in java9 we get :
    Issue1111.Box<? extends @Untainted Object super Integer>
    
    I am looking for the declaration of the function visit() in SimpleTreeVisitor.java. Any comments would be appreciated.
 
Regards,
Ravi

Werner Dietl

unread,
Jun 14, 2018, 3:28:56 PM6/14/18
to Ravi Roshan, Checker Framework GSOC, Jeff Yucong Luo

Hi Ravi,


as discussed in the meeting, you should determine the type of `memberVisitor` and look what methods are invoked on it or its superclasses.

Find where the different upper bound is introduced and see why that decision is different between 8 and 9.

Send us an update if you get stuck and try to make progress on a different issue in the meantime.


Cheers,

cu, WMD.



From: Ravi Roshan <rrosh...@gmail.com>
Sent: Thursday, June 14, 2018 9:02:22 AM

To: Werner Dietl
Cc: Checker Framework GSOC; Jeff Yucong Luo

Ravi Roshan

unread,
Jun 19, 2018, 2:58:06 AM6/19/18
to Werner Dietl, Checker Framework GSOC, Jeff Yucong Luo
Hi Werner, Jeff,
I was going through the errors in Tainting Test. I have reached the following point :
In the function : 
public static Type wildUpperBound(TypeMirror tm, ProcessingEnvironment env)
in TypesUtils.java, executions seem to differ for java 8 and java 9. In CF with java9, the statement : 'w.bound' returns 'null', while in CF with java8, it returns 'T'. Because of this, in the statement : 
return w.bound == null ? syms.objectType : w.bound.bound;
CF with java9 returns 'syms.objectType' which equals 'java.lang.Object' while CF with java8 returns 'w.bound.bound' which equals 'java.lang.Number'. This causes a change in the further execution. The value of 'w' in 'w.bound' is : '? super java.lang.Integer' which is same in both. Also the argument to the function 'wildUpperBound()' is :
TypeMirror tm : ? super java.lang.Integer
which is again same for both. Also the course of execution till here is almost similar in both java8 and java9.
I am further verifying it and checking why the executions differ here. Any suggestions would be appreciated.
Regards,
Ravi

Jeff Luo

unread,
Jun 20, 2018, 1:50:25 PM6/20/18
to Werner Dietl, Ravi Roshan, Checker Framework GSOC
i added a   if (w.bound == null) assert false;    just before the return statement to get a precise call trace to TypesUtils.wildUpperBound. Trace below.

only call site to TypesUtils.wildUpperBound() is from BoundsInitializer.initializeExtendsBound, which calls it by extracting the type mirror out of an AnnotatedWildcardType

debugging further I tried to see if the AnnotatedWildcardType that wraps this type mirror was constructed incorrectly but none of that code seems to modifiy the type mirror. Looking up all call sites of the bound field shows that checker framework itself never assigns anything to it.

Werner:

Is it possible that in Java 9 the compiler itself no longer gives us the bound in the type mirror?  As Ravi points out, Java 8 gives us T but Java 9 gives us null for the bound.

===

Exception: java.lang.AssertionError; Stack trace: org.checkerframework.javacutil.TypesUtils.wildUpperBound(TypesUtils.java:343)
  org.checkerframework.framework.type.BoundsInitializer$InitializerVisitor.initializeExtendsBound(BoundsInitializer.java:524)
  org.checkerframework.framework.type.BoundsInitializer.initializeExtendsBound(BoundsInitializer.java:260)
  org.checkerframework.framework.type.BoundsInitializer.initializeExtendsBound(BoundsInitializer.java:246)
  org.checkerframework.framework.type.AnnotatedTypeMirror$AnnotatedWildcardType.getExtendsBound(AnnotatedTypeMirror.java:1839)
  org.checkerframework.framework.type.TypeFromTypeTreeVisitor.visitAnnotatedType(TypeFromTypeTreeVisitor.java:67)
  org.checkerframework.framework.type.TypeFromTypeTreeVisitor.visitAnnotatedType(TypeFromTypeTreeVisitor.java:1)
  com.sun.tools.javac.tree.JCTree$JCAnnotatedType.accept(JCTree.java:2637)
  com.sun.source.util.SimpleTreeVisitor.visit(SimpleTreeVisitor.java:80)
  org.checkerframework.framework.type.TypeFromTypeTreeVisitor.visitParameterizedType(TypeFromTypeTreeVisitor.java:96)
  org.checkerframework.framework.type.TypeFromTypeTreeVisitor.visitParameterizedType(TypeFromTypeTreeVisitor.java:1)
  com.sun.tools.javac.tree.JCTree$JCTypeApply.accept(JCTree.java:2381)
  com.sun.source.util.SimpleTreeVisitor.visit(SimpleTreeVisitor.java:80)
  org.checkerframework.framework.type.TypeFromTree.fromTypeTree(TypeFromTree.java:63)
  org.checkerframework.framework.type.TypeFromMemberVisitor.visitVariable(TypeFromMemberVisitor.java:30)
  org.checkerframework.framework.type.TypeFromMemberVisitor.visitVariable(TypeFromMemberVisitor.java:1)
  com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:968)
  com.sun.source.util.SimpleTreeVisitor.visit(SimpleTreeVisitor.java:80)
  org.checkerframework.framework.type.TypeFromTree.fromMember(TypeFromTree.java:50)
  org.checkerframework.framework.type.AnnotatedTypeFactory.fromMember(AnnotatedTypeFactory.java:1207)
  org.checkerframework.framework.type.AnnotatedTypeFactory.fromElement(AnnotatedTypeFactory.java:1123)
  org.checkerframework.framework.type.AnnotatedTypeFactory.getAnnotatedType(AnnotatedTypeFactory.java:968)
  org.checkerframework.framework.flow.CFAbstractTransfer.initialStore(CFAbstractTransfer.java:250)
  org.checkerframework.framework.flow.CFAbstractTransfer.initialStore(CFAbstractTransfer.java:1)
  org.checkerframework.dataflow.analysis.Analysis.init(Analysis.java:470)
  org.checkerframework.dataflow.analysis.Analysis.performAnalysis(Analysis.java:183)
  org.checkerframework.framework.flow.CFAbstractAnalysis.performAnalysis(CFAbstractAnalysis.java:94)
  org.checkerframework.framework.type.GenericAnnotatedTypeFactory.analyze(GenericAnnotatedTypeFactory.java:1238)
  org.checkerframework.framework.type.GenericAnnotatedTypeFactory.analyze(GenericAnnotatedTypeFactory.java:1197)
  org.checkerframework.framework.type.GenericAnnotatedTypeFactory.performFlowAnalysis(GenericAnnotatedTypeFactory.java:1133)
  org.checkerframework.framework.type.GenericAnnotatedTypeFactory.checkAndPerformFlowAnalysis(GenericAnnotatedTypeFactory.java:1498)
  org.checkerframework.framework.type.GenericAnnotatedTypeFactory.preProcessClassTree(GenericAnnotatedTypeFactory.java:259)
  org.checkerframework.common.basetype.BaseTypeVisitor.visitClass(BaseTypeVisitor.java:291)
  org.checkerframework.common.basetype.BaseTypeVisitor.visitClass(BaseTypeVisitor.java:1)
  com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:808)
  com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:56)
  org.checkerframework.framework.source.SourceVisitor.visit(SourceVisitor.java:89)
  org.checkerframework.framework.source.SourceChecker.typeProcess(SourceChecker.java:1004)
  org.checkerframework.common.basetype.BaseTypeChecker.typeProcess(BaseTypeChecker.java:500)
  org.checkerframework.javacutil.AbstractTypeProcessor$AttributionTaskListener.finished(AbstractTypeProcessor.java:182)
  com.sun.tools.javac.api.ClientCodeWrapper$WrappedTaskListener.finished(ClientCodeWrapper.java:828)
  com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:120)
  com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1404)
  com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1363)
  com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:959)
  com.sun.tools.javac.main.Main.compile(Main.java:302)
  com.sun.tools.javac.main.Main.compile(Main.java:162)
  com.sun.tools.javac.Main.compile(Main.java:57)
  com.sun.tools.javac.Main.main(Main.java:43)
--
Jeff Luo
PhD Candidate, ECE, UWaterloo

Jeff Luo

unread,
Jun 21, 2018, 1:40:45 PM6/21/18
to Jeff Luo, Werner Dietl, Ravi Roshan, Checker Framework GSOC
TODO note from meeting: look into javac 9 methods that might instantiate this field, or see if there's some particular call order that is necessary to correctly instantiate the bound.

Jeff Luo

unread,
Jun 25, 2018, 12:29:59 AM6/25/18
to Werner Dietl, Ravi Roshan, Checker Framework GSOC
Hello Werner,

As you mentioned in person, WilcardType.withTypeVar(Type t)  updates the bounds of a wildcard type. There are no direct call sites to this method in CF for java 8 or 9. Eclipse shows many possible transitive call site within the java compiler sources.

I instrumented WilcardType.withTypeVar(Type t) with the following as the first lines of the method:

System.err.println("------------->" + this + ".withTypeVar(" + t + ");");
(new Exception()).printStackTrace();

shows that javac 8 & 9 both update the bound of "? super Integer ", and "@Untainted ? super Integer" with T :

------------->? super java.lang.Integer.withTypeVar(T);
------------->@org.checkerframework.checker.tainting.qual.Untainted ? super java.lang.Integer.withTypeVar(T);

and likewise for an unbounded wildcard, and annotated unbounded wildcard:

------------->?.withTypeVar(T);
------------->@org.checkerframework.checker.tainting.qual.Untainted ?.withTypeVar(T);

and the stack trace shows that all of the bounds updates are performed prior to CF type checking:

java.lang.AssertionError
at com.sun.tools.javac.code.Type$WildcardType.withTypeVar(Type.java:882)
at com.sun.tools.javac.comp.Attr.visitTypeApply(Attr.java:4107)
at com.sun.tools.javac.tree.JCTree$JCTypeApply.accept(JCTree.java:2369)
at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:653)
at com.sun.tools.javac.comp.Attr.attribType(Attr.java:713)
at com.sun.tools.javac.comp.Attr.attribType(Attr.java:706)
at com.sun.tools.javac.comp.MemberEnter.visitVarDef(MemberEnter.java:262)
at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:950)
at com.sun.tools.javac.comp.MemberEnter.memberEnter(MemberEnter.java:161)
at com.sun.tools.javac.comp.MemberEnter.signature(MemberEnter.java:109)
at com.sun.tools.javac.comp.MemberEnter.visitMethodDef(MemberEnter.java:191)
at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:866)
at com.sun.tools.javac.comp.MemberEnter.memberEnter(MemberEnter.java:161)
at com.sun.tools.javac.comp.MemberEnter.memberEnter(MemberEnter.java:173)
at com.sun.tools.javac.comp.TypeEnter$MembersPhase.finishClass(TypeEnter.java:947)
at com.sun.tools.javac.comp.TypeEnter$MembersPhase.runPhase(TypeEnter.java:931)
at com.sun.tools.javac.comp.TypeEnter$Phase.doCompleteEnvs(TypeEnter.java:270)
at com.sun.tools.javac.comp.TypeEnter$MembersPhase.doCompleteEnvs(TypeEnter.java:866)
at com.sun.tools.javac.comp.TypeEnter$Phase.completeEnvs(TypeEnter.java:245)
at com.sun.tools.javac.comp.TypeEnter$Phase.completeEnvs(TypeEnter.java:254)
at com.sun.tools.javac.comp.TypeEnter$Phase.completeEnvs(TypeEnter.java:254)
at com.sun.tools.javac.comp.TypeEnter$Phase.completeEnvs(TypeEnter.java:254)
at com.sun.tools.javac.comp.TypeEnter.complete(TypeEnter.java:195)
at com.sun.tools.javac.code.Symbol.complete(Symbol.java:633)
at com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:1314)
at com.sun.tools.javac.comp.Enter.complete(Enter.java:577)
at com.sun.tools.javac.comp.Enter.main(Enter.java:554)
at com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:1052)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:923)
at com.sun.tools.javac.main.Main.compile(Main.java:302)
at com.sun.tools.javac.main.Main.compile(Main.java:162)
at com.sun.tools.javac.Main.compile(Main.java:57)
at com.sun.tools.javac.Main.main(Main.java:43)

So, we should be getting correct WildcardTypes from the compiler... however

I instrumented BaseTypeChecker.typeProcess() to print out the contents of the AST at the start of this method, the earliest possible point of CF execution based on stack trace from last email, to see if we get the correct wildcard types from the compiler.

Here, the WildcardType.bound of "? super Integer" is T, but the WildcardType.bound of "@Untained ? super Integer" is null. For some reason, we're getting a different AST than what we expect from the compiler.

I'm inclined to believe my earlier hypothesis is correct. However, I'm not sure why we don't get the AST with which the compiler clearly updated the bounds. Somehow, we get an AST with bounds updated for unannotated wildcards, but not annotated wildcards.

Jeff

Werner Dietl

unread,
Jun 25, 2018, 1:14:09 PM6/25/18
to Jeff Yucong Luo, Ravi Roshan, Checker Framework GSOC

Hi Jeff,

 

Thanks for continuing to look into this.

 

Maybe it will be useful to look at the hashcodes of the WildcardType objects that get used in these different places.

Some method on Types return new anonymous inner class objects and change certain fields. Maybe something gets confused there.

It would also allow you to track down which wildcard first gets set by the compiler and which other wildcard you then see in the Checker Framework.

What’s the hashcode of the wildcard that has a null bound vs. the object on which the bound is set?

Which of the two objects do you see in the AST?

 

The withTypeVar code seems to directly modify the type in the AST, so this doesn’t yet explain why the bound isn’t set.

 

What is the smallest example program for which you can observe the difference in behavior?

What is your “earlier hypothesis”?

 

Instead of `(new Exception()).printStackTrace();` you can just write `Thread.dumpStack()`.

 

Best,

cu, WMD.
--
https://ece.uwaterloo.ca/~wdietl/

Jeff Luo

unread,
Jun 26, 2018, 2:04:58 PM6/26/18
to Werner Dietl, Jeff Yucong Luo, Ravi Roshan, Checker Framework GSOC
Here's the minimal test case:

    Box<? super Integer> tainedBox;

    Box<@Untainted ? super Integer> untainedBox;

    class Box<T extends Number> { }

Here's the hash codes of all of the WildcardType objects for which withTypeVar is invoked on in javac. I printed the hashcode both before and after bounds update, and whether the bound was updated or not, just in case the hashcode function is sensitive to the bound field (it turns out it isn't):

------------->? super java.lang.Integer.withTypeVar(T);
old bound: null
old hashcode: 1712536284
updated
new hashcode: 1712536284
------------->? super java.lang.Integer.withTypeVar(T);
old bound: null
old hashcode: 1123225098
updated
new hashcode: 1123225098
------------->? super java.lang.Integer.withTypeVar(T);
old bound: null
old hashcode: 1595212853
updated
new hashcode: 1595212853
------------->? super java.lang.Integer.withTypeVar(T);
old bound: null
old hashcode: 475266352
updated
new hashcode: 475266352
------------->? super java.lang.Integer.withTypeVar(T);
old bound: null
old hashcode: 1967205423
updated
new hashcode: 1967205423
------------->? super java.lang.Integer.withTypeVar(T);
old bound: null
old hashcode: 42121758
updated
new hashcode: 42121758
------------->? super java.lang.Integer.withTypeVar(T);
old bound: T
old hashcode: 1967205423
no updates
------------->@org.checkerframework.checker.tainting.qual.Untainted ? super java.lang.Integer.withTypeVar(T);
old bound: T
old hashcode: 42121758
no updates

From CF, the hashcodes of the WildcardType objects within the AST are:

===
? super java.lang.Integer
class com.sun.tools.javac.code.Type$WildcardType
T
hashcode: 1967205423
===
? super java.lang.Integer
class com.sun.tools.javac.code.Type$WildcardType
null
hashcode: 1176735295

In particular, the WildcardType object for the unannotated wildcard (hash 1967205423) is the one that has its bounds set by javac, but the WildcardType object for the annotated wildcard (hash 1176735295) is a different object all together (vs the annotated WildcardType object with correct bounds, hash 42121758).

There seems to be a number of copies of both wildcard type object visited upon by javac.

On Mon, Jun 25, 2018 at 1:14 PM Werner Dietl <werner...@uwaterloo.ca> wrote:

Hi Jeff,

 

Thanks for continuing to look into this.

 

Maybe it will be useful to look at the hashcodes of the WildcardType objects that get used in these different places.

Some method on Types return new anonymous inner class objects and change certain fields. Maybe something gets confused there.

It would also allow you to track down which wildcard first gets set by the compiler and which other wildcard you then see in the Checker Framework.

What’s the hashcode of the wildcard that has a null bound vs. the object on which the bound is set?

Which of the two objects do you see in the AST?

 

The withTypeVar code seems to directly modify the type in the AST, so this doesn’t yet explain why the bound isn’t set.

 

What is the smallest example program for which you can observe the difference in behavior?

What is your “earlier hypothesis”?

 

Instead of `(new Exception()).printStackTrace();` you can just write `Thread.dumpStack()`.

 

Best,

cu, WMD.
--
https://ece.uwaterloo.ca/~wdietl/

 

From: Jeff Luo
Sent: June 25, 2018 00:30
To: Werner Dietl; Ravi Roshan
Cc: Checker Framework GSOC

Jeff Luo

unread,
Jun 27, 2018, 10:34:49 PM6/27/18
to Ravi Roshan, Werner Dietl, Checker Framework GSOC
Hello Ravi,

We discovered the cause of why the wildcard type's bound is null.

Given:      Box<@Untainted ? super Integer> untaintedBox;

The AST created by javac contains an AnnotatedTypeTree node which represents "@Untainted ? super Integer".

The type attached to this node is different between java 8 and 9:

In java 8, the type attached is an AnnotatedType, which contains an underlying type that is a WildcardType with bound T. Our existing code is written to create an AnnotatedTypeMirror to wrap this WildcardType. 

In java 9, the type attached is a WildcardType with bound T, and an underlying type that is also a WildcardType with bound null. Thus, our existing code wraps the WildcardType with bound null. 

The solution is to update the AnnotatedTypeMirror returned by TypeFromTypeTreeVisitor.visitAnnotatedType() so that it wraps the correct WildcardType.

Werner, as we discussed in person, there's 2 solutions:

Option 1: create a brand new AnnotatedTypeMirror to wrap the WildcardType attached to the node (and not the underlying WildcardType).

Option 2: update the bound of the underlying WildcardType from null to T.

I calculated the total # of test cases, failures, expected diagnostics, and unexpected diagnostics for gradle alltests as follows:

No fixes applied:
Total tests: 161
Failures: 12
Skipped: 0
2339 out of 2351 total expected diagnostics were found
29 total unexpected diagnostics were found

Option 1 fix:
Total tests: 161
Failures: 12
Skipped: 0
2340 out of 2351 total expected diagnostics were found
28 total unexpected diagnostics were found

Option 2 fix:
Total tests: 161
Failures: 12
Skipped: 0
2340 out of 2351 total expected diagnostics were found
28 total unexpected diagnostics were found

Both options fix this specific problem and neither introduces more or eliminate any additional problems. I'm inclined to go with option 1, as we discussed in person that option 2 may or may not have effects on other tools that depend on the AST produced by java 9.

If this looks good then I'll file the PR.

As for Tainting Tests, we still have 1 unexpected diagnostic:
    Issue1942.java:14: error: (override.param.invalid)

Ravi: can you start a separate email thread for Issue1942 and see if you can find out what causes this in Java 9 and why it isn't there in Java 8? 

Jeff

Werner Dietl

unread,
Jun 27, 2018, 11:46:47 PM6/27/18
to Jeff Luo, rrosh...@gmail.com, Werner Dietl, Checker Framework GSOC
Hi Jeff,

thanks for the detailed analysis.
As you have both options implemented, can you please make 2 PRs so
that we can compare how the different options look?

cu, WMD.
> --
> You received this message because you are subscribed to the Google Groups "checker-framework-gsoc" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to checker-framework...@googlegroups.com.
> To post to this group, send email to checker-fra...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/checker-framework-gsoc/CALHuCLi4ehshNCo4ETGrhx%2BeQ2cXNNxO5FuoZgfyBBr9jeMfhQ%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.



--
http://www.google.com/profiles/wdietl

Jeff Luo

unread,
Jun 28, 2018, 1:11:33 PM6/28/18
to Werner Dietl, Jeff Luo, rrosh...@gmail.com, Werner Dietl, Checker Framework GSOC

Jeff Luo

unread,
Jun 28, 2018, 2:44:59 PM6/28/18
to Jeff Luo, Werner Dietl, rrosh...@gmail.com, Werner Dietl, Checker Framework GSOC
The text diff between the all systems test outputs for the two options don't show anything interesting: the order of the tests are executed differently but the outputs (failures & successes, as well as the specific errors of failures) are the same.
Reply all
Reply to author
Forward
0 new messages