diff --git a/checker/tests/tainting/TaintingIssue6060.java b/checker/tests/tainting/TaintingIssue6060.java new file mode 100644 index 00000000000..9c271eb16f3 --- /dev/null +++ b/checker/tests/tainting/TaintingIssue6060.java @@ -0,0 +1,25 @@ +import java.util.Spliterator; +import java.util.function.Consumer; +import org.checkerframework.checker.tainting.qual.Untainted; + +public interface TaintingIssue6060 extends Iterable<@Untainted R> { + + default Spliterator<@Untainted R> spliterator() { + return Iterable.super.spliterator(); + } + + default Spliterator spliterator2() { + // :: error: (return) + return Iterable.super.spliterator(); + } + + default Spliterator spliterator3() { + // :: error: (return) + return this.spliterator(); + } + + // :: error: (override.param) + default void forEach(Consumer action) { + Iterable.super.forEach(action); + } +} diff --git a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java index ab5fd89eef7..49f7bfcd5fe 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java +++ b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java @@ -2183,6 +2183,23 @@ public AnnotatedDeclaredType getEnclosingType(TypeElement typeElement, Tree tree return thisType; } + /** + * Returns the {@link AnnotatedTypeMirror} of the enclosing type at the location of {@code tree} + * that is a subtype of {@code typeElement}. + * + * @param typeElement super type of the enclosing type to return + * @param tree location to use + * @return the enclosing type at the location of {@code tree} that is a subtype of {@code + * typeElement} + */ + public AnnotatedDeclaredType getEnclosingSubType(TypeElement typeElement, Tree tree) { + AnnotatedDeclaredType thisType = getSelfType(tree); + while (!isSubtype(thisType.getUnderlyingType(), typeElement.asType())) { + thisType = thisType.getEnclosingType(); + } + return thisType; + } + /** * Returns true if the erasure of {@code type1} is a Java subtype of the erasure of {@code type2}. * diff --git a/framework/src/main/java/org/checkerframework/framework/type/TypeFromExpressionVisitor.java b/framework/src/main/java/org/checkerframework/framework/type/TypeFromExpressionVisitor.java index f2d7a862ccf..143d6a4f819 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/TypeFromExpressionVisitor.java +++ b/framework/src/main/java/org/checkerframework/framework/type/TypeFromExpressionVisitor.java @@ -28,6 +28,7 @@ import java.util.List; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType; @@ -246,6 +247,7 @@ public AnnotatedTypeMirror visitMemberSelect(MemberSelectTree tree, AnnotatedTyp } switch (ElementUtils.getKindRecordAsClass(elt)) { case METHOD: + case CONSTRUCTOR: // x0.super() in anoymous classes case PACKAGE: // "java.lang" in new java.lang.Short("2") case CLASS: // o instanceof MyClass.InnerClass case ENUM: @@ -260,6 +262,14 @@ public AnnotatedTypeMirror visitMemberSelect(MemberSelectTree tree, AnnotatedTyp // Tree is "MyClass.this", where "MyClass" may be the innermost enclosing type or any // outer type. return f.getEnclosingType(TypesUtils.getTypeElement(TreeUtils.typeOf(tree)), tree); + } else if (tree.getIdentifier().contentEquals("super")) { + // Tree is "MyClass.super", where "MyClass" may be the innermost enclosing type or any + // outer type. + TypeMirror superTypeMirror = TreeUtils.typeOf(tree); + TypeElement superTypeElement = TypesUtils.getTypeElement(superTypeMirror); + AnnotatedDeclaredType thisType = f.getEnclosingSubType(superTypeElement, tree); + return AnnotatedTypes.asSuper( + f, thisType, AnnotatedTypeMirror.createType(superTypeMirror, f, false)); } else { // tree must be a field access, so get the type of the expression, and then call // asMemberOf. diff --git a/framework/tests/Issue6060.java b/framework/tests/Issue6060.java new file mode 100644 index 00000000000..d9ee30afd15 --- /dev/null +++ b/framework/tests/Issue6060.java @@ -0,0 +1,13 @@ +import java.util.Spliterator; +import java.util.function.Consumer; + +public interface Issue6060 extends Iterable { + + default Spliterator spliterator() { + return Iterable.super.spliterator(); + } + + default void forEach(Consumer action) { + Iterable.super.forEach(action); + } +}