Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
edf711e
Add lintoption to instanceof
aosen-xiong May 3, 2025
2d05deb
Add the string to lintset
aosen-xiong May 3, 2025
f87d228
Use correct string
aosen-xiong May 3, 2025
e57ef74
Add manual section
aosen-xiong May 4, 2025
30220ed
Add test case
aosen-xiong May 4, 2025
33c692b
Fix log and refine tests
aosen-xiong May 4, 2025
a12fb71
Merge branch 'master' into fix-instanceof
aosen-xiong May 7, 2025
d1f6652
Merge branch 'master' into fix-instanceof
aosen-xiong May 19, 2025
ff6445d
Fix jtreg test
aosen-xiong May 20, 2025
93650de
Use field to store lint option
aosen-xiong May 20, 2025
f7b35f6
Merge branch 'master' into fix-instanceof
aosen-xiong May 20, 2025
5bbdb1d
Javadoc
aosen-xiong May 20, 2025
f112f83
Separate instanceof into two cases
aosen-xiong May 31, 2025
f4df421
Remove unused instanceof redundant field first
aosen-xiong May 31, 2025
c98e9c2
Typo
aosen-xiong Jun 3, 2025
75221b3
Refactor lint option
aosen-xiong Jun 3, 2025
fc6acdd
Add and rewrite text for lint option
aosen-xiong Jun 3, 2025
e50a7d9
Apply suggestions from code review
aosen-xiong Jun 4, 2025
727e532
Logic
aosen-xiong Jun 4, 2025
651af78
Format; Improve the tests
aosen-xiong Jun 4, 2025
4bbb1b3
Reword
aosen-xiong Jun 5, 2025
6e44d24
Fix test case format
aosen-xiong Jun 5, 2025
531531b
Try new logic
aosen-xiong Jun 5, 2025
92cdf81
Small fix
aosen-xiong Jun 5, 2025
52b175e
Fix line number in output
aosen-xiong Jun 5, 2025
b1a2a8d
Use correct strings
aosen-xiong Jun 5, 2025
a6d2165
Use lowercase for folder name
aosen-xiong Jun 5, 2025
1f0c852
Merge branch 'master' into fix-instanceof
aosen-xiong Jun 6, 2025
c16a0fa
Changelog
aosen-xiong Jun 6, 2025
c35d301
Empty commit for CI
aosen-xiong Jun 6, 2025
47a87f0
Merge branch 'master' into fix-instanceof
aosen-xiong Jun 12, 2025
ff83cb7
Tweak text
wmdietl Jun 15, 2025
97807bf
Merge branch 'master' into fix-instanceof
aosen-xiong Jun 15, 2025
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
17 changes: 17 additions & 0 deletions checker/jtreg/lintoption/InstanceofLintOptionDisabled.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* @test
* @summary Test case for instanceof lint option: -Alint=-instanceof
* @requires jdk.version >= 17
* @compile -processor org.checkerframework.checker.tainting.TaintingChecker InstanceofLintOptionEnabled.java -Alint=-instanceof
* @compile -processor org.checkerframework.checker.tainting.TaintingChecker InstanceofLintOptionEnabled.java -Alint=-instanceof:unsafe
* @compile -processor org.checkerframework.checker.tainting.TaintingChecker InstanceofLintOptionEnabled.java -Alint=instanceof,-instanceof:unsafe
*/

import org.checkerframework.checker.tainting.qual.Untainted;

public class InstanceofLintOptionDisabled {
void bar(Object o) {
if (o instanceof @Untainted String s) {}
if (o instanceof @Untainted String) {}
}
}
18 changes: 18 additions & 0 deletions checker/jtreg/lintoption/InstanceofLintOptionEnabled.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* @test
* Test case for instanceof lint option: -Alint=instanceof
* @requires jdk.version >= 17
* @compile/ref=InstanceofLintOptionEnabled.out -XDrawDiagnostics -processor org.checkerframework.checker.tainting.TaintingChecker InstanceofLintOptionEnabled.java
* @compile/ref=InstanceofLintOptionEnabled.out -XDrawDiagnostics -processor org.checkerframework.checker.tainting.TaintingChecker InstanceofLintOptionEnabled.java -Alint=instanceof
* @compile/ref=InstanceofLintOptionEnabled.out -XDrawDiagnostics -processor org.checkerframework.checker.tainting.TaintingChecker InstanceofLintOptionEnabled.java -Alint=instanceof:unsafe
* @compile/ref=InstanceofLintOptionEnabled.out -XDrawDiagnostics -processor org.checkerframework.checker.tainting.TaintingChecker InstanceofLintOptionEnabled.java -Alint=-instanceof,instanceof:unsafe
*/

import org.checkerframework.checker.tainting.qual.Untainted;

public class InstanceofLintOptionEnabled {
void bar(Object o) {
if (o instanceof @Untainted String s) {}
if (o instanceof @Untainted String) {}
}
}
4 changes: 4 additions & 0 deletions checker/jtreg/lintoption/InstanceofLintOptionEnabled.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
InstanceofLintOptionEnabled.java:15:15: compiler.warn.proc.messager: [instanceof.pattern.unsafe] instanceof pattern binding '@Tainted Object' to '@Untainted
String s' cannot be statically verified.
InstanceofLintOptionEnabled.java:16:15: compiler.warn.proc.messager: [instanceof.unsafe] '@Tainted Object' instanceof '@Untainted String' cannot be statically verified.
2 warnings
3 changes: 3 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ Version 3.49.3-eisop2 (June ??, 2025)

**User-visible changes:**

The `instanceof.unsafe` and `instanceof.pattern.unsafe` warnings in the Checker Framework are now controlled by lint options.
They are enabled by default and can be disabled using `-Alint=-instanceof.unsafe` or `-Alint=-instanceof`.

**Implementation details:**

**Closed issues:**
Expand Down
15 changes: 11 additions & 4 deletions docs/manual/warnings.tex
Original file line number Diff line number Diff line change
Expand Up @@ -711,12 +711,11 @@

\item
\code{cast:unsafe} (default: on) warn about unsafe casts that are not
checked at run time, as in \code{((@NonNull String) myref)}. Such casts
are generally not necessary because of type refinement
Comment thread
aosen-xiong marked this conversation as resolved.
(Section~\ref{type-refinement}).
checked at run time, as in \code{((@NonNull String) myref)}.
Such casts are unsafe as the type qualifiers are ignored at run time.

\item
\code{cast:redundant} (default: on) warn about redundant
\code{cast:redundant} (default: off) warn about redundant
Comment thread
aosen-xiong marked this conversation as resolved.
casts that are guaranteed to succeed at run time,
as in \code{((@NonNull String) "m")}. Such casts are not necessary,
because the target expression of the cast already has the given type
Expand All @@ -725,6 +724,14 @@
\item
\code{cast} Enable or disable all cast-related warnings.

\item
\code{instanceof:unsafe} (default: on) warn about unsafe instanceof tests
that are not checked at run time, as in \code{o instanceof @Untainted String}.
Such instanceof tests are unsafe as the type qualifiers are ignored at run time.

\item
\code{instanceof} Enable or disable instanceof-related warnings.
Comment thread
aosen-xiong marked this conversation as resolved.

\item
\begin{sloppypar}
\code{all} Enable or disable all lint warnings, including
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ protected Set<String> createSupportedLintOptions() {
lintSet.add("cast");
lintSet.add("cast:redundant");
lintSet.add("cast:unsafe");
lintSet.add("instanceof");
Comment thread
aosen-xiong marked this conversation as resolved.
lintSet.add("instanceof:unsafe");
return lintSet;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,15 @@ public class BaseTypeVisitor<Factory extends GenericAnnotatedTypeFactory<?, ?, ?
/** True if "-AcheckEnclosingExpr" was passed on the command line. */
private final boolean checkEnclosingExpr;

/** True if "-Alint=cast:redundant" was passed on the command line. */
private final boolean lintCastRedundantEnabled;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering whether we should call all these fields "xxxDisabled" and not have the negation in every check. Does it make the code easier to read either way?
If you do this, be careful in adapting the Javadocs.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lint option sounds optional check to me, and we enable unsafe lint options by default (maybe it could be an error?).

I think it would be nicer to keep these as xxxEnabled.


/** True unless "-Alint=-cast:unsafe" was passed on the command line. */
private final boolean lintCastUnsafeEnabled;

/** True unless "-Alint=-instanceof:unsafe" was passed on the command line. */
private final boolean lintInstanceofUnsafeEnabled;

/** The tree of the enclosing method that is currently being visited, if any. */
protected @Nullable MethodTree methodTree = null;

Expand Down Expand Up @@ -348,6 +357,9 @@ protected BaseTypeVisitor(BaseTypeChecker checker, @Nullable Factory typeFactory
checker.hasOption("assumeDeterministic") || checker.hasOption("assumePure");
assumePureGetters = checker.hasOption("assumePureGetters");
checkCastElementType = checker.hasOption("checkCastElementType");
lintCastRedundantEnabled = checker.getLintOption("cast:redundant", false);
lintCastUnsafeEnabled = checker.getLintOption("cast:unsafe", true);
lintInstanceofUnsafeEnabled = checker.getLintOption("instanceof:unsafe", true);
}

/** An array containing just {@code BaseTypeChecker.class}. */
Expand Down Expand Up @@ -2713,9 +2725,11 @@ public Void visitNewArray(NewArrayTree tree, Void p) {
/**
* If the lint option "cast:redundant" is set, this method issues a warning if the cast is
* redundant.
*
* @param typeCastTree the TypeCastTree to check
*/
protected void checkTypecastRedundancy(TypeCastTree typeCastTree) {
if (!checker.getLintOption("cast:redundant", false)) {
if (!lintCastRedundantEnabled) {
return;
}

Expand All @@ -2729,13 +2743,13 @@ protected void checkTypecastRedundancy(TypeCastTree typeCastTree) {

/**
* Issues a warning if the given explicitly-written typecast is unsafe. Does nothing if the lint
* option "cast:unsafe" is not set. Only primary qualifiers are checked unless the command line
* option "-cast:unsafe" is set. Only primary qualifiers are checked unless the command line
* option "checkCastElementType" is supplied.
*
* @param typeCastTree an explicitly-written typecast
*/
protected void checkTypecastSafety(TypeCastTree typeCastTree) {
if (!checker.getLintOption("cast:unsafe", true)) {
if (!lintCastUnsafeEnabled) {
return;
}
AnnotatedTypeMirror castType = atypeFactory.getAnnotatedType(typeCastTree);
Expand Down Expand Up @@ -2917,6 +2931,9 @@ public Void visitTypeCast(TypeCastTree tree, Void p) {

@Override
public Void visitInstanceOf(InstanceOfTree tree, Void p) {
if (!lintInstanceofUnsafeEnabled) {
return super.visitInstanceOf(tree, p);
}
// The "reference type" is the type after "instanceof".
Tree patternTree = InstanceOfUtils.getPattern(tree);
if (patternTree != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1890,7 +1890,7 @@ private String detailedMsgTextPositionString(
//

/**
* Determine which lint options are artive.
* Determine which lint options are active.
Comment thread
aosen-xiong marked this conversation as resolved.
*
* @param options the command-line options
* @return the active lint options
Expand Down