Skip to content
48 changes: 24 additions & 24 deletions checker/bin-devel/test-jspecify-reference-checker.sh
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
#!/bin/bash

set -e
# set -o verbose
set -o xtrace
export SHELLOPTS
echo "SHELLOPTS=${SHELLOPTS}"

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
source "$SCRIPT_DIR"/clone-related.sh

./gradlew assembleForJavac --console=plain -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.http.connectionTimeout=60000

# TODO: remove uses of `main-eisop` once that becomes `main`.
"$SCRIPT_DIR/.git-scripts/git-clone-related" --upstream-branch main-eisop eisop jspecify-reference-checker

cd ../jspecify-reference-checker

# Delete the eisop/jdk that was already cloned...
rm -r ../jdk
# instead clone the jspecify/jdk.
"$SCRIPT_DIR/.git-scripts/git-clone-related" jspecify jdk

JSPECIFY_CONFORMANCE_TEST_MODE=details ./gradlew build conformanceTests demoTest --console=plain --include-build "$CHECKERFRAMEWORK"
##!/bin/bash
#
#set -e
## set -o verbose
#set -o xtrace
#export SHELLOPTS
#echo "SHELLOPTS=${SHELLOPTS}"
#
#SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
#source "$SCRIPT_DIR"/clone-related.sh
#
#./gradlew assembleForJavac --console=plain -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.http.connectionTimeout=60000
#
## TODO: remove uses of `main-eisop` once that becomes `main`.
#"$SCRIPT_DIR/.git-scripts/git-clone-related" --upstream-branch main-eisop eisop jspecify-reference-checker
#
#cd ../jspecify-reference-checker
#
## Delete the eisop/jdk that was already cloned...
#rm -r ../jdk
## instead clone the jspecify/jdk.
#"$SCRIPT_DIR/.git-scripts/git-clone-related" jspecify jdk
#
#JSPECIFY_CONFORMANCE_TEST_MODE=details ./gradlew build conformanceTests demoTest --console=plain --include-build "$CHECKERFRAMEWORK"
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* @compile/fail/ref=AnnotatedForWithUseNoFlag.out -XDrawDiagnostics -Xlint:unchecked -processor org.checkerframework.checker.nullness.NullnessChecker AnnotatedForWithUse.java
* @compile/fail/ref=AnnotatedForWithUseOnlyAnnotatedFor.out -XDrawDiagnostics -Xlint:unchecked -processor org.checkerframework.checker.nullness.NullnessChecker -AonlyAnnotatedFor AnnotatedForWithUse.java
* @compile/fail/ref=AnnotatedForWithUseConservativeDefault.out -XDrawDiagnostics -Xlint:unchecked -processor org.checkerframework.checker.nullness.NullnessChecker -AuseConservativeDefaultsForUncheckedCode=source AnnotatedForWithUse.java
* @compile/fail/ref=AnnotatedForWithUseOptimisticDefault.out -XDrawDiagnostics -Xlint:unchecked -processor org.checkerframework.checker.nullness.NullnessChecker -AuseOptimisticDefaultsForUncheckedCode=source AnnotatedForWithUse.java
*/
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.AnnotatedFor;
Expand All @@ -23,13 +24,13 @@ void set(Object of) {}
@AnnotatedFor("nullness")
class AnnotatedUse {
void use(Unannotated u) {
// 1: OK, 2: OK, 3: Err
// 1: OK, 2: OK, 3: Err. 4: OK
@NonNull Object obj = u.o;
// 1. Err, 2: Err, TODO want OK, 3: OK, TODO want Err
// 1. Err, 2: Err, TODO want OK, 3: OK, TODO want Err, 4: Err, TODO want OK
u.o = null;
// 1: OK, 2: OK, 3: Err
// 1: OK, 2: OK, 3: Err, 4: OK
u.get().toString();
// 1: Err, 2: Err TODO want OK, 3: Err
// 1: Err, 2: Err TODO want OK, 3: Err, 4: OK
u.set(null);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
AnnotatedForWithUse.java:27:36: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
AnnotatedForWithUse.java:28:36: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @Nullable Object
required: @NonNull Object
AnnotatedForWithUse.java:31:18: compiler.err.proc.messager: [dereference.of.nullable] dereference of possibly-null reference u.get()
AnnotatedForWithUse.java:31:29: compiler.err.proc.messager: [method.invocation.invalid] call to toString() not allowed on the given receiver.
AnnotatedForWithUse.java:32:18: compiler.err.proc.messager: [dereference.of.nullable] dereference of possibly-null reference u.get()
AnnotatedForWithUse.java:32:29: compiler.err.proc.messager: [method.invocation.invalid] call to toString() not allowed on the given receiver.
found : @UnknownInitialization Object
required: @Initialized Object
AnnotatedForWithUse.java:33:19: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter of of Unannotated.set.
AnnotatedForWithUse.java:34:19: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter of of Unannotated.set.
found : @UnknownKeyFor NullType
required: @KeyForBottom Object
AnnotatedForWithUse.java:33:19: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter of of Unannotated.set.
AnnotatedForWithUse.java:34:19: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter of of Unannotated.set.
found : @Nullable NullType
required: @NonNull Object
5 errors
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
AnnotatedForWithUse.java:14:16: compiler.err.proc.messager: [initialization.field.uninitialized] the default constructor does not initialize field o
AnnotatedForWithUse.java:17:20: compiler.err.proc.messager: [return.type.incompatible] incompatible types in return.
AnnotatedForWithUse.java:15:16: compiler.err.proc.messager: [initialization.field.uninitialized] the default constructor does not initialize field o
AnnotatedForWithUse.java:18:20: compiler.err.proc.messager: [return.type.incompatible] incompatible types in return.
type of expression: @Nullable NullType
method return type: @NonNull Object
AnnotatedForWithUse.java:29:19: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
AnnotatedForWithUse.java:30:19: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @Nullable NullType
required: @NonNull Object
AnnotatedForWithUse.java:33:19: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter of of Unannotated.set.
AnnotatedForWithUse.java:34:19: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter of of Unannotated.set.
found : @Nullable NullType
required: @NonNull Object
4 errors
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
AnnotatedForWithUse.java:29:19: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
AnnotatedForWithUse.java:30:19: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @Nullable NullType
required: @NonNull Object
AnnotatedForWithUse.java:33:19: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter of of Unannotated.set.
AnnotatedForWithUse.java:34:19: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter of of Unannotated.set.
found : @Nullable NullType
required: @NonNull Object
2 errors
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
AnnotatedForWithUse.java:15:16: compiler.err.proc.messager: [type.invalid.annotations.on.location] annotation @org.checkerframework.checker.nullness.qual.KeyForBottom used on prohibited locations FIELD
AnnotatedForWithUse.java:15:16: compiler.err.proc.messager: [initialization.field.uninitialized] the default constructor does not initialize field o
AnnotatedForWithUse.java:15:16: compiler.err.proc.messager: [type.invalid.annotations.on.location] annotation @org.checkerframework.checker.initialization.qual.FBCBottom used on prohibited locations FIELD
AnnotatedForWithUse.java:17:16: compiler.err.proc.messager: [type.invalid.annotations.on.location] annotation @org.checkerframework.checker.nullness.qual.KeyForBottom used on prohibited locations RETURN
AnnotatedForWithUse.java:17:16: compiler.err.proc.messager: [type.invalid.annotations.on.location] annotation @org.checkerframework.checker.initialization.qual.FBCBottom used on prohibited locations RETURN
AnnotatedForWithUse.java:18:20: compiler.err.proc.messager: [return.type.incompatible] incompatible types in return.
type of expression: @UnknownKeyFor NullType
method return type: @KeyForBottom Object
AnnotatedForWithUse.java:18:20: compiler.err.proc.messager: [return.type.incompatible] incompatible types in return.
type of expression: @Nullable NullType
method return type: @NonNull Object
AnnotatedForWithUse.java:30:19: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @UnknownKeyFor NullType
required: @KeyForBottom Object
AnnotatedForWithUse.java:30:19: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @Nullable NullType
required: @NonNull Object
9 errors
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Version 3.49.5-eisop1 (July ??, 2025)

**User-visible changes:**

The new command-line option `-AuseOptimisticDefaultsForUncheckedCode` takes `source` and `bytecode` argument, similar to
`-AuseConservativeDefaultsForUnCheckedCode` but apply to optimistic default, that is, Top for method parameter type and
Bottom for method return and field type.
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.

We also need to go through the manual and discuss this new option there.


The new command-line option `-AonlyAnnotatedFor` suppresses all type-checking errors and warnings outside the scope of
a corresponding `@AnnotatedFor` annotation.
Note that the `@AnnotatedFor` annotation must include the checker's name to enable warnings from that checker.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@
// Whether to type check the enclosing expression of an inner class instantiation.
"checkEnclosingExpr",

// Whether to use optimistic defaults for bytecode and/or source code.
// The option takes same arguments as "useConservativeDefaultsForUncheckedCode".
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.

The ordering of the options should be switched, instead of having a forward reference here.

// Optimistic default will only apply the code is not in the scope of an @AnnotatedFor.
// Note using this option will not suppress the warning for source code not in the scope of an
// @AnnotatedFor, user can use -AonlyAnnotatedFor together with this option.
// Optimistic and conservative defaults should apply to source or/and bytecode at the same time.
"useOptimisticDefaultsForUncheckedCode",

// Whether to use conservative defaults for bytecode and/or source code.
// This option takes arguments "source" and/or "bytecode".
// The default is "-source,-bytecode" (eventually this will be changed to "-source,bytecode").
Expand Down Expand Up @@ -2814,8 +2822,35 @@ public boolean shouldSuppressWarnings(TreePath path, String errKey) {
}

/**
* Should conservative defaults be used for the kind of unchecked code indicated by the
* parameter?
* Determine whether optimistic defaults should be used for the kind of unchecked code indicated
* by the command line arguments.
*
* @param kindOfCode source or bytecode
* @return whether optimistic defaults should be used
*/
public boolean useOptimisticDefault(String kindOfCode) {
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.

Lots of duplicated code.

boolean useUncheckedDefaultsForSource = false;
boolean useUncheckedDefaultsForByteCode = false;
for (String arg : this.getStringsOption("useOptimisticDefaultsForUncheckedCode", ',')) {
boolean value = arg.indexOf("-") != 0;
arg = value ? arg : arg.substring(1);
if (arg.equals(kindOfCode)) {
return value;
}
}
if (kindOfCode.equals("source")) {
return useUncheckedDefaultsForSource;
} else if (kindOfCode.equals("bytecode")) {
return useUncheckedDefaultsForByteCode;
} else {
throw new UserError(
"SourceChecker: unexpected argument to useOptimisticDefault: " + kindOfCode);
}
}

/**
* Determine whether conservative defaults should be used for the kind of unchecked code
* indicated by the command line arguments.
*
* @param kindOfCode source or bytecode
* @return whether conservative defaults should be used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ protected final QualifierDefaults createAndInitQualifierDefaults() {
QualifierDefaults defs = createQualifierDefaults();
addCheckedCodeDefaults(defs);
addCheckedStandardDefaults(defs);
addUncheckedStandardDefaults(defs);
addUncheckedDefaults(defs);
checkForDefaultQualifierInHierarchy(defs);

return defs;
Expand Down Expand Up @@ -876,12 +876,13 @@ protected void addCheckedStandardDefaults(QualifierDefaults defs) {
}

/**
* Adds standard unchecked defaults that do not conflict with previously added defaults.
* Adds both optimistic and conservative unchecked defaults that do not conflict with previously
* added defaults.
*
* @param defs {@link QualifierDefaults} object to which defaults are added
*/
protected void addUncheckedStandardDefaults(QualifierDefaults defs) {
defs.addUncheckedStandardDefaults();
protected void addUncheckedDefaults(QualifierDefaults defs) {
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.

Why rename this method? It will still set the standard defaults. What changed?

defs.addUncheckedDefaults();
}

/**
Expand Down
Loading
Loading