Skip to content
Open
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
464 commits
Select commit Hold shift + click to select a range
331931e
default resource collection constructor returns no OCwO
Jun 24, 2025
123f26d
fix return rule for resource collections
Jun 24, 2025
d9d7feb
fix tests to account for enhanced precision of new defaults
Jun 24, 2025
ee95caa
add CollectionOwnershipStore and Analysis
Jun 25, 2025
ee0ce6d
add collectionfielddestructor postcon anno
Jun 25, 2025
12ae8fc
doc
Jun 25, 2025
b2505b7
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jun 25, 2025
ce34a10
add support for @OC fields
Jun 25, 2025
73af398
demand @CreatesCollectionObligation method invocs on fields to have @…
Jun 25, 2025
75f3cbf
add test for @OC fields
Jun 25, 2025
6134f55
make missing.creates.mustcall.for slightly more generic
Jun 25, 2025
fdf9b0a
add method deciding whether rc field is owning or not
Jun 26, 2025
0ae2cf5
introduce owning rc field as @OCwO in constructor
Jun 26, 2025
dcde6c3
prevent ownership transfer out of owning rc field
Jun 26, 2025
febc5cb
fix how owning rc fields are decided in COVisitor
Jun 26, 2025
e19a61c
check owning rc field assignments in consistency analyzer
Jun 26, 2025
2468321
more field tests
Jun 26, 2025
73b3985
Javadoc
mernst Jun 26, 2025
2b6456c
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
mernst Jun 26, 2025
21f3503
move logic for parsing JavaExp from string from visitor to atf
Jun 26, 2025
efa1d38
fix how @OC and owning rc field are decided
Jun 26, 2025
bf14a97
check field accesses to prevent accessing foreign owning rc fields
Jun 26, 2025
7fd44cc
new field tests
Jun 26, 2025
f3442c3
comment field null test, not implemented yet
Jun 26, 2025
eb46285
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
Jun 26, 2025
3dfe32b
Merge branch 'master' of https://github.com/typetools/checker-framewo…
Jun 26, 2025
5474b79
add missing doc
Jun 26, 2025
4700443
please new preferences of formatter
Jun 27, 2025
410f092
use new isOwningCollectionField in costore as well
Jun 27, 2025
77d6946
isocfield now expects element instead of tree
Jun 27, 2025
01ae15c
add missing @param
Jun 27, 2025
d7e3c0c
fix crash due to receiver not in store
Jun 27, 2025
a201ecb
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jun 27, 2025
620b82e
manual update
Jun 27, 2025
3181578
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
Jun 27, 2025
08a7c08
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jun 27, 2025
076f0b7
fix rlc-collections manual
Jun 28, 2025
b386e9e
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
Jun 28, 2025
b9bf410
fix quotes
Jun 28, 2025
fcf9e05
suppress this-escape warning for calling postInit()
Jun 28, 2025
fab3eb9
fix nullness crash
Jun 28, 2025
dd92896
make @OCBottom and @OCwO illegal manual annotations
Jun 28, 2025
6a46cfb
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jul 5, 2025
56e8fd4
disallow owning rc field assignments with @OC rhs
Jul 5, 2025
627cc6e
keep @NotOwningCollection rc fields in store as well
Jul 5, 2025
0a7d4f2
fix how return statements are checked for @OC return vals
Jul 5, 2025
ffd8f25
allow assignments to final field
Jul 5, 2025
d935a35
disallow static rc fields
Jul 6, 2025
23a2fcd
remove obligation of rhs in assignment to owning rc final field lhs
Jul 6, 2025
c8d95a0
improve error message for foreign rc field access
Jul 6, 2025
8ddb042
add field test cases
Jul 6, 2025
a62bede
remove array support
Jul 6, 2025
5f32f89
fix test outcomse after making List#get not owning
Jul 6, 2025
ab5b2a2
remove array tests
Jul 6, 2025
9e3c23a
fix collections rlc manual section with manu feedback
Jul 7, 2025
bbb7ef8
also require createsmcfor(this) for field asgnment with noc rhs
Jul 7, 2025
3ade7ed
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jul 9, 2025
62c4299
maps are now also resource collections
Jul 9, 2025
66901ee
remove expected warning for type.arg because map can now hold non-emp…
Jul 9, 2025
be87c39
@OwningCollection and @NotOwningCollection are inheritable!!!!
Jul 9, 2025
79506bd
polyowning inherited
Jul 9, 2025
71ae840
only collections with one typearg are rc
Jul 9, 2025
b1687a6
fix crash when annotated type not available
Jul 14, 2025
2b13a8d
Format
mernst Jul 21, 2025
518e749
fix loopbodyanalysis (fix by Suzanne)
Jul 21, 2025
fe206ee
no errors for map.get
Jul 21, 2025
4c3dc9c
uncomment now working loop body analysis tests
Jul 21, 2025
14d37bf
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
Jul 21, 2025
82717fc
formatting
Jul 21, 2025
f474bc5
suppress interning warning
Jul 22, 2025
398d16c
fix crash in for-loop pattern match
Jul 22, 2025
f30abbb
make collectionownership annotations inheritable
Jul 22, 2025
80cd91a
formating
Jul 22, 2025
b10609c
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jul 22, 2025
9a4d4ef
suzanne's fix for the afu build file
Jul 22, 2025
33d7b64
annotate afu for collection ownership checker
Jul 23, 2025
3347442
warning suppressions in afu for collection ownership checker
Jul 23, 2025
555194e
add poly annotation as field
Jul 23, 2025
0f25e74
don't inherit polyoc annotation
Jul 23, 2025
a4f1a3f
propagate annotations from parameter decl to use site
Jul 23, 2025
64b1855
adapt annos&suppressions for afu subproject after not inheriting poly…
Jul 23, 2025
03efa5f
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jul 23, 2025
4433b46
Add Javadoc
mernst Jul 23, 2025
ffa65ba
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
mernst Jul 23, 2025
b39a77a
Add Javadoc
mernst Jul 23, 2025
fe92dab
Use %n, not \n, in format strings
mernst Jul 24, 2025
10a30c2
Documentation improvements
mernst Jul 24, 2025
eaadec9
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Jul 24, 2025
ceebfff
Documentation improvements
mernst Jul 25, 2025
6e95c34
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Jul 25, 2025
9549bfc
Use "true if" instead of "whether"
mernst Jul 25, 2025
116f596
Improve Javadoc style
mernst Jul 25, 2025
6b0b327
Rename variable
mernst Jul 25, 2025
346b9ed
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Jul 25, 2025
a012a9d
Use curly braces around then and else clauses
mernst Jul 25, 2025
96bd8a1
Documentation tweaks and improve efficiency by doing cheap test first
mernst Jul 25, 2025
a961341
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Jul 27, 2025
5d55958
Improve Javadoc style
mernst Jul 27, 2025
9a0246b
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Jul 27, 2025
7db0254
Checkpoint
mernst Jul 27, 2025
83fed79
Variable names
mernst Jul 30, 2025
b343553
Documentation for `defaultCreateAbstractValue`
mernst Jul 30, 2025
20aa7d7
Checkpoint
mernst Jul 30, 2025
13c41f0
Merge ../checker-framework-fork-mernst-branch-defaultCreateAbstractVa…
mernst Jul 30, 2025
94c2730
Add curly braces around `then` clauses
mernst Jul 30, 2025
76358b6
Merge ../checker-framework-fork-mernst-branch-curly-braces into rlc-c…
mernst Jul 30, 2025
0e80e9d
Add curly braces
mernst Jul 30, 2025
41396e0
Code review edits
mernst Jul 30, 2025
a00e883
Code review edits
mernst Jul 30, 2025
2e81982
Revert experimental change
mernst Jul 30, 2025
37c76a5
Make `insertIntoStores` non-static
mernst Jul 30, 2025
66d4ca8
Documentation fixes
mernst Jul 30, 2025
a6e60b7
Remove suppression
mernst Jul 30, 2025
6f47713
Add `@NotOwning` annotation
mernst Jul 31, 2025
8c1d87a
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Aug 3, 2025
f9da2da
Suppress warnings
mernst Aug 5, 2025
f4d47c6
Temporary warning suppression
mernst Aug 5, 2025
eaa5492
more annotations for rlc4c
Aug 6, 2025
e3e06d9
add receiver annotation
Aug 6, 2025
596f2e1
add comment
Aug 6, 2025
6b17e65
add rlc4c annos
Aug 6, 2025
dada8a3
fix javadoc
Aug 6, 2025
7bcf851
remove unnecessary warning suppression
Aug 7, 2025
343f76a
Add annotations
mernst Aug 7, 2025
8477297
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
mernst Aug 7, 2025
7f51f70
Add Javadoc
mernst Aug 7, 2025
19f39a8
Add annotations, suppress warnings
mernst Aug 7, 2025
8e2fc86
import `@Nullable`
mernst Aug 7, 2025
1480bed
Move annotations
mernst Aug 7, 2025
9d12532
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Aug 8, 2025
251cb94
address code review
Aug 8, 2025
02cc724
address code review: remove createSourceVisitor override in coc
Aug 8, 2025
72bdbc8
remove unnecessary nullness checks
Aug 8, 2025
d552b3e
make mcatf a field in coatf
Aug 8, 2025
aab1708
remove catch bugincf to make error explicit
Aug 8, 2025
bba3c2f
remove mcoeobligationaltering loop wrapper class
Aug 8, 2025
d915819
replace catch (Exception) with catch (BugInCF)
Aug 8, 2025
b88929c
minor changes code review
Aug 8, 2025
0ab02c8
minor changes code review
Aug 8, 2025
03aed4a
fix expected test outcome after renaming an error code
Aug 8, 2025
3bf63c4
minor fixes code review
Aug 8, 2025
8ed76d7
formatting
Aug 8, 2025
d00a615
minor changes code review
Aug 8, 2025
3aeafe7
fix faulty link
Aug 8, 2025
02fa7e8
use old collectors method to prevent runtime error
Aug 9, 2025
c53a155
prevent crash in loop body analysis
Aug 9, 2025
845006a
catch BugInCF if tree has unexpected shape when deciding rc
Aug 9, 2025
1b89b55
prevent crash when rhs of oc field assignment not in store
Aug 10, 2025
e325d51
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Aug 12, 2025
adfc3ab
Fix a typo
kelloggm Aug 13, 2025
f9a0665
clarifications and typo fixes in the manual
kelloggm Aug 13, 2025
73d6163
explanatory comment
kelloggm Aug 13, 2025
7322107
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Aug 17, 2025
4504294
clarify comment
Aug 17, 2025
912aa9a
remove commented out code
Aug 17, 2025
639ff0d
add explanation why loop matching is in mc-visitor
Aug 17, 2025
26a43c1
update explanation for expected test behavior
Aug 17, 2025
4b2a223
add a test case
Aug 17, 2025
4bf1f92
remove commented out defaults for OCBottom
Aug 17, 2025
65abe44
move field example code before explanation in manual
Aug 17, 2025
3d1a831
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
Aug 17, 2025
5179206
comment out mentions of iterator support in rl manual
Aug 17, 2025
062b104
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Aug 20, 2025
ccc78f1
Merge branch 'master' into rlc-collections-redesign
mernst Aug 20, 2025
ec858ae
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Aug 24, 2025
157054a
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Aug 26, 2025
b4fe2ef
parser moved
Aug 26, 2025
fcfc684
add obligation upon CreatsCollectionObligation even for @OC
Aug 26, 2025
7f155e1
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Aug 28, 2025
0913ff3
Merge branch 'master' into rlc-collections-redesign
mernst Sep 1, 2025
a8d2991
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Sep 2, 2025
a5030a7
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Sep 8, 2025
0de2d9c
Fix bug in CFG construction for preincrement
mernst Sep 9, 2025
9d61bff
Fixup
mernst Sep 9, 2025
11ee250
Return locally
mernst Sep 9, 2025
6645c05
Merge ../checker-framework-fork-mernst-branch-partially-undo-9bc061c-…
mernst Sep 9, 2025
1d12e3d
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Sep 9, 2025
49a566f
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Sep 10, 2025
50ff472
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Oct 3, 2025
23da55c
fix spelling mistake in manual
Oct 7, 2025
8b35b86
add explanation when catching InvalidLoopBodyAnalysis Exception
Oct 7, 2025
e40bbbf
mark method as @override
Oct 7, 2025
a552a56
prefer this.equals over other.equals
Oct 7, 2025
04284ad
remove array example from rlc4c manual
Oct 7, 2025
af26a63
fix typo in comment
Oct 7, 2025
54b6000
add override decorators to test file
Oct 7, 2025
69175cf
explicitly use MustCall({}) instead of MustCall
Oct 7, 2025
f945491
remove exceptional stores noop
Oct 7, 2025
527004c
annotated @CreatesCollectionObligation as documented
Oct 7, 2025
3b3a8df
fix doc for createscollectionobligation
Oct 7, 2025
b105a8a
improve javadoc
Oct 8, 2025
a8111ef
address trivial coderabbit PR comments
Oct 8, 2025
c2309f0
revert error message to previous
Oct 8, 2025
2d53603
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Oct 9, 2025
50394ff
Comment improvements
mernst Oct 9, 2025
4afb91f
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Oct 22, 2025
7018049
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Oct 23, 2025
e94545e
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Oct 28, 2025
7bb6e34
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Nov 17, 2025
a7824c3
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Nov 19, 2025
0faec76
fix compilation error in rlccmatf
skehrli Nov 19, 2025
4c56f0c
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Dec 5, 2025
a8d9fca
fix up rlc4c manual section
skehrli Dec 5, 2025
43dcf8e
fix typo in error message
skehrli Dec 5, 2025
5956dd2
nullness guard when checking owning collection field
skehrli Dec 5, 2025
3142935
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Dec 7, 2025
b33e107
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Dec 15, 2025
4006c6f
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Dec 16, 2025
2c99d54
Merge branch 'typetools:master' into rlc-collections-redesign
skehrli Jan 11, 2026
036ebd8
Merge branch 'rlc-collections-redesign' of github.com:skehrli/checker…
skehrli Jan 11, 2026
e99fdb7
remove old manual section about missing rlc for collections
skehrli Jan 11, 2026
5d9dc72
fix error in example program in manual
skehrli Jan 11, 2026
63f0c0f
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Feb 1, 2026
ea3601a
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Mar 2, 2026
57985ba
Put error key in brackets
mernst Mar 2, 2026
88ca42c
Merge ../checker-framework-fork-mernst-branch-more-square-brackets in…
mernst Mar 2, 2026
7668ccc
Undo a change
mernst Mar 2, 2026
cb5f029
Another pair of brackets
mernst Mar 2, 2026
9cae831
Merge ../checker-framework-fork-mernst-branch-more-square-brackets in…
mernst Mar 2, 2026
224f485
Merge ../checker-framework-branch-master into more-square-brackets
mernst Mar 3, 2026
775a2db
Add space around heading
mernst Mar 3, 2026
f26dca7
Merge ../checker-framework-branch-master into more-square-brackets
mernst Mar 3, 2026
58be6f6
Merge ../checker-framework-fork-mernst-branch-more-square-brackets in…
mernst Mar 3, 2026
21ece95
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Mar 3, 2026
83464c7
Merge ../checker-framework-branch-master into rlc-collections-redesign
mernst Mar 4, 2026
2893965
Merge branch 'master' into rlc-collections-redesign
msridhar Mar 19, 2026
ffda69b
Add pre-lambda post-analysis hook for resource leak
iamsanjaymalakar Mar 23, 2026
0082c05
Preserve RLCC method analysis during lambda fixpoint
iamsanjaymalakar Mar 23, 2026
e71b956
More loop support.
iamsanjaymalakar Feb 26, 2026
3b5490e
Allow mutation of not owning collection if inserted element is not ow…
iamsanjaymalakar Feb 26, 2026
aeb82cd
bug fixes.
iamsanjaymalakar Mar 17, 2026
983ecdb
Tests are passing now. more restructuring + documentation remains.
iamsanjaymalakar Mar 31, 2026
d19c583
Merge branch 'master' into rlc-for-collections
iamsanjaymalakar Mar 31, 2026
26f8422
Documentation in COATF and COA.
iamsanjaymalakar Apr 1, 2026
06e60fa
Document lambda fixpoint lifecycle for resource leak analysis
iamsanjaymalakar Apr 1, 2026
58219b0
More documentation.
iamsanjaymalakar Apr 2, 2026
1b3f47e
Merge branch 'master' into rlc-for-collections
iamsanjaymalakar Apr 2, 2026
09593d7
Merge branch 'master' into rlc-for-collections
iamsanjaymalakar Apr 2, 2026
5c6eeef
Use the new annotation hierarchy API in RLCC
iamsanjaymalakar Apr 2, 2026
91e9f76
Fix RLCC typecheck and misc CI issues
iamsanjaymalakar Apr 3, 2026
c3fef46
Merge branch 'master' into rlc-for-collections
iamsanjaymalakar Apr 3, 2026
93abd88
Type check issue.
iamsanjaymalakar Apr 4, 2026
2e03c50
Merge branch 'master' into rlc-for-collections
iamsanjaymalakar Apr 4, 2026
2c2468a
Type check issue.
iamsanjaymalakar Apr 4, 2026
a809c1c
Merge branch 'master' into rlc-for-collections
iamsanjaymalakar Apr 4, 2026
34c5027
Made LinkedHashKeyedSet as NOC; the Map takes ownership of the resour…
iamsanjaymalakar Apr 5, 2026
d2d1a36
Type check issue.
iamsanjaymalakar Apr 5, 2026
ae959a1
Merge remote-tracking branch 'upstream/master' into rlc-for-collections
iamsanjaymalakar Apr 8, 2026
9e18cc6
Handle zero-arg Arrays.asList() in must-call polymorphism
iamsanjaymalakar Apr 9, 2026
b48eba3
Merge branch 'master' into rlc-for-collections
iamsanjaymalakar Apr 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@
import org.checkerframework.afu.scenelib.type.BoundedType;
import org.checkerframework.afu.scenelib.type.DeclaredType;
import org.checkerframework.afu.scenelib.type.Type;
import org.checkerframework.checker.collectionownership.qual.PolyOwningCollection;
import org.checkerframework.checker.interning.qual.Interned;
import org.checkerframework.checker.mustcall.qual.NotOwning;
import org.objectweb.asm.TypePath;

/**
Expand Down Expand Up @@ -185,7 +187,7 @@ public int size() {
}

@Override
public Iterator<Insertion> iterator() {
public @PolyOwningCollection Iterator<Insertion> iterator(@PolyOwningCollection Insertions this) {
return new Iterator<Insertion>() {
private Iterator<Map<String, Set<Insertion>>> miter = store.values().iterator();
// These two fields are initially empty iterators, but are set the first time that hasNext is
Expand All @@ -210,7 +212,7 @@ public boolean hasNext() {
}

@Override
public Insertion next() {
public @NotOwning Insertion next() {
if (hasNext()) {
return iiter.next();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
import java.util.NoSuchElementException;
import java.util.Objects;
import org.checkerframework.afu.annotator.find.CaseUtils;
import org.checkerframework.checker.collectionownership.qual.NotOwningCollection;
import org.checkerframework.checker.collectionownership.qual.PolyOwningCollection;
import org.plumelib.util.ArraysPlume;

/** A path through the AST. */
Expand Down Expand Up @@ -295,7 +297,7 @@ public static Comparator<ASTPath> getComparator() {

// TODO: replace w/ skip list?
@Override
public Iterator<ASTEntry> iterator() {
public @PolyOwningCollection Iterator<ASTEntry> iterator(@PolyOwningCollection ASTPath this) {
ImmutableStack<ASTEntry> s = this;
int n = size();
ASTEntry[] a = new ASTEntry[n];
Expand Down Expand Up @@ -1447,17 +1449,16 @@ private static <T, S extends ImmutableStack<T>> S extend(T el, S s0) {
*
* @return true if the stack is empty
*/
public boolean isEmpty() {
public boolean isEmpty(@NotOwningCollection ImmutableStack<E> this) {
return size == 0;
}

/**
* Returns the top element of the stack, without modifying the stack.
*
* @return the top element of the stack
* @throws IllegalStateException if the stack is empty
*/
public E peek() {
public E peek(@NotOwningCollection ImmutableStack<E> this) {
if (isEmpty()) {
throw new IllegalStateException("peek() on empty stack");
}
Expand All @@ -1468,9 +1469,8 @@ public E peek() {
* Returns all of the stack except the top element.
*
* @return all of the stack except the top element
* @throws IllegalStateException if the stack is empty
*/
public ImmutableStack<E> pop() {
public ImmutableStack<E> pop(@NotOwningCollection ImmutableStack<E> this) {
if (isEmpty()) {
throw new IllegalStateException("pop() on empty stack");
}
Expand All @@ -1486,7 +1486,7 @@ public ImmutableStack<E> push(E elem) {
*
* @return the size of this stack
*/
public int size() {
public int size(@NotOwningCollection ImmutableStack<E> this) {
return size;
}

Expand All @@ -1495,7 +1495,6 @@ public int size() {
*
* @param index which element to return
* @return the index-th element of this stack
* @throws NoSuchElementException if the index is out of bounds
*/
public E get(int index) {
int n = size();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.checkerframework.afu.scenelib.field.ArrayAFT;
import org.checkerframework.afu.scenelib.field.ClassTokenAFT;
import org.checkerframework.afu.scenelib.field.EnumAFT;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.signature.qual.ClassGetName;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
Expand Down Expand Up @@ -430,7 +431,8 @@ public FieldAnnotationSceneWriter(int api, String name, FieldVisitor fv) {
}

@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
@SuppressWarnings("nullness:override.return") // ASM lacks (some?) @Nullable annotations
public @Nullable AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
existingFieldAnnotations.add(descriptor);

// If annotation exists in scene, and in overwrite mode,
Expand All @@ -443,7 +445,8 @@ public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
}

@Override
public AnnotationVisitor visitTypeAnnotation(
@SuppressWarnings("nullness:override.return") // ASM lacks (some?) @Nullable annotations
public @Nullable AnnotationVisitor visitTypeAnnotation(
int typeRef, TypePath typePath, String descriptor, boolean visible) {
// typeRef: FIELD
existingFieldAnnotations.add(descriptor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import org.checkerframework.checker.collectionownership.qual.NotOwningCollection;
import org.checkerframework.checker.collectionownership.qual.PolyOwningCollection;
import org.checkerframework.checker.mustcall.qual.NotOwning;
import org.checkerframework.checker.mustcall.qual.Owning;

/**
* A simple implementation of {@link KeyedSet} backed by an insertion-order {@link
Expand All @@ -17,7 +21,7 @@ public class LinkedHashKeyedSet<K, V> extends AbstractSet<V> implements KeyedSet
private final Keyer<? extends K, ? super V> keyer;

/** The map that backs this set. */
// Not declared as Map because some implementations of Map prohibit null keys.
// Declared as LinkedHashMap because some implementations of Map prohibit null keys.
private final LinkedHashMap<K, V> theMap = new LinkedHashMap<>();

/** The values in the set. Implemented as a view into the map. */
Expand Down Expand Up @@ -50,7 +54,7 @@ public boolean hasNext() {
}

@Override
public V next() {
public @NotOwning V next() {
return itr.next();
}

Expand All @@ -63,7 +67,7 @@ public void remove() {
}

@Override
public Iterator<V> iterator() {
public Iterator<V> iterator(@PolyOwningCollection LinkedHashKeyedSet<K, V> this) {
return new KeyedSetIterator();
}

Expand All @@ -85,7 +89,8 @@ public <T> T[] toArray(T[] a) {
* @param old the element to be removed, if {@code behavior} is REPLACE
* @return true if an element was removed
*/
private boolean checkAdd(int behavior, V old) {
private boolean checkAdd(
@NotOwningCollection LinkedHashKeyedSet<K, V> this, int behavior, V old) {
switch (behavior) {
case REPLACE:
remove(old);
Expand All @@ -104,7 +109,11 @@ private static boolean eq(Object x, Object y) {
}

@Override
public V add(V o, int conflictBehavior, int equalBehavior) {
public V add(
@NotOwningCollection LinkedHashKeyedSet<K, V> this,
V o,
int conflictBehavior,
int equalBehavior) {
K key = keyer.getKeyFor(o);
V old = theMap.get(key);
if (old == null
Expand All @@ -114,12 +123,12 @@ public V add(V o, int conflictBehavior, int equalBehavior) {
}

@Override
public boolean add(V o) {
public boolean add(@Owning V o) {
return add(o, THROW_EXCEPTION, IGNORE) == null;
Comment on lines +126 to 127
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify ownership annotations on all mutators that can insert/replace elements.
fd -t f "LinkedHashKeyedSet.java" annotation-file-utilities \
  --exec sed -n '100,170p' {}

# Verify interface declarations for add/replace contract context.
fd -t f "KeyedSet.java" annotation-file-utilities \
  --exec sed -n '1,120p' {}

# Inspect all add/replace declarations in the concrete class.
rg -n --type=java '\b(public\s+)?(boolean|V)\s+(add|replace)\s*\(' \
  annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/LinkedHashKeyedSet.java

Repository: typetools/checker-framework

Length of output: 7389


Ownership contract is inconsistent across insertion APIs.

Line 119 requires @Owning for add(V), but insertion still occurs through add(V, int, int) (Line 109) and replace(V) (Line 148) without ownership annotations. Both methods call theMap.put(), creating bypass paths that weaken ownership/RLC guarantees.

Update both KeyedSet interface and LinkedHashKeyedSet implementation:

  • Add @Owning to add(V, int, int) parameter
  • Add @Owning to replace(V) parameter
💡 Changes needed

In KeyedSet.java:

-  public abstract V add(V v, int conflictBehavior, int equalBehavior);
+  public abstract V add(`@Owning` V v, int conflictBehavior, int equalBehavior);
-  public abstract V replace(V v);
+  public abstract V replace(`@Owning` V v);

In LinkedHashKeyedSet.java:

-  public V add(V o, int conflictBehavior, int equalBehavior) {
+  public V add(`@Owning` V o, int conflictBehavior, int equalBehavior) {
-  public V replace(V v) {
+  public V replace(`@Owning` V v) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/LinkedHashKeyedSet.java`
around lines 119 - 120, The ownership contract is inconsistent: add(V) is
annotated `@Owning` but the other insertion APIs are not, allowing bypasses via
theMap.put; update the KeyedSet interface and LinkedHashKeyedSet implementation
so the parameter on add(V, int, int) and replace(V) is annotated `@Owning`
(matching add(V)), and adjust the method signatures in both KeyedSet and
LinkedHashKeyedSet (where add(V,int,int) and replace(V) call theMap.put(...)) to
enforce the same ownership contract; also add any necessary imports or
annotations to compile.

}

@Override
public boolean remove(Object o) {
public boolean remove(@NotOwningCollection LinkedHashKeyedSet<K, V> this, Object o) {
return theValues.remove(o);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.checkerframework.checker.mustcall.qual.NotOwning;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* A {@link WrapperMap} is a map all of whose methods delegate by default to those of a supplied
Expand Down Expand Up @@ -42,7 +44,7 @@ public Set<java.util.Map.Entry<K, V>> entrySet() {
}

@Override
public V get(Object key) {
public @NotOwning @Nullable V get(Object key) {
return back.get(key);
}

Expand All @@ -57,7 +59,8 @@ public Set<K> keySet() {
}

@Override
public V put(K key, V value) {
@SuppressWarnings("keyfor:contracts.postcondition") // uses a delegate map
public @NotOwning @Nullable V put(K key, V value) {
return back.put(key, value);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.checkerframework.checker.collectionownership.qual;

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;
import org.checkerframework.framework.qual.InheritedAnnotation;
import org.checkerframework.framework.qual.PostconditionAnnotation;

/**
* The annotated method destructs the given resource collection fields. That is, this method calls
* all required methods on their elements.
*
* <pre><code>
* {@literal @}CollectionFieldDestructor("socketList")
* void close() {
* for (Socket s : this.socketList) {
* try {
* s.close();
* } catch (Exception e) {}
* }
* }
* </code></pre>
*
* @checker_framework.manual #resource-leak-checker Resource Leak Checker
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@PostconditionAnnotation(qualifier = OwningCollectionWithoutObligation.class)
@InheritedAnnotation
public @interface CollectionFieldDestructor {
/**
* Returns the resource collection fields whose collection obligation the destructor fulfills.
*
* @return the resource collection fields whose collection obligation the destructor fulfills
*/
String[] value();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.checkerframework.checker.collectionownership.qual;

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;
import org.checkerframework.framework.qual.InheritedAnnotation;

/**
* A method carrying this annotation creates a {@code CollectionObligation} for the receiver
* collection.
*
* <p>Consider a call to a {@code CreatesCollectionObligation}-annotated method. If the receiver is
* of type {@code @OwningCollectionWithoutObligation}, it is unrefined to {@code @OwningCollection},
* and a CollectionObligation is created for each {@code @MustCall} method of the type variable of
* the receiver.
*
* <p>This annotation should only be used on method declarations of collections, as defined by the
* CollectionOwnershipChecker, that is, {@code java.lang.Iterable} and {@code java.util.Iterator}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is the reference to java.util.Iterator here out of date? Or does our checker actually treats Iterators as potentially owning collections?

* implementations.
*
* @checker_framework.manual #resource-leak-checker Resource Leak Checker
*/
@Documented
@InheritedAnnotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface CreatesCollectionObligation {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.checkerframework.checker.collectionownership.qual;

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;
import org.checkerframework.framework.qual.SubtypeOf;

/**
* An expression of type {@code NotOwningCollection} is a non-owning reference to a resource
* collection/array. Because it does not own the underlying collection/array, it cannot add or
* remove elements from it.
*
* @checker_framework.manual #resource-leak-checker Resource Leak Checker
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@SubtypeOf({})
public @interface NotOwningCollection {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.checkerframework.checker.collectionownership.qual;

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;
import org.checkerframework.framework.qual.SubtypeOf;

/**
* An expression of type {@code @OwningCollection} is a resource collection/array that definitely
* owns the underlying collection/array. It can add or remove elements from the collection/array.
*
* <p>The annotated expression (or one of its aliases) must either call the methods in the
* {@code @MustCall} type of its elements on all of its elements, or pass on the obligation to
* another expression.
*
* @checker_framework.manual #resource-leak-checker Resource Leak Checker
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@SubtypeOf({NotOwningCollection.class})
public @interface OwningCollection {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.checkerframework.checker.collectionownership.qual;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.checkerframework.framework.qual.DefaultFor;
import org.checkerframework.framework.qual.DefaultQualifierInHierarchy;
import org.checkerframework.framework.qual.SubtypeOf;
import org.checkerframework.framework.qual.TypeUseLocation;

/**
* The bottom qualifier of the Collection Ownership type hierarchy. It is the default qualifier.
*
* <p>An expression of type {@code @OwningCollectionBottom} is either not a collection/array or is a
* collection/array whose elements have empty {@code @MustCall} type.
*
* @checker_framework.manual #resource-leak-checker Resource Leak Checker
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@SubtypeOf({OwningCollectionWithoutObligation.class})
@DefaultQualifierInHierarchy
@DefaultFor({
TypeUseLocation.EXCEPTION_PARAMETER,
TypeUseLocation.RESOURCE_VARIABLE,
TypeUseLocation.RETURN,
TypeUseLocation.UPPER_BOUND
})
public @interface OwningCollectionBottom {}
Loading
Loading