diff --git a/checker-qual/src/main/java/org/checkerframework/checker/calledmethods/qual/CalledMethodsBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/calledmethods/qual/CalledMethodsBottom.java
index 6f2e388c1c2..ecc5d2546f2 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/calledmethods/qual/CalledMethodsBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/calledmethods/qual/CalledMethodsBottom.java
@@ -19,5 +19,5 @@
@SubtypeOf({CalledMethods.class, CalledMethodsPredicate.class})
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
public @interface CalledMethodsBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/compilermsgs/qual/CompilerMessageKeyBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/compilermsgs/qual/CompilerMessageKeyBottom.java
index b1dc0b2350c..f730e685a02 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/compilermsgs/qual/CompilerMessageKeyBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/compilermsgs/qual/CompilerMessageKeyBottom.java
@@ -22,6 +22,6 @@
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@SubtypeOf(CompilerMessageKey.class)
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@DefaultFor(TypeUseLocation.LOWER_BOUND)
public @interface CompilerMessageKeyBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/fenum/qual/FenumBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/fenum/qual/FenumBottom.java
index 4385d9492c3..b48b127a622 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/fenum/qual/FenumBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/fenum/qual/FenumBottom.java
@@ -22,7 +22,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
// Subtype relationships are set up by passing this class as a bottom
// to the multigraph hierarchy constructor.
@SubtypeOf({})
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/fenum/qual/FenumTop.java b/checker-qual/src/main/java/org/checkerframework/checker/fenum/qual/FenumTop.java
index 0123d2518a5..8f0c43b5bff 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/fenum/qual/FenumTop.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/fenum/qual/FenumTop.java
@@ -19,7 +19,12 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({
+ TypeUseLocation.LOWER_BOUND,
+ TypeUseLocation.UPPER_BOUND,
+ TypeUseLocation.LOCAL_VARIABLE,
+ TypeUseLocation.RESOURCE_VARIABLE
+})
@SubtypeOf({})
@DefaultFor({TypeUseLocation.LOCAL_VARIABLE, TypeUseLocation.RESOURCE_VARIABLE})
public @interface FenumTop {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/formatter/qual/FormatBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/formatter/qual/FormatBottom.java
index 9d6aa8186cc..9438cf76820 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/formatter/qual/FormatBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/formatter/qual/FormatBottom.java
@@ -20,7 +20,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf({Format.class, InvalidFormat.class})
@DefaultFor(value = {TypeUseLocation.LOWER_BOUND})
public @interface FormatBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/formatter/qual/UnknownFormat.java b/checker-qual/src/main/java/org/checkerframework/checker/formatter/qual/UnknownFormat.java
index a110ce19bc9..e0512950429 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/formatter/qual/UnknownFormat.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/formatter/qual/UnknownFormat.java
@@ -18,8 +18,8 @@
*
A type annotation indicating that the run-time value might or might not be a valid format
* string.
*
- *
This annotation may not be written in source code; it is an implementation detail of the
- * checker.
+ *
It is usually not necessary to write this annotation in source code. It is an implementation
+ * detail of the checker.
*
* @checker_framework.manual #formatter-checker Format String Checker
*/
@@ -29,5 +29,5 @@
@InvisibleQualifier
@SubtypeOf({})
@DefaultQualifierInHierarchy
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.ALL})
public @interface UnknownFormat {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/i18n/qual/LocalizableKeyBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/i18n/qual/LocalizableKeyBottom.java
index 36e7b6f7e81..f0727f5b9eb 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/i18n/qual/LocalizableKeyBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/i18n/qual/LocalizableKeyBottom.java
@@ -21,7 +21,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf(LocalizableKey.class)
@DefaultFor(TypeUseLocation.LOWER_BOUND)
public @interface LocalizableKeyBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/i18nformatter/qual/I18nFormatBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/i18nformatter/qual/I18nFormatBottom.java
index d05041e49cf..ff45b277970 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/i18nformatter/qual/I18nFormatBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/i18nformatter/qual/I18nFormatBottom.java
@@ -21,7 +21,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf({I18nFormat.class, I18nInvalidFormat.class, I18nFormatFor.class})
@DefaultFor(value = {TypeUseLocation.LOWER_BOUND})
public @interface I18nFormatBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/i18nformatter/qual/I18nUnknownFormat.java b/checker-qual/src/main/java/org/checkerframework/checker/i18nformatter/qual/I18nUnknownFormat.java
index c0f9466c425..66b587b2653 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/i18nformatter/qual/I18nUnknownFormat.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/i18nformatter/qual/I18nUnknownFormat.java
@@ -18,12 +18,15 @@
*
A type annotation indicating that the run-time value might or might not be a valid i18n format
* string.
*
+ *
It is usually not necessary to write this annotation in source code. It is an implementation
+ * detail of the checker.
+ *
* @checker_framework.manual #i18n-formatter-checker Internationalization Format String Checker
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.ALL})
@InvisibleQualifier
@SubtypeOf({})
@DefaultQualifierInHierarchy
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/LowerBoundBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/LowerBoundBottom.java
index e0b937a427c..4bff20599c3 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/LowerBoundBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/LowerBoundBottom.java
@@ -19,6 +19,6 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf({Positive.class})
public @interface LowerBoundBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SameLenBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SameLenBottom.java
index b1ce427d00a..5f4360c00d5 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SameLenBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SameLenBottom.java
@@ -19,6 +19,6 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf(SameLen.class)
public @interface SameLenBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SearchIndexBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SearchIndexBottom.java
index 66cea84cad9..5b36dc568ba 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SearchIndexBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SearchIndexBottom.java
@@ -19,6 +19,6 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf(NegativeIndexFor.class)
public @interface SearchIndexBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SubstringIndexBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SubstringIndexBottom.java
index afd093a4a4f..2fe7a440d4c 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SubstringIndexBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/SubstringIndexBottom.java
@@ -19,6 +19,6 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf(SubstringIndexFor.class)
public @interface SubstringIndexBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/UpperBoundBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/UpperBoundBottom.java
index 75454f12b84..29b373fc5bb 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/UpperBoundBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/UpperBoundBottom.java
@@ -19,6 +19,6 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf({LTOMLengthOf.class, UpperBoundLiteral.class})
public @interface UpperBoundBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/UpperBoundLiteral.java b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/UpperBoundLiteral.java
index 3ed82578bdb..2f29d0d337c 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/index/qual/UpperBoundLiteral.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/index/qual/UpperBoundLiteral.java
@@ -18,7 +18,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf(LTEqLengthOf.class)
public @interface UpperBoundLiteral {
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/initialization/qual/FBCBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/initialization/qual/FBCBottom.java
index 6059d36c15a..0f54368bbc6 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/initialization/qual/FBCBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/initialization/qual/FBCBottom.java
@@ -24,7 +24,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf({UnderInitialization.class, Initialized.class})
@QualifierForLiterals(LiteralKind.NULL)
public @interface FBCBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/GuardSatisfied.java b/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/GuardSatisfied.java
index 6dfaba71bc4..248b373eb12 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/GuardSatisfied.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/GuardSatisfied.java
@@ -33,7 +33,14 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
-@TargetLocations({TypeUseLocation.RECEIVER, TypeUseLocation.PARAMETER, TypeUseLocation.RETURN})
+@TargetLocations({
+ TypeUseLocation.RECEIVER,
+ TypeUseLocation.PARAMETER,
+ TypeUseLocation.RETURN,
+ TypeUseLocation.FIELD,
+ TypeUseLocation.LOCAL_VARIABLE,
+ TypeUseLocation.CONSTRUCTOR_RESULT
+})
@SubtypeOf(GuardedByUnknown.class) // TODO: Should @GuardSatisfied be in its own hierarchy?
public @interface GuardSatisfied {
/**
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/GuardedByBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/GuardedByBottom.java
index 00001cf060b..793eb8069c9 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/GuardedByBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/GuardedByBottom.java
@@ -22,6 +22,6 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf({NewObject.class})
public @interface GuardedByBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/LockPossiblyHeld.java b/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/LockPossiblyHeld.java
index 1b28171f27a..0cc89dae203 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/LockPossiblyHeld.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/LockPossiblyHeld.java
@@ -6,6 +6,7 @@
import org.checkerframework.framework.qual.LiteralKind;
import org.checkerframework.framework.qual.QualifierForLiterals;
import org.checkerframework.framework.qual.SubtypeOf;
+import org.checkerframework.framework.qual.TargetLocations;
import org.checkerframework.framework.qual.TypeUseLocation;
import java.lang.annotation.Documented;
@@ -16,8 +17,8 @@
/**
* Indicates that an expression is not known to be {@link LockHeld}.
*
- *
This annotation may not be written in source code; it is an implementation detail of the
- * checker.
+ *
It is usually not necessary to write this annotation in source code. It is an implementation
+ * detail of the checker.
*
* @see LockHeld
* @checker_framework.manual #lock-checker Lock Checker
@@ -29,5 +30,6 @@
@SubtypeOf({})
@DefaultQualifierInHierarchy
@DefaultFor(value = TypeUseLocation.LOWER_BOUND, types = Void.class)
+@TargetLocations({TypeUseLocation.ALL})
@QualifierForLiterals(LiteralKind.NULL)
public @interface LockPossiblyHeld {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/NewObject.java b/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/NewObject.java
index 9a87643d56e..2fe65e1fac0 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/NewObject.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/lock/qual/NewObject.java
@@ -22,7 +22,12 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({
+ TypeUseLocation.LOWER_BOUND,
+ TypeUseLocation.UPPER_BOUND,
+ TypeUseLocation.CONSTRUCTOR_RESULT,
+ TypeUseLocation.RETURN
+})
@SubtypeOf({GuardedBy.class, GuardSatisfied.class})
@DefaultFor(TypeUseLocation.CONSTRUCTOR_RESULT)
@QualifierForLiterals({LiteralKind.STRING, LiteralKind.PRIMITIVE})
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/nullness/qual/KeyForBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/nullness/qual/KeyForBottom.java
index 1d03442dbf8..5ed2010f703 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/nullness/qual/KeyForBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/nullness/qual/KeyForBottom.java
@@ -22,7 +22,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@InvisibleQualifier
@SubtypeOf(KeyFor.class)
public @interface KeyForBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/propkey/qual/PropertyKeyBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/propkey/qual/PropertyKeyBottom.java
index 8d0c0471948..e45d61a8ab8 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/propkey/qual/PropertyKeyBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/propkey/qual/PropertyKeyBottom.java
@@ -21,7 +21,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf(PropertyKey.class)
@DefaultFor(TypeUseLocation.LOWER_BOUND)
public @interface PropertyKeyBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/regex/qual/RegexBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/regex/qual/RegexBottom.java
index 45c69bd0040..301b6b74fc4 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/regex/qual/RegexBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/regex/qual/RegexBottom.java
@@ -21,7 +21,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@InvisibleQualifier
@SubtypeOf({Regex.class, org.checkerframework.checker.regex.qual.PartialRegex.class})
@DefaultFor(value = {TypeUseLocation.LOWER_BOUND})
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/regex/qual/UnknownRegex.java b/checker-qual/src/main/java/org/checkerframework/checker/regex/qual/UnknownRegex.java
index 626fd8657f3..398b04b7398 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/regex/qual/UnknownRegex.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/regex/qual/UnknownRegex.java
@@ -20,7 +20,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.ALL})
@InvisibleQualifier
@SubtypeOf({})
@DefaultQualifierInHierarchy
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/signature/qual/SignatureBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/signature/qual/SignatureBottom.java
index 9496508d547..91cdba36d25 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/signature/qual/SignatureBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/signature/qual/SignatureBottom.java
@@ -20,7 +20,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf({
FieldDescriptorForPrimitive.class,
PrimitiveType.class,
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/signedness/qual/SignednessBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/signedness/qual/SignednessBottom.java
index ea92761feaf..33ec7578e0e 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/signedness/qual/SignednessBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/signedness/qual/SignednessBottom.java
@@ -21,6 +21,9 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({
+ TypeUseLocation.LOWER_BOUND,
+ TypeUseLocation.UPPER_BOUND,
+})
@SubtypeOf({SignedPositiveFromUnsigned.class})
public @interface SignednessBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/checker/units/qual/UnitsBottom.java b/checker-qual/src/main/java/org/checkerframework/checker/units/qual/UnitsBottom.java
index 72a10f6b0c6..1c0eb735f01 100644
--- a/checker-qual/src/main/java/org/checkerframework/checker/units/qual/UnitsBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/checker/units/qual/UnitsBottom.java
@@ -20,7 +20,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf({}) // needs to be done programmatically
@DefaultFor(TypeUseLocation.LOWER_BOUND)
public @interface UnitsBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/common/initializedfields/qual/InitializedFieldsBottom.java b/checker-qual/src/main/java/org/checkerframework/common/initializedfields/qual/InitializedFieldsBottom.java
index 7e80adbe808..628c199eca5 100644
--- a/checker-qual/src/main/java/org/checkerframework/common/initializedfields/qual/InitializedFieldsBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/common/initializedfields/qual/InitializedFieldsBottom.java
@@ -18,5 +18,5 @@
@SubtypeOf({InitializedFields.class})
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
public @interface InitializedFieldsBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/ClassValBottom.java b/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/ClassValBottom.java
index d143d19cc53..e68c8281686 100644
--- a/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/ClassValBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/ClassValBottom.java
@@ -20,7 +20,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@InvisibleQualifier
@SubtypeOf({ClassVal.class, ClassBound.class})
public @interface ClassValBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/MethodValBottom.java b/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/MethodValBottom.java
index 6c202c8e44d..3e39e6b04d2 100644
--- a/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/MethodValBottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/MethodValBottom.java
@@ -20,7 +20,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@InvisibleQualifier
@SubtypeOf({MethodVal.class})
public @interface MethodValBottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/UnknownClass.java b/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/UnknownClass.java
index 57a6988f3cc..ccea4c45929 100644
--- a/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/UnknownClass.java
+++ b/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/UnknownClass.java
@@ -23,7 +23,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.ALL})
@InvisibleQualifier
@SubtypeOf({})
@DefaultQualifierInHierarchy
diff --git a/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/UnknownMethod.java b/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/UnknownMethod.java
index 15ad2e035a3..bf556909632 100644
--- a/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/UnknownMethod.java
+++ b/checker-qual/src/main/java/org/checkerframework/common/reflection/qual/UnknownMethod.java
@@ -24,7 +24,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.ALL})
@InvisibleQualifier
@SubtypeOf({})
@DefaultQualifierInHierarchy
diff --git a/checker-qual/src/main/java/org/checkerframework/common/returnsreceiver/qual/BottomThis.java b/checker-qual/src/main/java/org/checkerframework/common/returnsreceiver/qual/BottomThis.java
index 1147536e871..a3e0f92d8bf 100644
--- a/checker-qual/src/main/java/org/checkerframework/common/returnsreceiver/qual/BottomThis.java
+++ b/checker-qual/src/main/java/org/checkerframework/common/returnsreceiver/qual/BottomThis.java
@@ -19,5 +19,5 @@
@SubtypeOf({UnknownThis.class})
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
public @interface BottomThis {}
diff --git a/checker-qual/src/main/java/org/checkerframework/common/subtyping/qual/Bottom.java b/checker-qual/src/main/java/org/checkerframework/common/subtyping/qual/Bottom.java
index 0630b187696..93c521d8964 100644
--- a/checker-qual/src/main/java/org/checkerframework/common/subtyping/qual/Bottom.java
+++ b/checker-qual/src/main/java/org/checkerframework/common/subtyping/qual/Bottom.java
@@ -29,5 +29,5 @@
@Documented
@SubtypeOf({})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
public @interface Bottom {}
diff --git a/checker-qual/src/main/java/org/checkerframework/common/value/qual/BottomVal.java b/checker-qual/src/main/java/org/checkerframework/common/value/qual/BottomVal.java
index 5742400dad0..26b00d63827 100644
--- a/checker-qual/src/main/java/org/checkerframework/common/value/qual/BottomVal.java
+++ b/checker-qual/src/main/java/org/checkerframework/common/value/qual/BottomVal.java
@@ -20,7 +20,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.UPPER_BOUND, TypeUseLocation.LOWER_BOUND})
@SubtypeOf({
ArrayLen.class,
BoolVal.class,
diff --git a/checker-qual/src/main/java/org/checkerframework/framework/qual/TargetLocations.java b/checker-qual/src/main/java/org/checkerframework/framework/qual/TargetLocations.java
index 7382cb51a20..d1f544e7017 100644
--- a/checker-qual/src/main/java/org/checkerframework/framework/qual/TargetLocations.java
+++ b/checker-qual/src/main/java/org/checkerframework/framework/qual/TargetLocations.java
@@ -7,31 +7,37 @@
import java.lang.annotation.Target;
/**
- * NOTE: This meta-annotation is not currently
- * enforced.
- *
- *
A meta-annotation that restricts the type-use locations where a type qualifier may be written.
+ * A meta-annotation that restricts the type-use locations where a type qualifier may be applied.
* When written together with {@code @Target({ElementType.TYPE_USE})}, the given type qualifier may
- * be written only at locations listed in the {@code @TargetLocations(...)} meta-annotation.
+ * be applied only at locations listed in the {@code @TargetLocations(...)} meta-annotation.
* {@code @Target({ElementType.TYPE_USE})} together with no {@code @TargetLocations(...)} means that
- * the qualifier can be written on any type use.
+ * the qualifier can be applied to any type use. {@code @TargetLocations({})} means that the
+ * qualifier should not be used in source code. The same goal can be achieved by writing
+ * {@code @Target({})}, which is enforced by javac itself. {@code @TargetLocations({...})} is
+ * enforced by the checker. The resulting errors from the checker can either be suppressed using
+ * {@code @SuppressWarnings("type.invalid.annotations.on.location")} or can be ignored by providing
+ * the {@code -AignoreTargetLocations} option.
*
- *
This enables a type system designer to permit a qualifier to be written only in certain
+ *
This enables a type system designer to permit a qualifier to be applied only in certain
* locations. For example, some type systems' top and bottom qualifier (such as {@link
- * org.checkerframework.checker.nullness.qual.KeyForBottom}) should only be written on an explicit
+ * org.checkerframework.checker.regex.qual.RegexBottom}) should only be written on an explicit
* wildcard upper or lower bound. This meta-annotation is a declarative, coarse-grained approach to
* enable that. For finer-grained control, override {@code visit*} methods that visit trees in
* BaseTypeVisitor.
*
- *
This annotation does not prevent the type system from defaulting, inferring, or computing the
- * given type annotation at the given location. It only prevents users from writing an explicit
- * annotation at the given location.
+ *
{@code @TargetLocations} are used for all appearances of qualifiers regardless of whether they
+ * are provided explicitly or implicitly (inferred or computed). Therefore, only use type-use
+ * locations {@code LOWER_BOUND/UPPER_BOUND} instead of the {@code IMPLICIT_XX/EXPLICIT_XX}
+ * alternatives.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface TargetLocations {
- /** Type uses at which the qualifier is permitted to be written in source code. */
+ /**
+ * Type uses at which the qualifier is permitted to be applied in source code.
+ *
+ * @return type-use locations declared in this meta-annotation
+ */
TypeUseLocation[] value();
}
diff --git a/checker-qual/src/main/java/org/checkerframework/framework/qual/TypeUseLocation.java b/checker-qual/src/main/java/org/checkerframework/framework/qual/TypeUseLocation.java
index 96a3db427f1..59b771a5b6a 100644
--- a/checker-qual/src/main/java/org/checkerframework/framework/qual/TypeUseLocation.java
+++ b/checker-qual/src/main/java/org/checkerframework/framework/qual/TypeUseLocation.java
@@ -6,6 +6,13 @@
*
The order of enums is important. Defaults are applied in this order. In particular, this means
* that OTHERWISE and ALL should be last.
*
+ *
For an annotation on a variable which has element kind ENUM_CONSTANT, the annotation's
+ * type-use location is either {@code TypeUseLocation.FIELD} or {@code
+ * TypeUseLocation.CONSTRUCTOR_RESULT}.
+ *
+ *
Note: The use locations listed here are not complete, for more details see EISOP Issue #340
+ *
* @see DefaultQualifier
* @see javax.lang.model.element.ElementKind
*/
@@ -45,7 +52,7 @@ public enum TypeUseLocation {
/**
* Apply default annotations to unannotated lower bounds for type variables and wildcards both
- * explicit ones in {@code extends} clauses, and implicit upper bounds when no explicit {@code
+ * explicit ones in {@code super} clauses, and implicit lower bounds when no explicit {@code
* extends} or {@code super} clause is present.
*/
LOWER_BOUND,
diff --git a/checker/jtreg/sortwarnings/ErrorOrders.java b/checker/jtreg/sortwarnings/ErrorOrders.java
index 53c36bcc8a3..f2f8dec12f0 100644
--- a/checker/jtreg/sortwarnings/ErrorOrders.java
+++ b/checker/jtreg/sortwarnings/ErrorOrders.java
@@ -13,6 +13,8 @@ void test2(int i, int[] a) {
a[i] = 2;
}
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ @SuppressWarnings("type.invalid.annotations.on.location")
int test4(
@GTENegativeOne @UpperBoundBottom int p1,
@UpperBoundBottom @GTENegativeOne int p2,
@@ -45,6 +47,8 @@ void test2(int i, int[] a) {
a[i] = 2;
}
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ @SuppressWarnings("type.invalid.annotations.on.location")
int test4(
@GTENegativeOne @UpperBoundBottom int p1,
@UpperBoundBottom @GTENegativeOne int p2,
diff --git a/checker/jtreg/sortwarnings/ErrorOrders.out b/checker/jtreg/sortwarnings/ErrorOrders.out
index b9b36485398..69eb381caaf 100644
--- a/checker/jtreg/sortwarnings/ErrorOrders.out
+++ b/checker/jtreg/sortwarnings/ErrorOrders.out
@@ -1,16 +1,16 @@
-OrderOfCheckers.java:12:99: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
+OrderOfCheckers.java:14:99: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @UnknownVal int @UnknownVal []
required: @UnknownVal int @BottomVal []
-OrderOfCheckers.java:12:99: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
+OrderOfCheckers.java:14:99: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : int []
required: @SearchIndexBottom int []
-OrderOfCheckers.java:12:99: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
+OrderOfCheckers.java:14:99: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : int @SameLen("y") []
required: int @SameLenBottom []
-OrderOfCheckers.java:12:99: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
+OrderOfCheckers.java:14:99: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : int []
required: @GTENegativeOne int []
-OrderOfCheckers.java:12:99: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
+OrderOfCheckers.java:14:99: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : int []
required: @UpperBoundBottom int []
ErrorOrders.java:13:11: compiler.err.proc.messager: [array.access.unsafe.low] Potentially unsafe array access: the index could be negative.
@@ -19,122 +19,122 @@ required: an integer >= 0 (@NonNegative or @Positive)
ErrorOrders.java:13:11: compiler.err.proc.messager: [array.access.unsafe.high] Potentially unsafe array access: the index could be larger than the array's bound
found : int
required: @IndexFor("a") or @LTLengthOf("a") -- an integer less than a's length
-ErrorOrders.java:23:33: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
+ErrorOrders.java:25:33: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @UpperBoundLiteral(0) int
required: @LTLengthOf("p2") int
-ErrorOrders.java:24:47: compiler.err.proc.messager: [expression.unparsable.type.invalid] Expression invalid in dependent type annotation: [error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]
-ErrorOrders.java:24:55: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
+ErrorOrders.java:26:47: compiler.err.proc.messager: [expression.unparsable.type.invalid] Expression invalid in dependent type annotation: [error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]
+ErrorOrders.java:26:55: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @LTLengthOf("p2") int
required: @LTLengthOf("[error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]") int
-ErrorOrders.java:29:15: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
+ErrorOrders.java:31:15: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
found : int
required: @GTENegativeOne int
-ErrorOrders.java:29:15: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
+ErrorOrders.java:31:15: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
found : int
required: @UpperBoundBottom int
-ErrorOrders.java:29:24: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
+ErrorOrders.java:31:24: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
found : int
required: @GTENegativeOne int
-ErrorOrders.java:29:24: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
+ErrorOrders.java:31:24: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
found : int
required: @UpperBoundBottom int
-ErrorOrders.java:29:25: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
+ErrorOrders.java:31:25: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
found : int
required: @GTENegativeOne int
-ErrorOrders.java:29:25: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
+ErrorOrders.java:31:25: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
found : int
required: @UpperBoundBottom int
-ErrorOrders.java:29:29: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
+ErrorOrders.java:31:29: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
found : int
required: @GTENegativeOne int
-ErrorOrders.java:29:29: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
+ErrorOrders.java:31:29: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
found : int
required: @UpperBoundBottom int
-ErrorOrders.java:29:33: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p3 of test4.
+ErrorOrders.java:31:33: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p3 of test4.
found : @UnknownVal int @UnknownVal []
required: @UnknownVal int @BottomVal []
-ErrorOrders.java:29:37: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p4 of test4.
+ErrorOrders.java:31:37: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p4 of test4.
found : int @SameLen("p4") []
required: int @SameLenBottom []
-ErrorOrders.java:29:41: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p5 of test4.
+ErrorOrders.java:31:41: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p5 of test4.
found : @UnknownVal int
required: @BottomVal int
-ErrorOrders.java:29:46: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p3 of test4.
+ErrorOrders.java:31:46: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p3 of test4.
found : @UnknownVal int @UnknownVal []
required: @UnknownVal int @BottomVal []
-ErrorOrders.java:29:50: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p4 of test4.
+ErrorOrders.java:31:50: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p4 of test4.
found : int @SameLen("p4") []
required: int @SameLenBottom []
-ErrorOrders.java:29:54: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p5 of test4.
+ErrorOrders.java:31:54: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p5 of test4.
found : @UnknownVal int
required: @BottomVal int
-ErrorOrders.java:33:47: compiler.err.proc.messager: [expression.unparsable.type.invalid] Expression invalid in dependent type annotation: [error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]
-ErrorOrders.java:33:55: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
+ErrorOrders.java:35:47: compiler.err.proc.messager: [expression.unparsable.type.invalid] Expression invalid in dependent type annotation: [error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]
+ErrorOrders.java:35:55: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @UpperBoundLiteral(0) int
required: @LTLengthOf("[error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]") int
-ErrorOrders.java:36:15: compiler.err.proc.messager: [array.access.unsafe.low] Potentially unsafe array access: the index could be negative.
+ErrorOrders.java:38:15: compiler.err.proc.messager: [array.access.unsafe.low] Potentially unsafe array access: the index could be negative.
found : int
required: an integer >= 0 (@NonNegative or @Positive)
-ErrorOrders.java:36:15: compiler.err.proc.messager: [array.access.unsafe.high] Potentially unsafe array access: the index could be larger than the array's bound
+ErrorOrders.java:38:15: compiler.err.proc.messager: [array.access.unsafe.high] Potentially unsafe array access: the index could be larger than the array's bound
found : int
required: @IndexFor("a") or @LTLengthOf("a") -- an integer less than a's length
-ErrorOrders.java:42:43: compiler.err.proc.messager: [expression.unparsable.type.invalid] Expression invalid in dependent type annotation: [error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]
-ErrorOrders.java:42:51: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
+ErrorOrders.java:44:43: compiler.err.proc.messager: [expression.unparsable.type.invalid] Expression invalid in dependent type annotation: [error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]
+ErrorOrders.java:44:51: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @UpperBoundLiteral(0) int
required: @LTLengthOf("[error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]") int
-ErrorOrders.java:45:11: compiler.err.proc.messager: [array.access.unsafe.low] Potentially unsafe array access: the index could be negative.
+ErrorOrders.java:47:11: compiler.err.proc.messager: [array.access.unsafe.low] Potentially unsafe array access: the index could be negative.
found : int
required: an integer >= 0 (@NonNegative or @Positive)
-ErrorOrders.java:45:11: compiler.err.proc.messager: [array.access.unsafe.high] Potentially unsafe array access: the index could be larger than the array's bound
+ErrorOrders.java:47:11: compiler.err.proc.messager: [array.access.unsafe.high] Potentially unsafe array access: the index could be larger than the array's bound
found : int
required: @IndexFor("a") or @LTLengthOf("a") -- an integer less than a's length
-ErrorOrders.java:55:33: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
+ErrorOrders.java:59:33: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @UpperBoundLiteral(0) int
required: @LTLengthOf("p2") int
-ErrorOrders.java:56:47: compiler.err.proc.messager: [expression.unparsable.type.invalid] Expression invalid in dependent type annotation: [error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]
-ErrorOrders.java:56:55: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
+ErrorOrders.java:60:47: compiler.err.proc.messager: [expression.unparsable.type.invalid] Expression invalid in dependent type annotation: [error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]
+ErrorOrders.java:60:55: compiler.err.proc.messager: [assignment.type.incompatible] incompatible types in assignment.
found : @LTLengthOf("p2") int
required: @LTLengthOf("[error for expression: This isn't an expression; error: Invalid 'This isn't an expression' because the expression did not parse. Error message: Encountered unexpected token: "isn" ]") int
-ErrorOrders.java:61:15: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
+ErrorOrders.java:65:15: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
found : int
required: @GTENegativeOne int
-ErrorOrders.java:61:15: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
+ErrorOrders.java:65:15: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
found : int
required: @UpperBoundBottom int
-ErrorOrders.java:61:24: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
+ErrorOrders.java:65:24: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
found : int
required: @GTENegativeOne int
-ErrorOrders.java:61:24: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
+ErrorOrders.java:65:24: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
found : int
required: @UpperBoundBottom int
-ErrorOrders.java:61:25: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
+ErrorOrders.java:65:25: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
found : int
required: @GTENegativeOne int
-ErrorOrders.java:61:25: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
+ErrorOrders.java:65:25: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p1 of test4.
found : int
required: @UpperBoundBottom int
-ErrorOrders.java:61:29: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
+ErrorOrders.java:65:29: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
found : int
required: @GTENegativeOne int
-ErrorOrders.java:61:29: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
+ErrorOrders.java:65:29: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p2 of test4.
found : int
required: @UpperBoundBottom int
-ErrorOrders.java:61:33: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p3 of test4.
+ErrorOrders.java:65:33: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p3 of test4.
found : @UnknownVal int @UnknownVal []
required: @UnknownVal int @BottomVal []
-ErrorOrders.java:61:37: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p4 of test4.
+ErrorOrders.java:65:37: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p4 of test4.
found : int @SameLen("p4") []
required: int @SameLenBottom []
-ErrorOrders.java:61:41: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p5 of test4.
+ErrorOrders.java:65:41: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p5 of test4.
found : @UnknownVal int
required: @BottomVal int
-ErrorOrders.java:61:46: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p3 of test4.
+ErrorOrders.java:65:46: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p3 of test4.
found : @UnknownVal int @UnknownVal []
required: @UnknownVal int @BottomVal []
-ErrorOrders.java:61:50: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p4 of test4.
+ErrorOrders.java:65:50: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p4 of test4.
found : int @SameLen("p4") []
required: int @SameLenBottom []
-ErrorOrders.java:61:54: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p5 of test4.
+ErrorOrders.java:65:54: compiler.err.proc.messager: [argument.type.incompatible] incompatible argument for parameter p5 of test4.
found : @UnknownVal int
required: @BottomVal int
49 errors
diff --git a/checker/jtreg/sortwarnings/OrderOfCheckers.java b/checker/jtreg/sortwarnings/OrderOfCheckers.java
index 3f59a3c40d0..b1c2df2104d 100644
--- a/checker/jtreg/sortwarnings/OrderOfCheckers.java
+++ b/checker/jtreg/sortwarnings/OrderOfCheckers.java
@@ -8,6 +8,8 @@
/** This class tests that errors issued on the same tree are sorted by checker. */
public class OrderOfCheckers {
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ @SuppressWarnings("type.invalid.annotations.on.location")
void test(int[] y) {
@GTENegativeOne @UpperBoundBottom @SearchIndexBottom int @BottomVal @SameLenBottom [] x = y;
}
diff --git a/checker/jtreg/sortwarnings/OrderOfCheckers.out b/checker/jtreg/sortwarnings/OrderOfCheckers.out
index f250b7b9217..479526be3c2 100644
--- a/checker/jtreg/sortwarnings/OrderOfCheckers.out
+++ b/checker/jtreg/sortwarnings/OrderOfCheckers.out
@@ -1,16 +1,16 @@
-OrderOfCheckers.java:12:99: compiler.err.proc.messager: [[value, allcheckers]:assignment.type.incompatible] incompatible types in assignment.
+OrderOfCheckers.java:14:99: compiler.err.proc.messager: [[value, allcheckers]:assignment.type.incompatible] incompatible types in assignment.
found : @UnknownVal int @UnknownVal []
required: @UnknownVal int @BottomVal []
-OrderOfCheckers.java:12:99: compiler.err.proc.messager: [[index, searchindex, allcheckers]:assignment.type.incompatible] incompatible types in assignment.
+OrderOfCheckers.java:14:99: compiler.err.proc.messager: [[index, searchindex, allcheckers]:assignment.type.incompatible] incompatible types in assignment.
found : int []
required: @SearchIndexBottom int []
-OrderOfCheckers.java:12:99: compiler.err.proc.messager: [[index, samelen, allcheckers]:assignment.type.incompatible] incompatible types in assignment.
+OrderOfCheckers.java:14:99: compiler.err.proc.messager: [[index, samelen, allcheckers]:assignment.type.incompatible] incompatible types in assignment.
found : int @SameLen("y") []
required: int @SameLenBottom []
-OrderOfCheckers.java:12:99: compiler.err.proc.messager: [[index, lowerbound, allcheckers]:assignment.type.incompatible] incompatible types in assignment.
+OrderOfCheckers.java:14:99: compiler.err.proc.messager: [[index, lowerbound, allcheckers]:assignment.type.incompatible] incompatible types in assignment.
found : int []
required: @GTENegativeOne int []
-OrderOfCheckers.java:12:99: compiler.err.proc.messager: [[index, upperbound, allcheckers]:assignment.type.incompatible] incompatible types in assignment.
+OrderOfCheckers.java:14:99: compiler.err.proc.messager: [[index, upperbound, allcheckers]:assignment.type.incompatible] incompatible types in assignment.
found : int []
required: @UpperBoundBottom int []
5 errors
diff --git a/checker/src/test/java/org/checkerframework/checker/test/junit/CalledMethodsTest.java b/checker/src/test/java/org/checkerframework/checker/test/junit/CalledMethodsTest.java
index f65fd30488a..ac396d83db1 100644
--- a/checker/src/test/java/org/checkerframework/checker/test/junit/CalledMethodsTest.java
+++ b/checker/src/test/java/org/checkerframework/checker/test/junit/CalledMethodsTest.java
@@ -15,6 +15,8 @@ public CalledMethodsTest(List testFiles) {
CalledMethodsChecker.class,
"calledmethods",
"-nowarn",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations",
"-encoding",
"UTF-8");
}
diff --git a/checker/src/test/java/org/checkerframework/checker/test/junit/FenumSwingTest.java b/checker/src/test/java/org/checkerframework/checker/test/junit/FenumSwingTest.java
index f7b3b66d998..dfc7f55fb4c 100644
--- a/checker/src/test/java/org/checkerframework/checker/test/junit/FenumSwingTest.java
+++ b/checker/src/test/java/org/checkerframework/checker/test/junit/FenumSwingTest.java
@@ -18,7 +18,9 @@ public FenumSwingTest(List testFiles) {
testFiles,
org.checkerframework.checker.fenum.FenumChecker.class,
"fenum",
- "-Aquals=org.checkerframework.checker.fenum.qual.SwingVerticalOrientation,org.checkerframework.checker.fenum.qual.SwingHorizontalOrientation,org.checkerframework.checker.fenum.qual.SwingBoxOrientation,org.checkerframework.checker.fenum.qual.SwingCompassDirection,org.checkerframework.checker.fenum.qual.SwingElementOrientation,org.checkerframework.checker.fenum.qual.SwingTextOrientation");
+ "-Aquals=org.checkerframework.checker.fenum.qual.SwingVerticalOrientation,org.checkerframework.checker.fenum.qual.SwingHorizontalOrientation,org.checkerframework.checker.fenum.qual.SwingBoxOrientation,org.checkerframework.checker.fenum.qual.SwingCompassDirection,org.checkerframework.checker.fenum.qual.SwingElementOrientation,org.checkerframework.checker.fenum.qual.SwingTextOrientation",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations");
// TODO: check all qualifiers
}
diff --git a/checker/src/test/java/org/checkerframework/checker/test/junit/I18nTest.java b/checker/src/test/java/org/checkerframework/checker/test/junit/I18nTest.java
index a031bcdedfb..bd0e3687a65 100644
--- a/checker/src/test/java/org/checkerframework/checker/test/junit/I18nTest.java
+++ b/checker/src/test/java/org/checkerframework/checker/test/junit/I18nTest.java
@@ -14,7 +14,12 @@ public class I18nTest extends CheckerFrameworkPerDirectoryTest {
* @param testFiles the files containing test code, which will be type-checked
*/
public I18nTest(List testFiles) {
- super(testFiles, org.checkerframework.checker.i18n.I18nChecker.class, "i18n");
+ super(
+ testFiles,
+ org.checkerframework.checker.i18n.I18nChecker.class,
+ "i18n",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations");
}
@Parameters
diff --git a/checker/src/test/java/org/checkerframework/checker/test/junit/IndexInitializedFieldsTest.java b/checker/src/test/java/org/checkerframework/checker/test/junit/IndexInitializedFieldsTest.java
index dc34d3b7478..cdd19fb988a 100644
--- a/checker/src/test/java/org/checkerframework/checker/test/junit/IndexInitializedFieldsTest.java
+++ b/checker/src/test/java/org/checkerframework/checker/test/junit/IndexInitializedFieldsTest.java
@@ -24,7 +24,9 @@ public IndexInitializedFieldsTest(List testFiles) {
"org.checkerframework.common.initializedfields.InitializedFieldsChecker"),
"index-initializedfields",
Collections.emptyList(),
- "-Aajava=tests/index-initializedfields/input-annotation-files/");
+ "-Aajava=tests/index-initializedfields/input-annotation-files/",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations");
}
@Parameters
diff --git a/checker/src/test/java/org/checkerframework/checker/test/junit/IndexTest.java b/checker/src/test/java/org/checkerframework/checker/test/junit/IndexTest.java
index 38209b68031..4cae656a319 100644
--- a/checker/src/test/java/org/checkerframework/checker/test/junit/IndexTest.java
+++ b/checker/src/test/java/org/checkerframework/checker/test/junit/IndexTest.java
@@ -15,7 +15,12 @@ public class IndexTest extends CheckerFrameworkPerDirectoryTest {
* @param testFiles the files containing test code, which will be type-checked
*/
public IndexTest(List testFiles) {
- super(testFiles, org.checkerframework.checker.index.IndexChecker.class, "index");
+ super(
+ testFiles,
+ org.checkerframework.checker.index.IndexChecker.class,
+ "index",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations");
}
@Parameters
diff --git a/checker/src/test/java/org/checkerframework/checker/test/junit/LockTest.java b/checker/src/test/java/org/checkerframework/checker/test/junit/LockTest.java
index 67efab91427..7327a154632 100644
--- a/checker/src/test/java/org/checkerframework/checker/test/junit/LockTest.java
+++ b/checker/src/test/java/org/checkerframework/checker/test/junit/LockTest.java
@@ -14,7 +14,12 @@ public class LockTest extends CheckerFrameworkPerDirectoryTest {
* @param testFiles the files containing test code, which will be type-checked
*/
public LockTest(List testFiles) {
- super(testFiles, org.checkerframework.checker.lock.LockChecker.class, "lock");
+ super(
+ testFiles,
+ org.checkerframework.checker.lock.LockChecker.class,
+ "lock",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations");
}
@Parameters
diff --git a/checker/src/test/java/org/checkerframework/checker/test/junit/SignednessTest.java b/checker/src/test/java/org/checkerframework/checker/test/junit/SignednessTest.java
index 1d9c0ef2446..c5f0946897b 100644
--- a/checker/src/test/java/org/checkerframework/checker/test/junit/SignednessTest.java
+++ b/checker/src/test/java/org/checkerframework/checker/test/junit/SignednessTest.java
@@ -17,7 +17,9 @@ public SignednessTest(List testFiles) {
super(
testFiles,
org.checkerframework.checker.signedness.SignednessChecker.class,
- "signedness");
+ "signedness",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations");
}
@Parameters
diff --git a/checker/src/test/java/org/checkerframework/checker/test/junit/ValueIndexInteractionTest.java b/checker/src/test/java/org/checkerframework/checker/test/junit/ValueIndexInteractionTest.java
index 8e85a4f4fbc..edcaa5767f4 100644
--- a/checker/src/test/java/org/checkerframework/checker/test/junit/ValueIndexInteractionTest.java
+++ b/checker/src/test/java/org/checkerframework/checker/test/junit/ValueIndexInteractionTest.java
@@ -18,7 +18,9 @@ public ValueIndexInteractionTest(List testFiles) {
super(
testFiles,
org.checkerframework.common.value.ValueChecker.class,
- "value-index-interaction");
+ "value-index-interaction",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations");
}
@Parameters
diff --git a/checker/src/test/java/org/checkerframework/checker/testchecker/ainfer/qual/AinferBottom.java b/checker/src/test/java/org/checkerframework/checker/testchecker/ainfer/qual/AinferBottom.java
index dc9cf44522d..17af7931bc5 100644
--- a/checker/src/test/java/org/checkerframework/checker/testchecker/ainfer/qual/AinferBottom.java
+++ b/checker/src/test/java/org/checkerframework/checker/testchecker/ainfer/qual/AinferBottom.java
@@ -15,6 +15,6 @@
*/
@SubtypeOf({AinferImplicitAnno.class})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@DefaultFor(TypeUseLocation.LOWER_BOUND)
public @interface AinferBottom {}
diff --git a/checker/tests/i18n/Issue2163FinalI18n.java b/checker/tests/i18n/Issue2163FinalI18n.java
index 6a0de71a1e7..5d0191be291 100644
--- a/checker/tests/i18n/Issue2163FinalI18n.java
+++ b/checker/tests/i18n/Issue2163FinalI18n.java
@@ -38,8 +38,9 @@
}
@LocalizableKeyBottom class Issue2163FinalCB {
- // :: error: (type.invalid.annotations.on.use) :: warning: (inconsistent.constructor.type) ::
- // error: (super.invocation.invalid)
+ // :: warning: (inconsistent.constructor.type)
+ // :: error: (super.invocation.invalid)
+ // :: error: (type.invalid.annotations.on.use)
@LocalizableKey Issue2163FinalCB() {}
}
diff --git a/checker/tests/nullness/KeyForLub.java b/checker/tests/nullness/KeyForLub.java
index 03159a611d4..94b2b62fca7 100644
--- a/checker/tests/nullness/KeyForLub.java
+++ b/checker/tests/nullness/KeyForLub.java
@@ -32,11 +32,12 @@ void method(
return flag ? key1 : poly;
}
+ // :: error: (type.invalid.annotations.on.location)
void poly2(@PolyKeyFor String poly, @UnknownKeyFor String unknown, @KeyForBottom String bot) {
// :: error: (assignment.type.incompatible)
@PolyKeyFor String s1 = flag ? poly : unknown;
@PolyKeyFor String s2 = flag ? poly : bot;
- // :: error: (assignment.type.incompatible)
+ // :: error: (assignment.type.incompatible) :: error: (type.invalid.annotations.on.location)
@KeyForBottom String s3 = flag ? poly : bot;
}
}
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 908de8bedcd..6d9691c2a69 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -19,6 +19,13 @@ Fixed a bug in the Nullness Checker where an instance receiver is incorrectly ma
a static method or field access. This could lead to new nullness errors. The static access should be
changed to be through a class name.
+Checkers now enforce `@TargetLocations` meta-annotations: if a qualifier is declared with the
+meta-annotation `@TargetLocations({TypeUseLocation...})`, the qualifier should only be applied to
+these type use locations.
+The new command-line argument `-AignoreTargetLocations` disables validating the target locations
+of qualifiers. This option is not enabled by default. With this flag, the checker ignores all
+`@TargetLocations` meta-annotations and allows all qualifiers to be applied to every type use.
+
**Implementation details:**
Corrected the arguments to an `ObjectCreationNode` when the node refers to an
@@ -38,7 +45,7 @@ Changed the return types of
**Closed issues:**
-eisop#297, eisop#376, eisop#400, eisop#519, eisop#532, eisop#533, typetools#1590.
+eisop#297, eisop#376, eisop#400, eisop#519, eisop#532, eisop#533, typetools#1590, typetools#1919.
Version 3.34.0-eisop1 (May 9, 2023)
diff --git a/docs/manual/creating-a-checker.tex b/docs/manual/creating-a-checker.tex
index a8f43de3e7c..dae63b24c98 100644
--- a/docs/manual/creating-a-checker.tex
+++ b/docs/manual/creating-a-checker.tex
@@ -814,7 +814,7 @@
%
\begin{Verbatim}
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
\end{Verbatim}
Furthermore, by convention the name of such a qualifier ends with ``\''.
diff --git a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeValidator.java b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeValidator.java
index 3189ebea7d8..5b74b0bfa8b 100644
--- a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeValidator.java
+++ b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeValidator.java
@@ -13,6 +13,7 @@
import org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey;
import org.checkerframework.checker.nullness.qual.Nullable;
+import org.checkerframework.framework.qual.TypeUseLocation;
import org.checkerframework.framework.source.DiagMessage;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
@@ -36,6 +37,7 @@
import org.checkerframework.javacutil.TypesUtils;
import org.plumelib.util.ArrayMap;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -686,6 +688,7 @@ public Void visitWildcard(AnnotatedWildcardType type, Tree tree) {
reportInvalidBounds(type, tree);
}
+ validateWildCardTargetLocation(type, tree);
return super.visitWildcard(type, tree);
}
@@ -712,4 +715,62 @@ public boolean areBoundsValid(
return true;
}
+
+ /**
+ * Validate if qualifiers on wildcard are permitted by {@link
+ * org.checkerframework.framework.qual.TargetLocations}. Report an error if the actual use of
+ * this annotation is not listed in the declared TypeUseLocations in this meta-annotation.
+ *
+ * @param type the type to check
+ * @param tree the tree of this type
+ */
+ protected void validateWildCardTargetLocation(AnnotatedWildcardType type, Tree tree) {
+ if (visitor.ignoreTargetLocations) {
+ return;
+ }
+
+ for (AnnotationMirror am : type.getSuperBound().getAnnotations()) {
+ List locations =
+ visitor.qualAllowedLocations.get(AnnotationUtils.annotationName(am));
+ // @Target({ElementType.TYPE_USE})} together with no @TargetLocations(...) means
+ // that the qualifier can be written on any type use.
+ // Otherwise, for a valid use of qualifier on the super bound, that qualifier must
+ // declare one of these four type-use locations in the @TargetLocations meta-annotation.
+ List lowerLocations =
+ Arrays.asList(
+ TypeUseLocation.ALL,
+ TypeUseLocation.LOWER_BOUND,
+ TypeUseLocation.IMPLICIT_LOWER_BOUND,
+ TypeUseLocation.EXPLICIT_LOWER_BOUND);
+ if (locations == null || locations.stream().anyMatch(lowerLocations::contains)) {
+ continue;
+ }
+
+ checker.reportError(
+ tree,
+ "type.invalid.annotations.on.location",
+ type.getSuperBound().getAnnotations().toString(),
+ "SUPER_WILDCARD");
+ }
+
+ for (AnnotationMirror am : type.getExtendsBound().getAnnotations()) {
+ List locations =
+ visitor.qualAllowedLocations.get(AnnotationUtils.annotationName(am));
+ List upperLocations =
+ Arrays.asList(
+ TypeUseLocation.ALL,
+ TypeUseLocation.UPPER_BOUND,
+ TypeUseLocation.IMPLICIT_UPPER_BOUND,
+ TypeUseLocation.EXPLICIT_UPPER_BOUND);
+ if (locations == null || locations.stream().anyMatch(upperLocations::contains)) {
+ continue;
+ }
+
+ checker.reportError(
+ tree,
+ "type.invalid.annotations.on.location",
+ type.getExtendsBound().getAnnotations().toString(),
+ "EXTENDS_WILDCARD");
+ }
+ }
}
diff --git a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java
index 3a81afb0ca0..f7f7b81fde4 100644
--- a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java
+++ b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java
@@ -47,6 +47,7 @@
import org.checkerframework.checker.interning.qual.FindDistinct;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
+import org.checkerframework.checker.signature.qual.CanonicalName;
import org.checkerframework.dataflow.analysis.TransferResult;
import org.checkerframework.dataflow.cfg.node.BooleanLiteralNode;
import org.checkerframework.dataflow.cfg.node.Node;
@@ -68,6 +69,8 @@
import org.checkerframework.framework.flow.CFAbstractStore;
import org.checkerframework.framework.flow.CFAbstractValue;
import org.checkerframework.framework.qual.DefaultQualifier;
+import org.checkerframework.framework.qual.TargetLocations;
+import org.checkerframework.framework.qual.TypeUseLocation;
import org.checkerframework.framework.qual.Unused;
import org.checkerframework.framework.source.DiagMessage;
import org.checkerframework.framework.source.SourceVisitor;
@@ -265,16 +268,27 @@ public class BaseTypeVisitor> qualAllowedLocations;
+
+ /**
+ * Constructor for creating a BaseTypeVisitor.
+ *
* @param checker the type-checker associated with this visitor (for callbacks to {@link
* TypeHierarchy#isSubtype})
*/
@@ -283,6 +297,8 @@ public BaseTypeVisitor(BaseTypeChecker checker) {
}
/**
+ * Constructor for creating a BaseTypeVisitor.
+ *
* @param checker the type-checker associated with this visitor
* @param typeFactory the type factory, or null. If null, this calls {@link #createTypeFactory}.
*/
@@ -307,6 +323,9 @@ protected BaseTypeVisitor(BaseTypeChecker checker, Factory typeFactory) {
suggestPureMethods = checker.hasOption("suggestPureMethods"); // NO-AFU || infer;
checkPurity = checker.hasOption("checkPurityAnnotations") || suggestPureMethods;
warnRedundantAnnotations = checker.hasOption("warnRedundantAnnotations");
+ ignoreTargetLocations = checker.hasOption("ignoreTargetLocations");
+ qualAllowedLocations = createQualAllowedLocations();
+
checkEnclosingExpr = checker.hasOption("checkEnclosingExpr");
ajavaChecks = checker.hasOption("ajavaChecks");
assumeSideEffectFree =
@@ -1021,7 +1040,6 @@ public Void visitMethod(MethodTree tree, Void p) {
tree.getParameters());
checkContractsAtMethodDeclaration(
tree, methodElement, formalParamNames, abstractMethod);
-
/* NO-AFU
// Infer postconditions
if (atypeFactory.getWholeProgramInference() != null) {
@@ -1584,10 +1602,140 @@ && getCurrentPath().getParentPath().getLeaf().getKind()
// so only validate if commonAssignmentCheck wasn't called
validateTypeOf(tree);
}
+ validateVariablesTargetLocation(tree, variableType);
warnRedundantAnnotations(tree, variableType);
return super.visitVariable(tree, p);
}
+ /**
+ * Validate if the annotations on the VariableTree are at the right locations, which is
+ * specified by the meta-annotation @TargetLocations. The difference of this method between
+ * {@link BaseTypeVisitor#validateTargetLocation(Tree, AnnotatedTypeMirror, TypeUseLocation)} is
+ * that this one is only used in {@link BaseTypeVisitor#visitVariable(VariableTree, Void)}
+ *
+ * @param tree annotations on this VariableTree will be validated
+ * @param type the type of the tree
+ */
+ protected void validateVariablesTargetLocation(Tree tree, AnnotatedTypeMirror type) {
+ if (ignoreTargetLocations) {
+ return;
+ }
+ Element element = TreeUtils.elementFromTree(tree);
+
+ if (element != null) {
+ ElementKind elemKind = element.getKind();
+ // TypeUseLocation.java doesn't have ENUM type use location right now.
+ for (AnnotationMirror am : type.getAnnotations()) {
+ List locations =
+ qualAllowedLocations.get(AnnotationUtils.annotationName(am));
+ if (locations == null || locations.contains(TypeUseLocation.ALL)) {
+ continue;
+ }
+ boolean issueError = true;
+ switch (elemKind) {
+ case LOCAL_VARIABLE:
+ if (locations.contains(TypeUseLocation.LOCAL_VARIABLE)) issueError = false;
+ break;
+ case EXCEPTION_PARAMETER:
+ if (locations.contains(TypeUseLocation.EXCEPTION_PARAMETER))
+ issueError = false;
+ break;
+ case PARAMETER:
+ if (((VariableTree) tree).getName().contentEquals("this")) {
+ if (locations.contains(TypeUseLocation.RECEIVER)) {
+ issueError = false;
+ }
+ } else {
+ if (locations.contains(TypeUseLocation.PARAMETER)) {
+ issueError = false;
+ }
+ }
+ break;
+ case RESOURCE_VARIABLE:
+ if (locations.contains(TypeUseLocation.RESOURCE_VARIABLE)) {
+ issueError = false;
+ }
+ break;
+ case FIELD:
+ if (locations.contains(TypeUseLocation.FIELD)) {
+ issueError = false;
+ }
+ break;
+ case ENUM_CONSTANT:
+ if (locations.contains(TypeUseLocation.FIELD)
+ || locations.contains(TypeUseLocation.CONSTRUCTOR_RESULT)) {
+ issueError = false;
+ }
+ break;
+ default:
+ throw new BugInCF("Location not matched");
+ }
+ if (issueError) {
+ checker.reportError(
+ tree,
+ "type.invalid.annotations.on.location",
+ am.toString(),
+ element.getKind().name());
+ }
+ }
+ }
+ }
+
+ /**
+ * Validate if the annotations on the tree are at the right locations, which are specified by
+ * the meta-annotation @TargetLocations.
+ *
+ * @param tree annotations on this VariableTree will be validated
+ * @param type the type of the tree
+ * @param required if all of the TypeUseLocations in {@code required} are not present in the
+ * specification of the annotation (@TargetLocations), issue an error.
+ */
+ protected void validateTargetLocation(
+ Tree tree, AnnotatedTypeMirror type, TypeUseLocation required) {
+ if (ignoreTargetLocations) {
+ return;
+ }
+ for (AnnotationMirror am : type.getAnnotations()) {
+ List locations =
+ qualAllowedLocations.get(AnnotationUtils.annotationName(am));
+ if (locations == null || locations.contains(TypeUseLocation.ALL)) {
+ continue;
+ }
+ boolean issueError = !locations.contains(required);
+
+ if (issueError) {
+ checker.reportError(
+ tree,
+ "type.invalid.annotations.on.location",
+ am.toString(),
+ required.toString());
+ }
+ }
+ }
+
+ /**
+ * Create a new map, which is used for declared type-use locations lookup.
+ *
+ * @return a new mapping from strings of qualifier names to their declared type-use locations.
+ */
+ protected Map<@CanonicalName String, List> createQualAllowedLocations() {
+ HashMap<@CanonicalName String, List> qualAllowedLocations =
+ new HashMap<>();
+ for (String qual : atypeFactory.getSupportedTypeQualifierNames()) {
+ Element elem = elements.getTypeElement(qual);
+ TargetLocations tls = elem.getAnnotation(TargetLocations.class);
+ // @Target({ElementType.TYPE_USE})} together with no @TargetLocations(...) means that
+ // the qualifier can be written on any type use.
+ if (tls == null) {
+ qualAllowedLocations.put(qual, null);
+ continue;
+ }
+ List locations = Arrays.asList(tls.value());
+ qualAllowedLocations.put(qual, locations);
+ }
+ return qualAllowedLocations;
+ }
+
/**
* Issues a "redundant.anno" warning if the annotation written on the type is the same as the
* default annotation for this type and location.
@@ -4882,6 +5030,7 @@ public boolean isValidUse(AnnotatedArrayType type, Tree tree) {
* check the return type.
*
* @param tree the AST type supplied by the user
+ * @return true if the type is valid
*/
public boolean validateTypeOf(Tree tree) {
AnnotatedTypeMirror type;
@@ -4889,7 +5038,6 @@ public boolean validateTypeOf(Tree tree) {
switch (tree.getKind()) {
case PRIMITIVE_TYPE:
case PARAMETERIZED_TYPE:
- case TYPE_PARAMETER:
case ARRAY_TYPE:
case UNBOUNDED_WILDCARD:
case EXTENDS_WILDCARD:
@@ -4897,6 +5045,17 @@ public boolean validateTypeOf(Tree tree) {
case ANNOTATED_TYPE:
type = atypeFactory.getAnnotatedTypeFromTypeTree(tree);
break;
+ case TYPE_PARAMETER:
+ type = atypeFactory.getAnnotatedTypeFromTypeTree(tree);
+ validateTargetLocation(
+ tree,
+ ((AnnotatedTypeVariable) type).getUpperBound(),
+ TypeUseLocation.UPPER_BOUND);
+ validateTargetLocation(
+ tree,
+ ((AnnotatedTypeVariable) type).getLowerBound(),
+ TypeUseLocation.LOWER_BOUND);
+ break;
case METHOD:
type = atypeFactory.getMethodReturnType((MethodTree) tree);
if (type == null || type.getKind() == TypeKind.VOID) {
@@ -4905,6 +5064,11 @@ public boolean validateTypeOf(Tree tree) {
// not use void as return type.
return true;
}
+ if (TreeUtils.isConstructor((MethodTree) tree)) {
+ validateTargetLocation(tree, type, TypeUseLocation.CONSTRUCTOR_RESULT);
+ } else {
+ validateTargetLocation(tree, type, TypeUseLocation.RETURN);
+ }
break;
default:
type = atypeFactory.getAnnotatedType(tree);
diff --git a/framework/src/main/java/org/checkerframework/common/basetype/messages.properties b/framework/src/main/java/org/checkerframework/common/basetype/messages.properties
index 832a2d12a16..7b4c723904f 100644
--- a/framework/src/main/java/org/checkerframework/common/basetype/messages.properties
+++ b/framework/src/main/java/org/checkerframework/common/basetype/messages.properties
@@ -25,6 +25,7 @@ type.invalid=invalid type: annotations %s in type "%s"
type.invalid.conflicting.annos=invalid type: conflicting annotations %s in type "%s"
type.invalid.too.few.annotations=invalid type: missing annotations %s in type "%s"
type.invalid.annotations.on.use=invalid type: annotations %s conflict with declaration of type %s
+type.invalid.annotations.on.location=annotation %s used on prohibited locations %s
type.invalid.super.wildcard=bounds must have the same annotations.%nsuper bound : %s%nextends bound: %s
cast.unsafe=cast from "%s" to "%s" cannot be statically verified
invariant.cast.unsafe=cannot cast from "%s" to "%s"
diff --git a/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java b/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java
index 61a562295f7..1bb9314a4af 100644
--- a/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java
+++ b/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java
@@ -338,6 +338,8 @@
// Do not perform a JRE version check.
"noJreVersionCheck",
+ // Do not validate meta-annotation @TargetLocations
+ "ignoreTargetLocations",
/// Format of messages
// Output detailed message in simple-to-parse format, useful
diff --git a/framework/src/test/java/org/checkerframework/framework/test/junit/AccumulationTest.java b/framework/src/test/java/org/checkerframework/framework/test/junit/AccumulationTest.java
index 0d8b18a8789..273290e5074 100644
--- a/framework/src/test/java/org/checkerframework/framework/test/junit/AccumulationTest.java
+++ b/framework/src/test/java/org/checkerframework/framework/test/junit/AccumulationTest.java
@@ -17,7 +17,14 @@ public class AccumulationTest extends CheckerFrameworkPerDirectoryTest {
* @param testFiles the files containing test code, which will be type-checked
*/
public AccumulationTest(List testFiles) {
- super(testFiles, TestAccumulationChecker.class, "accumulation", "-encoding", "UTF-8");
+ super(
+ testFiles,
+ TestAccumulationChecker.class,
+ "accumulation",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations",
+ "-encoding",
+ "UTF-8");
}
@Parameters
diff --git a/framework/src/test/java/org/checkerframework/framework/test/junit/ReflectionTest.java b/framework/src/test/java/org/checkerframework/framework/test/junit/ReflectionTest.java
index a902b8d41e5..6ede8662616 100644
--- a/framework/src/test/java/org/checkerframework/framework/test/junit/ReflectionTest.java
+++ b/framework/src/test/java/org/checkerframework/framework/test/junit/ReflectionTest.java
@@ -15,7 +15,12 @@ public class ReflectionTest extends CheckerFrameworkPerDirectoryTest {
* @param testFiles the files containing test code, which will be type-checked
*/
public ReflectionTest(List testFiles) {
- super(testFiles, ReflectionTestChecker.class, "reflection");
+ super(
+ testFiles,
+ ReflectionTestChecker.class,
+ "reflection",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations");
}
@Parameters
diff --git a/framework/src/test/java/org/checkerframework/framework/test/junit/ReturnsReceiverTest.java b/framework/src/test/java/org/checkerframework/framework/test/junit/ReturnsReceiverTest.java
index ab25ec3a7a6..a4526de8246 100644
--- a/framework/src/test/java/org/checkerframework/framework/test/junit/ReturnsReceiverTest.java
+++ b/framework/src/test/java/org/checkerframework/framework/test/junit/ReturnsReceiverTest.java
@@ -20,7 +20,9 @@ public ReturnsReceiverTest(List testFiles) {
ReturnsReceiverChecker.class,
"returnsreceiver",
"-Astubs=stubs/",
- "-nowarn");
+ "-nowarn",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations");
}
@Parameters
diff --git a/framework/src/test/java/org/checkerframework/framework/test/junit/ValueIgnoreRangeOverflowTest.java b/framework/src/test/java/org/checkerframework/framework/test/junit/ValueIgnoreRangeOverflowTest.java
index a08ff4d3179..afd06a04138 100644
--- a/framework/src/test/java/org/checkerframework/framework/test/junit/ValueIgnoreRangeOverflowTest.java
+++ b/framework/src/test/java/org/checkerframework/framework/test/junit/ValueIgnoreRangeOverflowTest.java
@@ -18,6 +18,8 @@ public ValueIgnoreRangeOverflowTest(List testFiles) {
testFiles,
org.checkerframework.common.value.ValueChecker.class,
"value",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations",
"-A" + ValueChecker.REPORT_EVAL_WARNS,
"-A" + ValueChecker.IGNORE_RANGE_OVERFLOW);
}
diff --git a/framework/src/test/java/org/checkerframework/framework/test/junit/ValueNonNullStringsConcatenationTest.java b/framework/src/test/java/org/checkerframework/framework/test/junit/ValueNonNullStringsConcatenationTest.java
index 8f3aa0af21d..f6d75d9e364 100644
--- a/framework/src/test/java/org/checkerframework/framework/test/junit/ValueNonNullStringsConcatenationTest.java
+++ b/framework/src/test/java/org/checkerframework/framework/test/junit/ValueNonNullStringsConcatenationTest.java
@@ -17,6 +17,8 @@ public ValueNonNullStringsConcatenationTest(List testFiles) {
testFiles,
org.checkerframework.common.value.ValueChecker.class,
"value-non-null-strings-concatenation",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations",
"-A" + ValueChecker.REPORT_EVAL_WARNS,
"-A" + ValueChecker.NON_NULL_STRINGS_CONCATENATION);
}
diff --git a/framework/src/test/java/org/checkerframework/framework/test/junit/ValueTest.java b/framework/src/test/java/org/checkerframework/framework/test/junit/ValueTest.java
index fe40bfa943e..f31984cc2ad 100644
--- a/framework/src/test/java/org/checkerframework/framework/test/junit/ValueTest.java
+++ b/framework/src/test/java/org/checkerframework/framework/test/junit/ValueTest.java
@@ -24,6 +24,8 @@ public ValueTest(List testFiles) {
testFiles,
org.checkerframework.common.value.ValueChecker.class,
"value",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations",
"-Astubs=tests/value/minints-stub.astub:tests/value/lowercase.astub",
"-A" + ValueChecker.REPORT_EVAL_WARNS);
}
diff --git a/framework/src/test/java/org/checkerframework/framework/test/junit/ValueUncheckedDefaultsTest.java b/framework/src/test/java/org/checkerframework/framework/test/junit/ValueUncheckedDefaultsTest.java
index 3872435532b..d33bdf51dd8 100644
--- a/framework/src/test/java/org/checkerframework/framework/test/junit/ValueUncheckedDefaultsTest.java
+++ b/framework/src/test/java/org/checkerframework/framework/test/junit/ValueUncheckedDefaultsTest.java
@@ -18,6 +18,8 @@ public ValueUncheckedDefaultsTest(List testFiles) {
testFiles,
ValueChecker.class,
"value",
+ // Ignore the test suite's usage of qualifiers in illegal locations.
+ "-AignoreTargetLocations",
"-AuseConservativeDefaultsForUncheckedCode=btyecode",
"-A" + ValueChecker.REPORT_EVAL_WARNS);
}
diff --git a/framework/src/test/java/org/checkerframework/framework/testchecker/compound/qual/ACCBottom.java b/framework/src/test/java/org/checkerframework/framework/testchecker/compound/qual/ACCBottom.java
index 54c2de9f16c..f26f4af606f 100644
--- a/framework/src/test/java/org/checkerframework/framework/testchecker/compound/qual/ACCBottom.java
+++ b/framework/src/test/java/org/checkerframework/framework/testchecker/compound/qual/ACCBottom.java
@@ -9,5 +9,5 @@
@SubtypeOf({ACCTop.class})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
public @interface ACCBottom {}
diff --git a/framework/src/test/java/org/checkerframework/framework/testchecker/compound/qual/CCBottom.java b/framework/src/test/java/org/checkerframework/framework/testchecker/compound/qual/CCBottom.java
index 1a1e65967a1..7567920d933 100644
--- a/framework/src/test/java/org/checkerframework/framework/testchecker/compound/qual/CCBottom.java
+++ b/framework/src/test/java/org/checkerframework/framework/testchecker/compound/qual/CCBottom.java
@@ -9,5 +9,5 @@
@SubtypeOf({CCTop.class})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
public @interface CCBottom {}
diff --git a/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/H1H2AnnotatedTypeFactory.java b/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/H1H2AnnotatedTypeFactory.java
index a6516a053e6..e97840ffd52 100644
--- a/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/H1H2AnnotatedTypeFactory.java
+++ b/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/H1H2AnnotatedTypeFactory.java
@@ -12,6 +12,7 @@
import org.checkerframework.framework.testchecker.h1h2checker.quals.H1S2;
import org.checkerframework.framework.testchecker.h1h2checker.quals.H1Top;
import org.checkerframework.framework.testchecker.h1h2checker.quals.H2Bot;
+import org.checkerframework.framework.testchecker.h1h2checker.quals.H2OnlyOnLB;
import org.checkerframework.framework.testchecker.h1h2checker.quals.H2Poly;
import org.checkerframework.framework.testchecker.h1h2checker.quals.H2S1;
import org.checkerframework.framework.testchecker.h1h2checker.quals.H2S2;
@@ -47,6 +48,7 @@ protected Set> createSupportedTypeQualifiers() {
H2Bot.class,
H1Poly.class,
H2Poly.class,
+ H2OnlyOnLB.class,
H1Invalid.class);
}
diff --git a/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/quals/H2Bot.java b/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/quals/H2Bot.java
index 2acdcfe6ff9..296bf34280b 100644
--- a/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/quals/H2Bot.java
+++ b/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/quals/H2Bot.java
@@ -13,6 +13,6 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@SubtypeOf({H2S1.class, H2S2.class})
+@SubtypeOf({H2S1.class, H2S2.class, H2OnlyOnLB.class})
@DefaultFor(TypeUseLocation.LOWER_BOUND)
public @interface H2Bot {}
diff --git a/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/quals/H2OnlyOnLB.java b/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/quals/H2OnlyOnLB.java
new file mode 100644
index 00000000000..2f6daffbf55
--- /dev/null
+++ b/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/quals/H2OnlyOnLB.java
@@ -0,0 +1,18 @@
+package org.checkerframework.framework.testchecker.h1h2checker.quals;
+
+import org.checkerframework.framework.qual.SubtypeOf;
+import org.checkerframework.framework.qual.TargetLocations;
+import org.checkerframework.framework.qual.TypeUseLocation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@TargetLocations({TypeUseLocation.LOWER_BOUND})
+@SubtypeOf({H2Top.class})
+public @interface H2OnlyOnLB {}
diff --git a/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/quals/H2S1.java b/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/quals/H2S1.java
index 87aa66bf3f5..29276abd5ed 100644
--- a/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/quals/H2S1.java
+++ b/framework/src/test/java/org/checkerframework/framework/testchecker/h1h2checker/quals/H2S1.java
@@ -1,6 +1,8 @@
package org.checkerframework.framework.testchecker.h1h2checker.quals;
import org.checkerframework.framework.qual.SubtypeOf;
+import org.checkerframework.framework.qual.TargetLocations;
+import org.checkerframework.framework.qual.TypeUseLocation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
@@ -11,5 +13,12 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@TargetLocations({
+ TypeUseLocation.FIELD,
+ TypeUseLocation.LOCAL_VARIABLE,
+ TypeUseLocation.PARAMETER,
+ TypeUseLocation.RETURN,
+ TypeUseLocation.CONSTRUCTOR_RESULT
+})
@SubtypeOf({H2Top.class})
public @interface H2S1 {}
diff --git a/framework/src/test/java/org/checkerframework/framework/testchecker/nontopdefault/qual/NTDBottom.java b/framework/src/test/java/org/checkerframework/framework/testchecker/nontopdefault/qual/NTDBottom.java
index 9e3bbfadc77..7f69c5fb6fe 100644
--- a/framework/src/test/java/org/checkerframework/framework/testchecker/nontopdefault/qual/NTDBottom.java
+++ b/framework/src/test/java/org/checkerframework/framework/testchecker/nontopdefault/qual/NTDBottom.java
@@ -14,7 +14,7 @@
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@SubtypeOf({NTDMiddle.class, NTDSide.class})
@DefaultFor({TypeUseLocation.LOWER_BOUND})
public @interface NTDBottom {}
diff --git a/framework/src/test/java/org/checkerframework/framework/testchecker/reflection/qual/TestReflectBottom.java b/framework/src/test/java/org/checkerframework/framework/testchecker/reflection/qual/TestReflectBottom.java
index 7f7823dfafb..eb81ae99876 100644
--- a/framework/src/test/java/org/checkerframework/framework/testchecker/reflection/qual/TestReflectBottom.java
+++ b/framework/src/test/java/org/checkerframework/framework/testchecker/reflection/qual/TestReflectBottom.java
@@ -16,6 +16,6 @@
*/
@SubtypeOf({TestReflectSibling1.class, TestReflectSibling2.class})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
@DefaultFor(TypeUseLocation.LOWER_BOUND)
public @interface TestReflectBottom {}
diff --git a/framework/src/test/java/org/checkerframework/framework/testchecker/supportedquals/qual/BottomQualifier.java b/framework/src/test/java/org/checkerframework/framework/testchecker/supportedquals/qual/BottomQualifier.java
index 6138eafa424..5fdd37a143f 100644
--- a/framework/src/test/java/org/checkerframework/framework/testchecker/supportedquals/qual/BottomQualifier.java
+++ b/framework/src/test/java/org/checkerframework/framework/testchecker/supportedquals/qual/BottomQualifier.java
@@ -9,5 +9,5 @@
@SubtypeOf({Qualifier.class})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
public @interface BottomQualifier {}
diff --git a/framework/src/test/java/org/checkerframework/framework/testchecker/testaccumulation/qual/TestAccumulationBottom.java b/framework/src/test/java/org/checkerframework/framework/testchecker/testaccumulation/qual/TestAccumulationBottom.java
index 0edd4029b4b..6df1ac88fd6 100644
--- a/framework/src/test/java/org/checkerframework/framework/testchecker/testaccumulation/qual/TestAccumulationBottom.java
+++ b/framework/src/test/java/org/checkerframework/framework/testchecker/testaccumulation/qual/TestAccumulationBottom.java
@@ -13,5 +13,5 @@
@SubtypeOf({TestAccumulation.class, TestAccumulationPredicate.class})
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
public @interface TestAccumulationBottom {}
diff --git a/framework/src/test/java/org/checkerframework/framework/testchecker/util/PatternBottomFull.java b/framework/src/test/java/org/checkerframework/framework/testchecker/util/PatternBottomFull.java
index f367be64949..fd016483cea 100644
--- a/framework/src/test/java/org/checkerframework/framework/testchecker/util/PatternBottomFull.java
+++ b/framework/src/test/java/org/checkerframework/framework/testchecker/util/PatternBottomFull.java
@@ -9,5 +9,5 @@
@SubtypeOf({PatternA.class, PatternB.class, PatternC.class})
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
-@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND})
+@TargetLocations({TypeUseLocation.LOWER_BOUND, TypeUseLocation.UPPER_BOUND})
public @interface PatternBottomFull {}
diff --git a/framework/tests/h1h2checker/EnforceTargetLocation.java b/framework/tests/h1h2checker/EnforceTargetLocation.java
new file mode 100644
index 00000000000..cfcf38117ea
--- /dev/null
+++ b/framework/tests/h1h2checker/EnforceTargetLocation.java
@@ -0,0 +1,30 @@
+import org.checkerframework.framework.testchecker.h1h2checker.quals.*;
+
+import java.util.List;
+
+// :: error: (type.invalid.annotations.on.location)
+public class EnforceTargetLocation {
+ @H2S1 Object right;
+
+ // :: error: (type.invalid.annotations.on.location)
+ @H2OnlyOnLB Object wrong;
+
+ @H2S1 Object correctUse(@H2S1 Object p1) {
+ // :: warning: (cast.unsafe.constructor.invocation)
+ @H2S1 Object o = new @H2S1 Object();
+ List super @H2OnlyOnLB Number> l;
+ return o;
+ }
+
+ @H2OnlyOnLB
+ // :: error: (type.invalid.annotations.on.location)
+ Object incorrect() {
+ // :: warning: (cast.unsafe.constructor.invocation)
+ // :: error: (type.invalid.annotations.on.location)
+ @H2OnlyOnLB Object o = new @H2OnlyOnLB Object();
+ return o;
+ }
+
+ // :: error: (type.invalid.annotations.on.location)
+ void incorrectUse2(@H2OnlyOnLB Object p1) {}
+}
diff --git a/framework/tests/h1h2checker/InferTypeArgsPolyChecker.java b/framework/tests/h1h2checker/InferTypeArgsPolyChecker.java
index 8db3f9ca1a1..d006bab8a43 100644
--- a/framework/tests/h1h2checker/InferTypeArgsPolyChecker.java
+++ b/framework/tests/h1h2checker/InferTypeArgsPolyChecker.java
@@ -108,6 +108,7 @@ List super F> methodF(List extends F> lExtF, List super F> lSupF) {
}
void contextF(
+ // :: error: (type.invalid.annotations.on.location)
List<@H1Bot @H2Bot ? extends @H1Top @H2S1 String> l1,
List super @H1S1 @H2S2 String> l2,
List<@H1S1 @H2S2 ? extends @H1Top @H2Top String> l3) {