Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions checker/tests/command-line/Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
# All targets
.PHONY: all clean skipped issue618
.PHONY: all clean skipped issue618 issue1015

# Tests that are currently passing
all: issue618
all: issue618 issue1015

# Tests that are currently not passing
skipped:

issue618:
make -C issue618

issue1015:
make -C issue1015

clean:
make -C issue618 clean
make -C issue1015 clean
8 changes: 8 additions & 0 deletions checker/tests/command-line/issue1015/Issue1015.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import org.checkerframework.checker.tainting.qual.Tainted;
import org.checkerframework.checker.tainting.qual.Untainted;

@Untainted class Issue1015 extends Super1015 implements Interface1015 {}

@Untainted class Super1015 {}

@Tainted interface Interface1015 {}
9 changes: 9 additions & 0 deletions checker/tests/command-line/issue1015/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.PHONY: all clean

all:
$(JAVAC) -processor tainting -Ashowchecks Issue1015.java > out.txt 2>&1
diff -u expected.txt out.txt

clean:
rm -f out.txt
rm -f *.class
12 changes: 12 additions & 0 deletions checker/tests/command-line/issue1015/expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
TaintingVisitor about to test whether the class declaration annotation is a subtype of the extends clause annotation (at Issue1015.java:4:36): extends tree = IDENTIFIER Super1015
actual: @org.checkerframework.checker.tainting.qual.Untainted Issue1015
expected: @org.checkerframework.checker.tainting.qual.Untainted Super1015
success: class declaration annotation is subtype of extends clause annotation (at Issue1015.java:4:36): extends tree = IDENTIFIER Super1015
actual: @org.checkerframework.checker.tainting.qual.Untainted Issue1015
expected: @org.checkerframework.checker.tainting.qual.Untainted Super1015
TaintingVisitor about to test whether the class declaration annotation is a subtype of the implements clause annotation (at Issue1015.java:4:57): implements tree = IDENTIFIER Interface1015
actual: @org.checkerframework.checker.tainting.qual.Untainted Issue1015
expected: @org.checkerframework.checker.tainting.qual.Tainted Interface1015
success: class declaration annotation is subtype of implements clause annotation (at Issue1015.java:4:57): implements tree = IDENTIFIER Interface1015
actual: @org.checkerframework.checker.tainting.qual.Untainted Issue1015
expected: @org.checkerframework.checker.tainting.qual.Tainted Interface1015
2 changes: 1 addition & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ median of four warm-daemon reps per side).

**Closed issues:**

eisop#433, eisop#792, eisop#863, eisop#1801.
eisop#433, eisop#792, eisop#863, eisop#1015, eisop#1801.


Version 3.49.5-eisop1 (April 26, 2026)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,11 @@ protected void checkExtendsOrImplements(
TypeMirror boundTM = boundType.getUnderlyingType();
for (AnnotationMirror classAnno : classBounds) {
AnnotationMirror boundAnno = boundType.getAnnotationInHierarchy(classAnno);
if (!qualHierarchy.isSubtypeShallow(classAnno, classType, boundAnno, boundTM)) {
checkExtendsOrImplementsStartDiagnostic(
boundClause, classAnno, classType, boundAnno, boundTM, isExtends);
boolean success =
qualHierarchy.isSubtypeShallow(classAnno, classType, boundAnno, boundTM);
if (!success) {
checker.reportError(
boundClause,
(isExtends
Expand All @@ -987,6 +991,85 @@ protected void checkExtendsOrImplements(
classAnno,
boundAnno);
}
checkExtendsOrImplementsEndDiagnostic(
success, boundClause, classAnno, classType, boundAnno, boundTM, isExtends);
}
}

/**
* Prints a diagnostic about entering {@link #checkExtendsOrImplements}, if the showchecks
* option was set.
*
* @param boundClause an extends or implements clause
* @param classAnno the annotation on the class declaration
* @param classType the type being declared
* @param boundAnno the annotation on the extends or implements clause
* @param boundTM the type of the extends or implements clause
* @param isExtends true for an extends clause, false for an implements clause
*/
protected final void checkExtendsOrImplementsStartDiagnostic(
Tree boundClause,
AnnotationMirror classAnno,
TypeMirror classType,
AnnotationMirror boundAnno,
TypeMirror boundTM,
boolean isExtends) {
if (showchecks) {
String clause = isExtends ? "extends" : "implements";
System.out.printf(
"%s %s (at %s): %s tree = %s %s%n actual: %s %s%n expected: %s %s%n",
this.getClass().getSimpleName(),
"about to test whether the class declaration annotation is a subtype of the "
+ clause
+ " clause annotation",
fileAndLineNumber(boundClause),
clause,
boundClause.getKind(),
boundClause,
classAnno,
classType,
boundAnno,
boundTM);
}
}

/**
* Prints a diagnostic about exiting {@link #checkExtendsOrImplements}, if the showchecks option
* was set.
*
* @param success whether the check succeeded or failed
* @param boundClause an extends or implements clause
* @param classAnno the annotation on the class declaration
* @param classType the type being declared
* @param boundAnno the annotation on the extends or implements clause
* @param boundTM the type of the extends or implements clause
* @param isExtends true for an extends clause, false for an implements clause
*/
protected final void checkExtendsOrImplementsEndDiagnostic(
boolean success,
Tree boundClause,
AnnotationMirror classAnno,
TypeMirror classType,
AnnotationMirror boundAnno,
TypeMirror boundTM,
boolean isExtends) {
if (showchecks) {
String clause = isExtends ? "extends" : "implements";
System.out.printf(
" %s (at %s): %s tree = %s %s%n actual: %s %s%n expected: %s %s%n",
(success
? "success: class declaration annotation is subtype of "
: "FAILURE: class declaration annotation is not subtype of ")
+ clause
+ " clause annotation",
fileAndLineNumber(boundClause),
clause,
boundClause.getKind(),
boundClause,
classAnno,
classType,
boundAnno,
boundTM);
}
}

Expand Down
Loading