diff --git a/.azure/azure-pipelines.yml b/.azure/azure-pipelines.yml index c1c914b6a38..d0a6278a255 100644 --- a/.azure/azure-pipelines.yml +++ b/.azure/azure-pipelines.yml @@ -75,7 +75,6 @@ jobs: git config --global core.protectNTFS false cd ../jdk21u git diff --exit-code - echo $? displayName: clone-related-jdk21u - bash: | git config --global --add safe.directory $(cd ../jdk21u && pwd) diff --git a/.azure/azure-pipelines.yml.m4 b/.azure/azure-pipelines.yml.m4 index 6a8b8c82195..5e1d4c8e38a 100644 --- a/.azure/azure-pipelines.yml.m4 +++ b/.azure/azure-pipelines.yml.m4 @@ -78,7 +78,6 @@ jobs: git config --global core.protectNTFS false cd ../jdk21u git diff --exit-code - echo $? displayName: clone-related-jdk21u - bash: | git config --global --add safe.directory $(cd ../jdk21u && pwd) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4df8c95b0b0..57d44cb35f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,7 @@ jobs: run: make jdk build_jdk21u: + if: endsWith(github.repository, '/jdk') needs: - check_generated_ci runs-on: ubuntu-latest @@ -90,10 +91,13 @@ jobs: git config --global pull.rebase false git config --global core.longpaths true git config --global core.protectNTFS false + git config --global --add safe.directory /__w/jdk/jdk # This creates ../jdk21u . # Run `git-clone-related` without a limit on depth, because if the depth is # too small, the merge will fail. Don't use "--filter=blob:none" because that # leads to "fatal: remote error: filter 'combine' not supported". + - name: ci-info + run: /tmp/$USER/plume-scripts/ci-info --debug - name: clone-related-jdk21u run: | set -ex @@ -107,7 +111,6 @@ jobs: /tmp/$USER/git-scripts/git-clone-related typetools jdk21u ../jdk21u --single-branch cd ../jdk21u git diff --exit-code - echo $? - name: git merge run: | set -ex @@ -115,7 +118,14 @@ jobs: git status eval $(/tmp/$USER/plume-scripts/ci-info typetools) echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" - cd ../jdk21u && git pull --no-edit "https://github.com/${CI_ORGANIZATION}/jdk" "${CI_BRANCH_NAME}" || (git --version && git show | head -100 && git status && git diff | head -1000 && echo "Merge failed; see 'Pull request merge conflicts' at https://github.com/typetools/jdk/blob/master/README.md " && false) + if ! git pull --no-edit "https://github.com/${CI_ORGANIZATION}/jdk" "${CI_BRANCH_NAME}"; then + git --version + git show | head -100 + git status && git diff | head -1000 + echo "Merge failed; see 'Pull request merge conflicts' at https://github.com/typetools/jdk/blob/master/README.md" + false + fi + shell: bash --noprofile --norc -e {0} - name: configure run: | cd ../jdk21u diff --git a/.github/workflows/ci.yml.m4 b/.github/workflows/ci.yml.m4 index 6fae65fcea5..50210af2491 100644 --- a/.github/workflows/ci.yml.m4 +++ b/.github/workflows/ci.yml.m4 @@ -55,6 +55,7 @@ jobs: run: make jdk build_jdk21u: + if: endsWith(github.repository, '/jdk') needs: - check_generated_ci runs-on: ubuntu-latest @@ -94,10 +95,13 @@ jobs: git config --global pull.rebase false git config --global core.longpaths true git config --global core.protectNTFS false + git config --global --add safe.directory /__w/jdk/jdk # This creates ../jdk21u . # Run `git-clone-related` without a limit on depth, because if the depth is # too small, the merge will fail. Don't use "--filter=blob:none" because that # leads to "fatal: remote error: filter 'combine' not supported". + - name: ci-info + run: /tmp/$USER/plume-scripts/ci-info --debug - name: clone-related-jdk21u run: | set -ex @@ -111,7 +115,6 @@ jobs: /tmp/$USER/git-scripts/git-clone-related typetools jdk21u ../jdk21u --single-branch cd ../jdk21u git diff --exit-code - echo $? - name: git merge run: | set -ex @@ -119,7 +122,14 @@ jobs: git status eval $(/tmp/$USER/plume-scripts/ci-info typetools) echo "About to run: git pull --no-edit https://github.com/${CI_ORGANIZATION}/jdk ${CI_BRANCH_NAME}" - cd ../jdk21u && git pull --no-edit "https://github.com/${CI_ORGANIZATION}/jdk" "${CI_BRANCH_NAME}" || (git --version && git show | head -100 && git status && git diff | head -1000 && echo "Merge failed; see 'Pull request merge conflicts' at https://github.com/typetools/jdk/blob/master/README.md " && false) + if ! git pull --no-edit "https://github.com/${CI_ORGANIZATION}/jdk" "${CI_BRANCH_NAME}"; then + git --version + git show | head -100 + git status && git diff | head -1000 + echo "Merge failed; see 'Pull request merge conflicts' at https://github.com/typetools/jdk/blob/master/README.md" + false + fi + shell: bash --noprofile --norc -e {0} - name: configure run: | cd ../jdk21u diff --git a/.github/workflows/defs.m4 b/.github/workflows/defs.m4 index 5f7252a201d..a1be2742577 100644 --- a/.github/workflows/defs.m4 +++ b/.github/workflows/defs.m4 @@ -1,9 +1,11 @@ changequote +define(`LBRACKET',`[')dnl +define(`RBRACKET',`]')dnl changequote(`[',`]')dnl - +ifelse([The built-in "dnl" m4 macro means "discard to next line",])dnl define([canary_os], [ubuntu])dnl define([canary_version], [25])dnl -define([latest_version], [25])dnl +define([latest_version], [26])dnl define([canary_test], [canary_os[]canary_version])dnl define([docker_testing], [])dnl ifelse([uncomment the next line to use the "testing" Docker images])dnl diff --git a/.gitignore b/.gitignore index 5bfc3729bf1..6ed3abd3ad5 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,4 @@ NashornProfile.txt /.cproject /compile_commands.json /.cache -.plume-scripts/ +.plume-scripts diff --git a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp index 26d60441c2d..ed828f9356b 100644 --- a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp @@ -298,7 +298,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, } else { assert(is_phantom, "only remaining strength"); assert(!is_narrow, "phantom access cannot be narrow"); - target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak); + target = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_phantom); } __ call(target); __ mv(t0, x10); diff --git a/src/java.base/share/classes/java/io/BufferedReader.java b/src/java.base/share/classes/java/io/BufferedReader.java index 54985d9826e..168f571e45c 100644 --- a/src/java.base/share/classes/java/io/BufferedReader.java +++ b/src/java.base/share/classes/java/io/BufferedReader.java @@ -38,8 +38,9 @@ import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.Iterator; import java.util.NoSuchElementException; @@ -510,8 +511,8 @@ private long implSkip(long n) throws IOException { * * @throws IOException If an I/O error occurs */ - @EnsuresNonNullIf(expression={"readLine()"}, result=true) @Pure + @EnsuresNonNullIf(expression={"readLine()"}, result=true) public boolean ready(@GuardSatisfied BufferedReader this) throws IOException { Object lock = this.lock; if (lock instanceof InternalLock locker) { @@ -708,7 +709,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public String next(/*@NonEmpty Iterator this*/) { if (nextLine != null || hasNext()) { String line = nextLine; diff --git a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java index 2a132d6f6df..22583039e6e 100644 --- a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java +++ b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java @@ -35,7 +35,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import jdk.internal.math.DoubleToDecimal; @@ -527,7 +527,7 @@ public int codePointBefore(@Positive int index) { * {@code dst.length} * */ - @SideEffectsOnly("#3") + // @SideEffectsOnly("#3") public void getChars(@NonNegative int srcBegin, @NonNegative int srcEnd, char[] dst, @IndexOrHigh({"#3"}) int dstBegin) { Preconditions.checkFromToIndex(srcBegin, srcEnd, count, Preconditions.SIOOBE_FORMATTER); // compatible to old version diff --git a/src/java.base/share/classes/java/lang/CharSequence.java b/src/java.base/share/classes/java/lang/CharSequence.java index e79f030b6ed..3469c83c9bd 100644 --- a/src/java.base/share/classes/java/lang/CharSequence.java +++ b/src/java.base/share/classes/java/lang/CharSequence.java @@ -34,8 +34,9 @@ import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.NoSuchElementException; import java.util.Objects; @@ -174,7 +175,8 @@ public boolean hasNext() { return cur < length(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int nextInt(@NonEmpty CharIterator this) { if (hasNext()) { return charAt(cur++); @@ -251,7 +253,8 @@ public boolean hasNext() { return cur < length(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int nextInt(@NonEmpty CodePointIterator this) { final int length = length(); diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index a045fbc5537..3062174a591 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -853,8 +853,8 @@ public Void run() { * {@code false} otherwise. * @since 1.1 */ - @EnsuresNonNullIf(expression={"getComponentType()"}, result=true) @Pure + @EnsuresNonNullIf(expression={"getComponentType()"}, result=true) @IntrinsicCandidate public native boolean isArray(@GuardSatisfied Class this); diff --git a/src/java.base/share/classes/java/lang/StackStreamFactory.java b/src/java.base/share/classes/java/lang/StackStreamFactory.java index 2900a4f31ce..e2df08c6e17 100644 --- a/src/java.base/share/classes/java/lang/StackStreamFactory.java +++ b/src/java.base/share/classes/java/lang/StackStreamFactory.java @@ -26,7 +26,7 @@ import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import jdk.internal.reflect.MethodAccessor; import jdk.internal.reflect.ConstructorAccessor; import java.lang.StackWalker.Option; @@ -375,7 +375,7 @@ private void setContinuation(Continuation cont) { * * @see #tryNextFrame */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") final Class nextFrame() { if (!hasNext()) { return null; diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index adbab0732fd..412e998ec96 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -56,7 +56,7 @@ import org.checkerframework.common.value.qual.StringVal; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; @@ -1777,7 +1777,7 @@ public int codePointBefore(@LTEqLengthOf({"this"}) @Positive int index) { *
  • {@code dstBegin+(srcEnd-srcBegin)} is larger than * {@code dst.length} */ - @SideEffectsOnly("#3") + // @SideEffectsOnly("#3") public void getChars(@IndexOrHigh({"this"}) int srcBegin, @IndexOrHigh({"this"}) int srcEnd, char @GuardSatisfied [] dst, @IndexOrHigh({"#3"}) int dstBegin) { checkBoundsBeginEnd(srcBegin, srcEnd, length()); checkBoundsOffCount(dstBegin, srcEnd - srcBegin, dst.length); @@ -1934,8 +1934,8 @@ public void getBytes(@IndexOrHigh({"this"}) int srcBegin, @IndexOrHigh({"this"}) * @see #compareTo(String) * @see #equalsIgnoreCase(String) */ - @EnsuresNonNullIf(expression={"#1"}, result=true) @Pure + @EnsuresNonNullIf(expression={"#1"}, result=true) @StaticallyExecutable public boolean equals(@GuardSatisfied @Nullable Object anObject) { if (this == anObject) { @@ -2073,8 +2073,8 @@ public boolean contentEquals(@GuardSatisfied CharSequence cs) { * @see #equals(Object) * @see #codePoints() */ - @EnsuresNonNullIf(expression={"#1"}, result=true) @Pure + @EnsuresNonNullIf(expression={"#1"}, result=true) @StaticallyExecutable public boolean equalsIgnoreCase(@Nullable String anotherString) { return (this == anotherString) ? true diff --git a/src/java.base/share/classes/java/lang/StringBuffer.java b/src/java.base/share/classes/java/lang/StringBuffer.java index c753cc66ec4..7e84758f72d 100644 --- a/src/java.base/share/classes/java/lang/StringBuffer.java +++ b/src/java.base/share/classes/java/lang/StringBuffer.java @@ -35,7 +35,7 @@ import org.checkerframework.common.aliasing.qual.Unique; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import java.io.IOException; @@ -304,7 +304,7 @@ public synchronized int offsetByCodePoints(int index, int codePointOffset) { /** * @throws IndexOutOfBoundsException {@inheritDoc} */ - @SideEffectsOnly("#3") + // @SideEffectsOnly("#3") @Override public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, @IndexOrHigh({"#3"}) int dstBegin) diff --git a/src/java.base/share/classes/java/lang/StringBuilder.java b/src/java.base/share/classes/java/lang/StringBuilder.java index 6c17308dfdb..641a2f40026 100644 --- a/src/java.base/share/classes/java/lang/StringBuilder.java +++ b/src/java.base/share/classes/java/lang/StringBuilder.java @@ -34,7 +34,7 @@ import org.checkerframework.checker.regex.qual.PolyRegex; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import jdk.internal.vm.annotation.IntrinsicCandidate; @@ -183,14 +183,14 @@ public int compareTo(StringBuilder another) { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(@GuardSatisfied @Nullable Object obj) { return append(String.valueOf(obj)); } @Override @IntrinsicCandidate - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(@Nullable String str) { super.append(str); return this; @@ -215,14 +215,14 @@ public StringBuilder append(@Nullable String str) { * @param sb the {@code StringBuffer} to append. * @return a reference to this object. */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(@Nullable StringBuffer sb) { super.append(sb); return this; } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(@Nullable CharSequence s) { super.append(s); return this; @@ -232,14 +232,14 @@ public StringBuilder append(@Nullable CharSequence s) { * @throws IndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(@Nullable CharSequence s, @IndexOrHigh({"#1"}) int start, @IndexOrHigh({"#1"}) int end) { super.append(s, start, end); return this; } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(char[] str) { super.append(str); return this; @@ -249,14 +249,14 @@ public StringBuilder append(char[] str) { * @throws IndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(char[] str, @IndexOrHigh({"#1"}) int offset, @LTLengthOf(value={"#1"}, offset={"#2 - 1"}) @NonNegative int len) { super.append(str, offset, len); return this; } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(boolean b) { super.append(b); return this; @@ -264,7 +264,7 @@ public StringBuilder append(boolean b) { @Override @IntrinsicCandidate - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(char c) { super.append(c); return this; @@ -272,28 +272,28 @@ public StringBuilder append(char c) { @Override @IntrinsicCandidate - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(int i) { super.append(i); return this; } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(long lng) { super.append(lng); return this; } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(float f) { super.append(f); return this; } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder append(double d) { super.append(d); return this; @@ -303,7 +303,7 @@ public StringBuilder append(double d) { * @since 1.5 */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder appendCodePoint(int codePoint) { super.appendCodePoint(codePoint); return this; @@ -313,7 +313,7 @@ public StringBuilder appendCodePoint(int codePoint) { * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder delete(@NonNegative int start, @NonNegative int end) { super.delete(start, end); return this; @@ -323,7 +323,7 @@ public StringBuilder delete(@NonNegative int start, @NonNegative int end) { * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder deleteCharAt(@NonNegative int index) { super.deleteCharAt(index); return this; @@ -333,7 +333,7 @@ public StringBuilder deleteCharAt(@NonNegative int index) { * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder replace(@NonNegative int start, @NonNegative int end, String str) { super.replace(start, end, str); return this; @@ -343,7 +343,7 @@ public StringBuilder replace(@NonNegative int start, @NonNegative int end, Strin * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int index, char[] str, @IndexOrHigh({"#2"}) int offset, @IndexOrHigh({"#2"}) int len) { @@ -355,7 +355,7 @@ public StringBuilder insert(@NonNegative int index, char[] str, @IndexOrHigh({"# * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int offset, @GuardSatisfied @Nullable Object obj) { super.insert(offset, obj); return this; @@ -365,7 +365,7 @@ public StringBuilder insert(@NonNegative int offset, @GuardSatisfied @Nullable O * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int offset, @Nullable String str) { super.insert(offset, str); return this; @@ -375,7 +375,7 @@ public StringBuilder insert(@NonNegative int offset, @Nullable String str) { * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int offset, char[] str) { super.insert(offset, str); return this; @@ -385,7 +385,7 @@ public StringBuilder insert(@NonNegative int offset, char[] str) { * @throws IndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int dstOffset, @Nullable CharSequence s) { super.insert(dstOffset, s); return this; @@ -395,7 +395,7 @@ public StringBuilder insert(@NonNegative int dstOffset, @Nullable CharSequence s * @throws IndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int dstOffset, @Nullable CharSequence s, @NonNegative int start, @NonNegative int end) { @@ -407,7 +407,7 @@ public StringBuilder insert(@NonNegative int dstOffset, @Nullable CharSequence s * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int offset, boolean b) { super.insert(offset, b); return this; @@ -417,7 +417,7 @@ public StringBuilder insert(@NonNegative int offset, boolean b) { * @throws IndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int offset, char c) { super.insert(offset, c); return this; @@ -427,7 +427,7 @@ public StringBuilder insert(@NonNegative int offset, char c) { * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int offset, int i) { super.insert(offset, i); return this; @@ -437,7 +437,7 @@ public StringBuilder insert(@NonNegative int offset, int i) { * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int offset, long l) { super.insert(offset, l); return this; @@ -447,7 +447,7 @@ public StringBuilder insert(@NonNegative int offset, long l) { * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int offset, float f) { super.insert(offset, f); return this; @@ -457,7 +457,7 @@ public StringBuilder insert(@NonNegative int offset, float f) { * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder insert(@NonNegative int offset, double d) { super.insert(offset, d); return this; @@ -488,7 +488,7 @@ public StringBuilder insert(@NonNegative int offset, double d) { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public StringBuilder reverse() { super.reverse(); return this; @@ -499,7 +499,7 @@ public StringBuilder reverse() { * * @since 21 */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") @Override @SideEffectFree public StringBuilder repeat(int codePoint, int count) { @@ -512,7 +512,7 @@ public StringBuilder repeat(int codePoint, int count) { * * @since 21 */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") @Override public StringBuilder repeat(CharSequence cs, int count) { super.repeat(cs, count); diff --git a/src/java.base/share/classes/java/lang/StringLatin1.java b/src/java.base/share/classes/java/lang/StringLatin1.java index fc60e533a50..6ea2269026d 100644 --- a/src/java.base/share/classes/java/lang/StringLatin1.java +++ b/src/java.base/share/classes/java/lang/StringLatin1.java @@ -25,7 +25,7 @@ package java.lang; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import java.util.Arrays; import java.util.Locale; @@ -85,7 +85,7 @@ public static byte[] inflate(byte[] value, int off, int len) { return ret; } - @SideEffectsOnly("#3") + // @SideEffectsOnly("#3") public static void getChars(byte[] value, int srcBegin, int srcEnd, char[] dst, int dstBegin) { inflate(value, srcBegin, dst, dstBegin, srcEnd - srcBegin); } diff --git a/src/java.base/share/classes/java/lang/StringUTF16.java b/src/java.base/share/classes/java/lang/StringUTF16.java index 5ac6b14182d..30e1dd8f1e7 100644 --- a/src/java.base/share/classes/java/lang/StringUTF16.java +++ b/src/java.base/share/classes/java/lang/StringUTF16.java @@ -25,7 +25,7 @@ package java.lang; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import java.util.Arrays; import java.util.Locale; @@ -433,7 +433,7 @@ static byte[] toBytesSupplementary(int cp) { } @IntrinsicCandidate - @SideEffectsOnly("#3") + // @SideEffectsOnly("#3") public static void getChars(byte[] value, int srcBegin, int srcEnd, char[] dst, int dstBegin) { // We need a range check here because 'getChar' has no checks if (srcBegin < srcEnd) { diff --git a/src/java.base/share/classes/java/lang/invoke/AbstractConstantGroup.java b/src/java.base/share/classes/java/lang/invoke/AbstractConstantGroup.java index 1863d17c082..075fe0f562d 100644 --- a/src/java.base/share/classes/java/lang/invoke/AbstractConstantGroup.java +++ b/src/java.base/share/classes/java/lang/invoke/AbstractConstantGroup.java @@ -28,7 +28,8 @@ import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.*; import jdk.internal.vm.annotation.Stable; @@ -100,7 +101,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Object next(@NonEmpty AsIterator this) { int i = bumpIndex(); if (resolving) diff --git a/src/java.base/share/classes/java/net/URL.java b/src/java.base/share/classes/java/net/URL.java index 56c7f6c8496..9aaf4a1b7df 100644 --- a/src/java.base/share/classes/java/net/URL.java +++ b/src/java.base/share/classes/java/net/URL.java @@ -33,8 +33,9 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.File; import java.io.IOException; @@ -1512,7 +1513,8 @@ public boolean hasNext() { return getNext(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public URLStreamHandlerProvider next(/*@NonEmpty Iterator this*/) { if (!getNext()) throw new NoSuchElementException(); diff --git a/src/java.base/share/classes/java/nio/charset/Charset.java b/src/java.base/share/classes/java/nio/charset/Charset.java index 8211245916e..d4b4eb59191 100644 --- a/src/java.base/share/classes/java/nio/charset/Charset.java +++ b/src/java.base/share/classes/java/nio/charset/Charset.java @@ -28,7 +28,8 @@ import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import jdk.internal.misc.ThreadTracker; import jdk.internal.misc.VM; @@ -369,7 +370,8 @@ public boolean hasNext() { return getNext(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public CharsetProvider next(/*@NonEmpty Iterator this*/) { if (!getNext()) throw new NoSuchElementException(); diff --git a/src/java.base/share/classes/java/nio/file/FileTreeIterator.java b/src/java.base/share/classes/java/nio/file/FileTreeIterator.java index 1015bb8f2c1..fff8cbec475 100644 --- a/src/java.base/share/classes/java/nio/file/FileTreeIterator.java +++ b/src/java.base/share/classes/java/nio/file/FileTreeIterator.java @@ -28,7 +28,8 @@ import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.Closeable; import java.io.IOException; @@ -112,7 +113,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Event next(@NonEmpty FileTreeIterator this) { if (!walker.isOpen()) throw new IllegalStateException(); diff --git a/src/java.base/share/classes/java/nio/file/Files.java b/src/java.base/share/classes/java/nio/file/Files.java index 47a14596b4c..959034b566f 100644 --- a/src/java.base/share/classes/java/nio/file/Files.java +++ b/src/java.base/share/classes/java/nio/file/Files.java @@ -30,12 +30,13 @@ import org.checkerframework.checker.mustcall.qual.MustCall; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; +import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -3878,7 +3879,8 @@ public boolean hasNext() { throw new UncheckedIOException(e.getCause()); } } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Override public Path next(/*@NonEmpty Iterator this*/) { try { diff --git a/src/java.base/share/classes/java/nio/file/Path.java b/src/java.base/share/classes/java/nio/file/Path.java index a5e263acdae..d1ab91c4bec 100644 --- a/src/java.base/share/classes/java/nio/file/Path.java +++ b/src/java.base/share/classes/java/nio/file/Path.java @@ -30,8 +30,9 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.File; import java.io.IOException; @@ -962,7 +963,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Path next(/*@NonEmpty Iterator this*/) { if (i < getNameCount()) { Path result = getName(i); diff --git a/src/java.base/share/classes/java/security/Provider.java b/src/java.base/share/classes/java/security/Provider.java index ac75e1630ca..57875c937c0 100644 --- a/src/java.base/share/classes/java/security/Provider.java +++ b/src/java.base/share/classes/java/security/Provider.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import javax.security.auth.login.Configuration; import jdk.internal.event.SecurityProviderServiceEvent; @@ -637,6 +638,7 @@ public synchronized Object replace(Object key, Object value) { * @since 1.8 */ @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void replaceAll(BiFunction function) { check("putProviderProperty." + name); @@ -665,6 +667,7 @@ public synchronized void replaceAll(BiFunction remappingFunction) { check("putProviderProperty." + name); @@ -695,6 +698,7 @@ public synchronized void replaceAll(BiFunction mappingFunction) { check("putProviderProperty." + name); @@ -724,6 +728,7 @@ public synchronized void replaceAll(BiFunction remappingFunction) { @@ -757,6 +762,7 @@ public synchronized void replaceAll(BiFunction remappingFunction) { diff --git a/src/java.base/share/classes/java/util/AbstractCollection.java b/src/java.base/share/classes/java/util/AbstractCollection.java index 7b1300ad87e..d38628827e0 100644 --- a/src/java.base/share/classes/java/util/AbstractCollection.java +++ b/src/java.base/share/classes/java/util/AbstractCollection.java @@ -39,6 +39,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import jdk.internal.util.ArraysSupport; @@ -275,6 +276,8 @@ private static T[] finishToArray(T[] r, Iterator it) { * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@GuardSatisfied AbstractCollection this, E e) { throw new UnsupportedOperationException(); } @@ -296,6 +299,8 @@ public boolean add(@GuardSatisfied AbstractCollection this, E e) { * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @CanShrink AbstractCollection this, @GuardSatisfied @UnknownSignedness Object o) { Iterator it = iterator(); if (o==null) { @@ -359,6 +364,8 @@ public boolean containsAll(@GuardSatisfied AbstractCollection this, @GuardSat * * @see #add(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@GuardSatisfied AbstractCollection this, Collection c) { boolean modified = false; for (E e : c) @@ -389,6 +396,8 @@ public boolean addAll(@GuardSatisfied AbstractCollection this, Collection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; @@ -424,6 +433,8 @@ public boolean removeAll(@GuardSatisfied @CanShrink AbstractCollection this, * @see #remove(Object) * @see #contains(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@GuardSatisfied @CanShrink AbstractCollection this, Collection c) { Objects.requireNonNull(c); boolean modified = false; @@ -453,6 +464,8 @@ public boolean retainAll(@GuardSatisfied @CanShrink AbstractCollection this, * * @throws UnsupportedOperationException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink AbstractCollection this) { Iterator it = iterator(); while (it.hasNext()) { diff --git a/src/java.base/share/classes/java/util/AbstractList.java b/src/java.base/share/classes/java/util/AbstractList.java index cb72fccb35f..7997e85e864 100644 --- a/src/java.base/share/classes/java/util/AbstractList.java +++ b/src/java.base/share/classes/java/util/AbstractList.java @@ -39,9 +39,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.function.Consumer; @@ -131,6 +132,8 @@ protected AbstractList() { * prevents it from being added to this list */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@GuardSatisfied AbstractList this, E e) { add(size(), e); return true; @@ -157,6 +160,8 @@ public boolean add(@GuardSatisfied AbstractList this, E e) { * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(@GuardSatisfied AbstractList this, @IndexFor({"this"}) int index, E element) { throw new UnsupportedOperationException(); } @@ -174,6 +179,8 @@ public E set(@GuardSatisfied AbstractList this, @IndexFor({"this"}) int index * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(@GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, E element) { throw new UnsupportedOperationException(); } @@ -188,6 +195,8 @@ public void add(@GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int * @throws UnsupportedOperationException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(@GuardSatisfied @CanShrink AbstractList this, @IndexFor({"this"}) int index) { throw new UnsupportedOperationException(); } @@ -266,6 +275,8 @@ public E remove(@GuardSatisfied @CanShrink AbstractList this, @IndexFor({"thi * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this list */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink AbstractList this) { removeRange(0, size()); } @@ -290,6 +301,8 @@ public void clear(@GuardSatisfied @CanShrink AbstractList this) { * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@GuardSatisfied AbstractList this, @IndexOrHigh({"this"}) int index, Collection c) { rangeCheckForAdd(index); boolean modified = false; @@ -394,7 +407,8 @@ public boolean hasNext() { return cursor != size(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty Itr this) { checkForComodification(); try { @@ -409,6 +423,8 @@ public E next(@NonEmpty Itr this) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastRet < 0) throw new IllegalStateException(); @@ -436,6 +452,7 @@ private class ListItr extends Itr implements ListIterator { cursor = index; } + @Pure public boolean hasPrevious() { return cursor != 0; } @@ -453,14 +470,18 @@ public E previous() { } } + @Pure public int nextIndex() { return cursor; } + @Pure public int previousIndex() { return cursor-1; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); @@ -474,6 +495,8 @@ public void set(E e) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { checkForComodification(); @@ -625,6 +648,8 @@ public int hashCode(@GuardSatisfied AbstractList this) { * @param fromIndex index of first element to be removed * @param toIndex index after last element to be removed */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") protected void removeRange(@GuardSatisfied @CanShrink AbstractList this, @IndexOrHigh({"this"}) int fromIndex, @IndexOrHigh({"this"}) int toIndex) { ListIterator it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i E get(List list, int i) { try { return list.get(i); @@ -808,12 +834,15 @@ protected SubList(SubList parent, int fromIndex, int toIndex) { this.modCount = root.modCount; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(int index, E element) { Objects.checkIndex(index, size); checkForComodification(); return root.set(offset + index, element); } + @Pure public E get(int index) { Objects.checkIndex(index, size); checkForComodification(); @@ -826,6 +855,8 @@ public int size() { return size; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(int index, E element) { rangeCheckForAdd(index); checkForComodification(); @@ -833,6 +864,8 @@ public void add(int index, E element) { updateSizeAndModCount(1); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(int index) { Objects.checkIndex(index, size); checkForComodification(); @@ -847,10 +880,14 @@ protected void removeRange(int fromIndex, int toIndex) { updateSizeAndModCount(fromIndex - toIndex); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { return addAll(size, c); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { rangeCheckForAdd(index); int cSize = c.size(); @@ -862,6 +899,7 @@ public boolean addAll(int index, Collection c) { return true; } + @SideEffectFree public Iterator iterator() { return listIterator(); } @@ -880,7 +918,8 @@ public boolean hasNext() { return nextIndex() < size; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(/*@NonEmpty ListIterator this*/) { if (hasNext()) return i.next(); @@ -893,7 +932,7 @@ public boolean hasPrevious() { return previousIndex() >= 0; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public E previous() { if (hasPrevious()) return i.previous(); @@ -911,15 +950,21 @@ public int previousIndex() { return i.previousIndex() - offset; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { i.remove(); updateSizeAndModCount(-1); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { i.set(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { i.add(e); updateSizeAndModCount(1); @@ -927,6 +972,7 @@ public void add(E e) { }; } + @SideEffectFree public List subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList<>(this, fromIndex, toIndex); @@ -976,6 +1022,7 @@ private static class RandomAccessSubList super(parent, fromIndex, toIndex); } + @SideEffectFree public List subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new RandomAccessSubList<>(this, fromIndex, toIndex); diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index 806a5146c43..79f7049ca70 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -37,9 +37,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.stream.Stream; import java.util.function.Consumer; @@ -167,8 +168,8 @@ public boolean containsValue(@GuardSatisfied AbstractMap this, @GuardSatis * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) @Pure + @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { Iterator> i = entrySet().iterator(); if (key==null) { @@ -237,6 +238,8 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi */ @ReleasesNoLocks @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(@GuardSatisfied AbstractMap this, K key, V value) { throw new UnsupportedOperationException(); } @@ -263,6 +266,8 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V remove(@GuardSatisfied AbstractMap this, @GuardSatisfied @UnknownSignedness Object key) { Iterator> i = entrySet().iterator(); Entry correctEntry = null; @@ -308,6 +313,8 @@ public boolean containsKey(@GuardSatisfied AbstractMap this, @GuardSatisfi * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putAll(@GuardSatisfied AbstractMap this, Map m) { for (Map.Entry e : m.entrySet()) put(e.getKey(), e.getValue()); @@ -325,6 +332,8 @@ public void putAll(@GuardSatisfied AbstractMap this, Map this) { entrySet().clear(); } @@ -380,6 +389,7 @@ public void clear(@GuardSatisfied AbstractMap this) { Set ks = keySet; if (ks == null) { ks = new AbstractSet() { + @SideEffectFree public Iterator iterator() { return new Iterator() { private Iterator> i = entrySet().iterator(); @@ -390,11 +400,14 @@ public boolean hasNext() { return i.hasNext(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K next(/*@NonEmpty Iterator this*/) { return i.next().getKey(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { i.remove(); } @@ -412,10 +425,13 @@ public boolean isEmpty() { return AbstractMap.this.isEmpty(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { AbstractMap.this.clear(); } + @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@UnknownSignedness Object k) { return AbstractMap.this.containsKey(k); @@ -447,6 +463,7 @@ public Collection values(@GuardSatisfied AbstractMap this) { Collection vals = values; if (vals == null) { vals = new AbstractCollection() { + @SideEffectFree public Iterator iterator() { return new Iterator() { private Iterator> i = entrySet().iterator(); @@ -457,11 +474,14 @@ public boolean hasNext() { return i.hasNext(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V next(/*@NonEmpty Iterator this*/) { return i.next().getValue(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { i.remove(); } @@ -479,10 +499,13 @@ public boolean isEmpty() { return AbstractMap.this.isEmpty(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { AbstractMap.this.clear(); } + @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@UnknownSignedness Object v) { return AbstractMap.this.containsValue(v); @@ -615,6 +638,7 @@ public String toString(@GuardSatisfied AbstractMap this) { * * @return a shallow copy of this map */ + @SideEffectFree protected Object clone() throws CloneNotSupportedException { AbstractMap result = (AbstractMap)super.clone(); result.keySet = null; @@ -718,6 +742,8 @@ public V getValue(AbstractMap.@GuardSatisfied SimpleEntry this) { * @param value new value to be stored in this entry * @return the old value corresponding to the entry */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V setValue(AbstractMap.@GuardSatisfied SimpleEntry this, V value) { V oldValue = this.value; this.value = value; @@ -961,25 +987,47 @@ public String toString(AbstractMap.@GuardSatisfied SimpleImmutableEntry th UnsupportedOperationException uoe() { return new UnsupportedOperationException(); } abstract Collection view(); + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E t) { throw uoe(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { throw uoe(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { view().clear(); } + @Pure public boolean contains(Object o) { return view().contains(o); } + @Pure public boolean containsAll(Collection c) { return view().containsAll(c); } public void forEach(Consumer c) { view().forEach(c); } + @Pure public boolean isEmpty() { return view().isEmpty(); } + @SideEffectFree public Iterator iterator() { return view().iterator(); } public Stream parallelStream() { return view().parallelStream(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(Object o) { return view().remove(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return view().removeAll(c); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { return view().removeIf(filter); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { return view().retainAll(c); } + @Pure public int size() { return view().size(); } + @SideEffectFree public Spliterator spliterator() { return view().spliterator(); } public Stream stream() { return view().stream(); } + @SideEffectFree public Object[] toArray() { return view().toArray(); } public T[] toArray(IntFunction generator) { return view().toArray(generator); } public T[] toArray(T[] a) { return view().toArray(a); } + @SideEffectFree public String toString() { return view().toString(); } } } diff --git a/src/java.base/share/classes/java/util/AbstractQueue.java b/src/java.base/share/classes/java/util/AbstractQueue.java index 0bd11fc96d0..c349250b238 100644 --- a/src/java.base/share/classes/java/util/AbstractQueue.java +++ b/src/java.base/share/classes/java/util/AbstractQueue.java @@ -39,7 +39,9 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.NonEmpty; +import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * This class provides skeletal implementations of some {@link Queue} @@ -99,6 +101,8 @@ protected AbstractQueue() { * prevents it from being added to this queue */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@GuardSatisfied AbstractQueue this, E e) { if (offer(e)) return true; @@ -117,6 +121,8 @@ public boolean add(@GuardSatisfied AbstractQueue this, E e) { * @return the head of this queue * @throws NoSuchElementException if this queue is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(@GuardSatisfied @NonEmpty @CanShrink AbstractQueue this) { E x = poll(); if (x != null) @@ -136,6 +142,7 @@ public E remove(@GuardSatisfied @NonEmpty @CanShrink AbstractQueue this) { * @return the head of this queue * @throws NoSuchElementException if this queue is empty */ + @Pure public E element(@GuardSatisfied @NonEmpty AbstractQueue this) { E x = peek(); if (x != null) @@ -151,6 +158,8 @@ public E element(@GuardSatisfied @NonEmpty AbstractQueue this) { *

    This implementation repeatedly invokes {@link #poll poll} until it * returns {@code null}. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink AbstractQueue this) { while (poll() != null) ; @@ -185,6 +194,8 @@ public void clear(@GuardSatisfied @CanShrink AbstractQueue this) { * this time due to insertion restrictions * @see #add(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@GuardSatisfied AbstractQueue this, Collection c) { if (c == null) throw new NullPointerException(); diff --git a/src/java.base/share/classes/java/util/AbstractSequentialList.java b/src/java.base/share/classes/java/util/AbstractSequentialList.java index 9097f49066f..a8932d5d667 100644 --- a/src/java.base/share/classes/java/util/AbstractSequentialList.java +++ b/src/java.base/share/classes/java/util/AbstractSequentialList.java @@ -33,6 +33,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * This class provides a skeletal implementation of the {@code List} @@ -124,6 +125,8 @@ public E get(@GuardSatisfied AbstractSequentialList this, int index) { * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(@GuardSatisfied AbstractSequentialList this, int index, E element) { try { ListIterator e = listIterator(index); @@ -155,6 +158,8 @@ public E set(@GuardSatisfied AbstractSequentialList this, int index, E elemen * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(@GuardSatisfied AbstractSequentialList this, int index, E element) { try { listIterator(index).add(element); @@ -180,6 +185,8 @@ public void add(@GuardSatisfied AbstractSequentialList this, int index, E ele * @throws UnsupportedOperationException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(@GuardSatisfied @CanShrink AbstractSequentialList this, int index) { try { ListIterator e = listIterator(index); @@ -223,6 +230,8 @@ public E remove(@GuardSatisfied @CanShrink AbstractSequentialList this, int i * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@GuardSatisfied AbstractSequentialList this, int index, Collection c) { try { boolean modified = false; diff --git a/src/java.base/share/classes/java/util/AbstractSet.java b/src/java.base/share/classes/java/util/AbstractSet.java index a18723fbaca..19e90776f4b 100644 --- a/src/java.base/share/classes/java/util/AbstractSet.java +++ b/src/java.base/share/classes/java/util/AbstractSet.java @@ -31,6 +31,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * This class provides a skeletal implementation of the {@code Set} @@ -174,6 +175,8 @@ public int hashCode(@GuardSatisfied AbstractSet this) { * @see #remove(Object) * @see #contains(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@GuardSatisfied AbstractSet this, Collection c) { Objects.requireNonNull(c); boolean modified = false; diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index bb84f591155..56490f98106 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -50,8 +50,9 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.Serializable; import java.util.function.Consumer; @@ -301,6 +302,8 @@ static final E nonNullElementAt(@PolyNull @PolySigned Object[] es, int i) { * @param e the element to add * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(@GuardSatisfied ArrayDeque this, E e) { if (e == null) throw new NullPointerException(); @@ -318,6 +321,8 @@ public void addFirst(@GuardSatisfied ArrayDeque this, E e) { * @param e the element to add * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(@GuardSatisfied ArrayDeque this, E e) { if (e == null) throw new NullPointerException(); @@ -337,6 +342,8 @@ public void addLast(@GuardSatisfied ArrayDeque this, E e) { * @throws NullPointerException if the specified collection or any * of its elements are null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { final int s, needed; if ((needed = (s = size()) + c.size() + 1 - elements.length) > 0) @@ -356,6 +363,8 @@ private void copyElements(Collection c) { * @return {@code true} (as specified by {@link Deque#offerFirst}) * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(E e) { addFirst(e); return true; @@ -368,6 +377,8 @@ public boolean offerFirst(E e) { * @return {@code true} (as specified by {@link Deque#offerLast}) * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(E e) { addLast(e); return true; @@ -376,6 +387,8 @@ public boolean offerLast(E e) { /** * @throws NoSuchElementException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { E e = pollFirst(); if (e == null) @@ -386,6 +399,8 @@ public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { /** * @throws NoSuchElementException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeLast(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { E e = pollLast(); if (e == null) @@ -393,6 +408,8 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { return e; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@GuardSatisfied @CanShrink ArrayDeque this) { final Object[] es; final int h; @@ -404,6 +421,8 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { return e; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@GuardSatisfied @CanShrink ArrayDeque this) { final Object[] es; final int t; @@ -416,6 +435,7 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E getFirst(@GuardSatisfied @NonEmpty ArrayDeque this) { E e = elementAt(elements, head); if (e == null) @@ -426,6 +446,7 @@ public E getFirst(@GuardSatisfied @NonEmpty ArrayDeque this) { /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E getLast(@GuardSatisfied @NonEmpty ArrayDeque this) { final Object[] es = elements; E e = elementAt(es, dec(tail, es.length)); @@ -457,6 +478,8 @@ public E getLast(@GuardSatisfied @NonEmpty ArrayDeque this) { * @param o element to be removed from this deque, if present * @return {@code true} if the deque contained the specified element */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeFirstOccurrence(@GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o != null) { final Object[] es = elements; @@ -485,6 +508,8 @@ public boolean removeFirstOccurrence(@GuardSatisfied @CanShrink ArrayDeque th * @param o element to be removed from this deque, if present * @return {@code true} if the deque contained the specified element */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeLastOccurrence(@GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o != null) { final Object[] es = elements; @@ -513,6 +538,8 @@ public boolean removeLastOccurrence(@GuardSatisfied @CanShrink ArrayDeque thi * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@GuardSatisfied ArrayDeque this, E e) { addLast(e); return true; @@ -527,6 +554,8 @@ public boolean add(@GuardSatisfied ArrayDeque this, E e) { * @return {@code true} (as specified by {@link Queue#offer}) * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(@GuardSatisfied ArrayDeque this, E e) { return offerLast(e); } @@ -542,6 +571,8 @@ public boolean offer(@GuardSatisfied ArrayDeque this, E e) { * @return the head of the queue represented by this deque * @throws NoSuchElementException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { return removeFirst(); } @@ -556,6 +587,8 @@ public E remove(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { * @return the head of the queue represented by this deque, or * {@code null} if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink ArrayDeque this) { return pollFirst(); } @@ -570,6 +603,7 @@ public E remove(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { * @return the head of the queue represented by this deque * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E element(@GuardSatisfied @NonEmpty ArrayDeque this) { return getFirst(); } @@ -599,6 +633,8 @@ public E element(@GuardSatisfied @NonEmpty ArrayDeque this) { * @param e the element to push * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void push(@GuardSatisfied ArrayDeque this, E e) { addFirst(e); } @@ -613,6 +649,8 @@ public void push(@GuardSatisfied ArrayDeque this, E e) { * of the stack represented by this deque) * @throws NoSuchElementException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E pop(@GuardSatisfied @NonEmpty @CanShrink ArrayDeque this) { return removeFirst(); } @@ -724,7 +762,8 @@ public final boolean hasNext() { return remaining > 0; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty DeqIterator this) { if (remaining <= 0) throw new NoSuchElementException(); @@ -740,6 +779,8 @@ void postDelete(boolean leftShifted) { cursor = dec(cursor, elements.length); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void remove() { if (lastRet < 0) throw new IllegalStateException(); @@ -773,6 +814,8 @@ public void forEachRemaining(Consumer action) { private class DescendingIterator extends DeqIterator { DescendingIterator() { cursor = dec(tail, elements.length); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final E next(@NonEmpty DescendingIterator this) { if (remaining <= 0) throw new NoSuchElementException(); @@ -825,6 +868,7 @@ public final void forEachRemaining(Consumer action) { * @return a {@code Spliterator} over the elements in this deque * @since 1.8 */ + @SideEffectFree public Spliterator spliterator() { return new DeqSpliterator(); } @@ -928,6 +972,8 @@ public void forEach(Consumer action) { /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@CanShrink ArrayDeque this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -936,6 +982,8 @@ public boolean removeIf(@CanShrink ArrayDeque this, Predicate filt /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@CanShrink ArrayDeque this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -944,6 +992,8 @@ public boolean removeAll(@CanShrink ArrayDeque this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); @@ -1060,6 +1110,8 @@ public boolean contains(@GuardSatisfied ArrayDeque this, @GuardSatisfied @Nul * @param o element to be removed from this deque, if present * @return {@code true} if this deque contained the specified element */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @CanShrink ArrayDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeFirstOccurrence(o); } @@ -1068,6 +1120,8 @@ public boolean remove(@GuardSatisfied @CanShrink ArrayDeque this, @GuardSatis * Removes all of the elements from this deque. * The deque will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink ArrayDeque this) { circularClear(elements, head, tail); head = tail = 0; diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index e963b43e6f2..13733eae45c 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -42,9 +42,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.function.Consumer; import java.util.function.Predicate; @@ -448,6 +449,7 @@ E elementData(@NonNegative int index) { } @SuppressWarnings("unchecked") + @Pure static E elementAt(Object[] es, int index) { return (E) es[index]; } @@ -471,6 +473,7 @@ public E get(@GuardSatisfied ArrayList this, @NonNegative int index) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getFirst() { if (size == 0) { throw new NoSuchElementException(); @@ -485,6 +488,7 @@ public E getFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getLast() { int last = size - 1; if (last < 0) { @@ -503,7 +507,8 @@ public E getLast() { * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(@GuardSatisfied ArrayList this, @NonNegative int index, E element) { Objects.checkIndex(index, size); E oldValue = elementData(index); @@ -516,7 +521,7 @@ public E set(@GuardSatisfied ArrayList this, @NonNegative int index, E elemen * bytecode size under 35 (the -XX:MaxInlineSize default value), * which helps when add(E) is called in a C1-compiled loop. */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") private void add(E e, Object[] elementData, int s) { if (s == elementData.length) elementData = grow(); @@ -530,8 +535,10 @@ private void add(E e, Object[] elementData, int s) { * @param e element to be appended to this list * @return {@code true} (as specified by {@link Collection#add}) */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@GuardSatisfied ArrayList this, E e) { modCount++; add(e, elementData, size); @@ -547,7 +554,8 @@ public boolean add(@GuardSatisfied ArrayList this, E e) { * @param element element to be inserted * @throws IndexOutOfBoundsException {@inheritDoc} */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(@GuardSatisfied ArrayList this, @NonNegative int index, E element) { rangeCheckForAdd(index); modCount++; @@ -567,6 +575,8 @@ public void add(@GuardSatisfied ArrayList this, @NonNegative int index, E ele * * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E element) { add(0, element); } @@ -576,6 +586,8 @@ public void addFirst(E element) { * * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(E element) { add(element); } @@ -589,6 +601,8 @@ public void addLast(E element) { * @return the element that was removed from the list * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(@GuardSatisfied @CanShrink ArrayList this, @NonNegative int index) { Objects.checkIndex(index, size); final Object[] es = elementData; @@ -605,6 +619,8 @@ public E remove(@GuardSatisfied @CanShrink ArrayList this, @NonNegative int i * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeFirst() { if (size == 0) { throw new NoSuchElementException(); @@ -622,6 +638,8 @@ public E removeFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeLast() { int last = size - 1; if (last < 0) { @@ -703,6 +721,7 @@ private void checkForComodification(final int expectedModCount) { /** * {@inheritDoc} */ + @Pure public int hashCode() { int expectedModCount = modCount; int hash = hashCodeRange(0, size); @@ -736,6 +755,8 @@ int hashCodeRange(int from, int to) { * @param o element to be removed from this list, if present * @return {@code true} if this list contained the specified element */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @CanShrink ArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { final Object[] es = elementData; final int size = this.size; @@ -772,6 +793,8 @@ private void fastRemove(Object[] es, int i) { * Removes all of the elements from this list. The list will * be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink ArrayList this) { modCount++; final Object[] es = elementData; @@ -792,7 +815,8 @@ public void clear(@GuardSatisfied @CanShrink ArrayList this) { * @return {@code true} if this list changed as a result of the call * @throws NullPointerException if the specified collection is null */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@GuardSatisfied ArrayList this, Collection c) { Object[] a = c.toArray(); modCount++; @@ -823,7 +847,8 @@ public boolean addAll(@GuardSatisfied ArrayList this, Collection * @throws IndexOutOfBoundsException {@inheritDoc} * @throws NullPointerException if the specified collection is null */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@GuardSatisfied ArrayList this, @NonNegative int index, Collection c) { rangeCheckForAdd(index); @@ -915,6 +940,8 @@ private static String outOfBoundsMsg(int fromIndex, int toIndex) { * or if the specified collection is null * @see Collection#contains(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@CanShrink ArrayList this, Collection c) { return batchRemove(c, false, 0, size); } @@ -935,6 +962,8 @@ public boolean removeAll(@CanShrink ArrayList this, Collection this, Collection c) { return batchRemove(c, true, 0, size); } @@ -1094,7 +1123,8 @@ public boolean hasNext() { } @SuppressWarnings("unchecked") - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty Itr this) { checkForComodification(); int i = cursor; @@ -1107,6 +1137,8 @@ public E next(@NonEmpty Itr this) { return (E) elementData[lastRet = i]; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastRet < 0) throw new IllegalStateException(); @@ -1156,19 +1188,28 @@ private class ListItr extends Itr implements ListIterator { cursor = index; } + @Pure public boolean hasPrevious() { return cursor != 0; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @Pure public int nextIndex() { return cursor; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @Pure public int previousIndex() { return cursor - 1; } @SuppressWarnings("unchecked") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E previous() { checkForComodification(); int i = cursor - 1; @@ -1181,6 +1222,8 @@ public E previous() { return (E) elementData[lastRet = i]; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); @@ -1193,6 +1236,8 @@ public void set(E e) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { checkForComodification(); @@ -1237,6 +1282,9 @@ public void add(E e) { * @throws IndexOutOfBoundsException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @SideEffectFree public @PolyGrowShrink List subList(@GuardSatisfied @PolyGrowShrink ArrayList this, @NonNegative int fromIndex, @NonNegative int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList<>(this, fromIndex, toIndex); @@ -1270,6 +1318,8 @@ private SubList(SubList parent, int fromIndex, int toIndex) { this.modCount = parent.modCount; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(@NonNegative int index, E element) { Objects.checkIndex(index, size); checkForComodification(); @@ -1278,6 +1328,7 @@ public E set(@NonNegative int index, E element) { return oldValue; } + @Pure public E get(@NonNegative int index) { Objects.checkIndex(index, size); checkForComodification(); @@ -1290,6 +1341,8 @@ public E get(@NonNegative int index) { return size; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(@NonNegative int index, E element) { rangeCheckForAdd(index); checkForComodification(); @@ -1297,6 +1350,8 @@ public void add(@NonNegative int index, E element) { updateSizeAndModCount(1); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(@NonNegative int index) { Objects.checkIndex(index, size); checkForComodification(); @@ -1305,16 +1360,22 @@ public E remove(@NonNegative int index) { return result; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") protected void removeRange(int fromIndex, int toIndex) { checkForComodification(); root.removeRange(offset + fromIndex, offset + toIndex); updateSizeAndModCount(fromIndex - toIndex); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { return addAll(this.size, c); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@NonNegative int index, Collection c) { rangeCheckForAdd(index); int cSize = c.size(); @@ -1326,14 +1387,19 @@ public boolean addAll(@NonNegative int index, Collection c) { return true; } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { root.replaceAllRange(operator, offset, offset + size); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return batchRemove(c, false); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { return batchRemove(c, true); } @@ -1348,6 +1414,8 @@ private boolean batchRemove(Collection c, boolean complement) { return modified; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { checkForComodification(); int oldSize = root.size; @@ -1357,6 +1425,7 @@ public boolean removeIf(Predicate filter) { return modified; } + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(SubList<@PolyNull @PolySigned E> this) { checkForComodification(); return Arrays.copyOfRange(root.elementData, offset, offset + size); @@ -1374,6 +1443,7 @@ public boolean removeIf(Predicate filter) { return a; } + @Pure public boolean equals(@Nullable Object o) { if (o == this) { return true; @@ -1388,24 +1458,28 @@ public boolean equals(@Nullable Object o) { return equal; } + @Pure public int hashCode() { int hash = root.hashCodeRange(offset, offset + size); checkForComodification(); return hash; } + @Pure public int indexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { int index = root.indexOfRange(o, offset, offset + size); checkForComodification(); return index >= 0 ? index - offset : -1; } + @Pure public int lastIndexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { int index = root.lastIndexOfRange(o, offset, offset + size); checkForComodification(); return index >= 0 ? index - offset : -1; } + @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@Nullable @UnknownSignedness Object o) { return indexOf(o) >= 0; @@ -1432,7 +1506,7 @@ public boolean hasNext() { } @SuppressWarnings("unchecked") - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public E next(/*@NonEmpty ListIterator this*/) { checkForComodification(); int i = cursor; @@ -1445,6 +1519,7 @@ public E next(/*@NonEmpty ListIterator this*/) { return (E) elementData[offset + (lastRet = i)]; } + @Pure public boolean hasPrevious() { return cursor != 0; } @@ -1479,10 +1554,12 @@ public void forEachRemaining(Consumer action) { } } + @Pure public int nextIndex() { return cursor; } + @Pure public int previousIndex() { return cursor - 1; } @@ -1535,6 +1612,7 @@ final void checkForComodification() { }; } + @SideEffectFree public List subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList<>(this, fromIndex, toIndex); @@ -1645,6 +1723,7 @@ public int characteristics() { * @throws NullPointerException {@inheritDoc} */ @Override + @DoesNotUnrefineReceiver("modifiability") public void forEach(Consumer action) { Objects.requireNonNull(action); final int expectedModCount = modCount; @@ -1798,6 +1877,8 @@ private static boolean isClear(long[] bits, int i) { * @throws NullPointerException {@inheritDoc} */ @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@CanShrink ArrayList this, Predicate filter) { return removeIf(filter, 0, size); } @@ -1841,6 +1922,7 @@ boolean removeIf(@CanShrink ArrayList this, Predicate filter, int @SuppressWarnings({"unchecked"}) @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { replaceAllRange(operator, 0, size); // TODO(8203662): remove increment of modCount from ... @@ -1859,6 +1941,8 @@ private void replaceAllRange(UnaryOperator operator, int i, int end) { @Override @SuppressWarnings("unchecked") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, size, c); diff --git a/src/java.base/share/classes/java/util/Arrays.java b/src/java.base/share/classes/java/util/Arrays.java index e8c55ba81a5..37f0a44ea8a 100644 --- a/src/java.base/share/classes/java/util/Arrays.java +++ b/src/java.base/share/classes/java/util/Arrays.java @@ -44,9 +44,10 @@ import org.checkerframework.common.value.qual.MinLen; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import jdk.internal.util.ArraysSupport; import jdk.internal.vm.annotation.ForceInline; @@ -4401,7 +4402,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty ArrayItr this) { int i = cursor; if (i >= a.length) { diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index 01d2cd4416b..79c8e8a7bc8 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -41,6 +41,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.function.IntFunction; import java.util.function.Predicate; @@ -410,7 +411,6 @@ public interface Collection extends Iterable { * runtime component type} of the specified array * @throws NullPointerException if the specified array is null */ - @SideEffectFree @Nullable T [] toArray(@PolyNull T[] a); /** @@ -488,6 +488,8 @@ default T[] toArray(IntFunction generator) { * time due to insertion restrictions */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean add(@GuardSatisfied Collection this, E e); /** @@ -510,6 +512,8 @@ default T[] toArray(IntFunction generator) { * @throws UnsupportedOperationException if the {@code remove} operation * is not supported by this collection */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean remove(@GuardSatisfied @CanShrink Collection this, @UnknownSignedness Object o); @@ -562,6 +566,8 @@ default T[] toArray(IntFunction generator) { * this time due to insertion restrictions * @see #add(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean addAll(@GuardSatisfied Collection this, Collection c); /** @@ -587,6 +593,8 @@ default T[] toArray(IntFunction generator) { * @see #remove(Object) * @see #contains(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean removeAll(@GuardSatisfied @CanShrink Collection this, Collection c); /** @@ -611,6 +619,8 @@ default T[] toArray(IntFunction generator) { * supported. * @since 1.8 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default boolean removeIf(@CanShrink Collection this, Predicate filter) { Objects.requireNonNull(filter); boolean removed = false; @@ -646,6 +656,8 @@ default boolean removeIf(@CanShrink Collection this, Predicate fil * @see #remove(Object) * @see #contains(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean retainAll(@GuardSatisfied @CanShrink Collection this, Collection c); /** @@ -655,6 +667,8 @@ default boolean removeIf(@CanShrink Collection this, Predicate fil * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this collection */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void clear(@GuardSatisfied @CanShrink Collection this); @@ -785,6 +799,7 @@ default Spliterator spliterator() { * @return a sequential {@code Stream} over the elements in this collection * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default @PolyNonEmpty Stream stream(@PolyNonEmpty Collection this) { return StreamSupport.stream(spliterator(), false); } @@ -806,6 +821,7 @@ default Spliterator spliterator() { * collection * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default Stream parallelStream() { return StreamSupport.stream(spliterator(), true); } diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 7e714b807a9..7b8f53fdffb 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -45,9 +45,10 @@ import org.checkerframework.common.value.qual.StaticallyExecutable; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.IOException; import java.io.ObjectInputStream; @@ -290,6 +291,7 @@ else if (cmp > 0) * Gets the ith element from the given list by repositioning the specified * list listIterator. */ + // @SideEffectsOnly("#1") private static T get(ListIterator i, int index) { T obj; int pos = i.nextIndex(); @@ -1110,7 +1112,6 @@ static class UnmodifiableCollection implements Collection, Serializable { public boolean contains(@UnknownSignedness Object o) {return c.contains(o);} @SideEffectFree public @PolyNull @PolySigned Object[] toArray(Collections.UnmodifiableCollection<@PolyNull @PolySigned E> this) {return c.toArray();} - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) {return c.toArray(a);} public T[] toArray(IntFunction f) {return c.toArray(f);} public String toString() {return c.toString();} @@ -1123,12 +1124,16 @@ static class UnmodifiableCollection implements Collection, Serializable { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean hasNext() {return i.hasNext();} - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(/*@NonEmpty Iterator this*/) {return i.next();} + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public void forEachRemaining(Consumer action) { // Use backing collection version i.forEachRemaining(action); @@ -1136,10 +1141,14 @@ public void forEachRemaining(Consumer action) { }; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresNonEmpty("this") public boolean add(E e) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { throw new UnsupportedOperationException(); } @@ -1148,25 +1157,36 @@ public boolean remove(@UnknownSignedness Object o) { public boolean containsAll(Collection coll) { return c.containsAll(coll); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection coll) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection coll) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection coll) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { throw new UnsupportedOperationException(); } // Override default methods in Collection @Override + @DoesNotUnrefineReceiver("modifiability") public void forEach(Consumer action) { c.forEach(action); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { throw new UnsupportedOperationException(); } @@ -1178,11 +1198,15 @@ public Spliterator spliterator() { } @SuppressWarnings("unchecked") @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Stream stream() { return (Stream)c.stream(); } @SuppressWarnings("unchecked") @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Stream parallelStream() { return (Stream)c.parallelStream(); } @@ -1240,30 +1264,42 @@ private SequencedCollection sc() { // Even though this wrapper class is serializable, the reversed view is effectively // not serializable because it points to the reversed collection view, which usually isn't // serializable. + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public SequencedCollection reversed() { return new UnmodifiableSequencedCollection<>(sc().reversed()); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { throw new UnsupportedOperationException(); } + @Pure public E getFirst() { return sc().getFirst(); } + @Pure public E getLast() { return sc().getLast(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeFirst() { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeLast() { throw new UnsupportedOperationException(); } @@ -1302,7 +1338,9 @@ static class UnmodifiableSet extends UnmodifiableCollection private static final long serialVersionUID = -9215047833775013803L; UnmodifiableSet(Set s) {super(s);} + @Pure public boolean equals(Object o) {return o == this || c.equals(o);} + @Pure public int hashCode() {return c.hashCode();} } @@ -1340,7 +1378,9 @@ static class UnmodifiableSequencedSet extends UnmodifiableSequencedCollection private static final long serialVersionUID = -2153469532349793522L; UnmodifiableSequencedSet(SequencedSet s) {super(s);} + @Pure public boolean equals(Object o) {return o == this || c.equals(o);} + @Pure public int hashCode() {return c.hashCode();} @SuppressWarnings("unchecked") @@ -1351,6 +1391,8 @@ private SequencedSet ss() { // Even though this wrapper class is serializable, the reversed view is effectively // not serializable because it points to the reversed set view, which usually isn't // serializable. + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public SequencedSet reversed() { return new UnmodifiableSequencedSet<>(ss().reversed()); } @@ -1394,14 +1436,21 @@ static class UnmodifiableSortedSet UnmodifiableSortedSet(SortedSet s) {super(s); ss = s;} + @Pure public Comparator comparator() {return ss.comparator();} + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public SortedSet subSet(E fromElement, E toElement) { return new UnmodifiableSortedSet<>(ss.subSet(fromElement,toElement)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public SortedSet headSet(E toElement) { return new UnmodifiableSortedSet<>(ss.headSet(toElement)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public SortedSet tailSet(E fromElement) { return new UnmodifiableSortedSet<>(ss.tailSet(fromElement)); } @@ -1483,23 +1532,37 @@ public EmptyNavigableSet() { public E floor(E e) { return ns.floor(e); } public E ceiling(E e) { return ns.ceiling(e); } public E higher(E e) { return ns.higher(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E pollFirst() { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E pollLast() { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public NavigableSet descendingSet() { return new UnmodifiableNavigableSet<>(ns.descendingSet()); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Iterator descendingIterator() { return descendingSet().iterator(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { return new UnmodifiableNavigableSet<>( ns.subSet(fromElement, fromInclusive, toElement, toInclusive)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public NavigableSet headSet(E toElement, boolean inclusive) { return new UnmodifiableNavigableSet<>( ns.headSet(toElement, inclusive)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public NavigableSet tailSet(E fromElement, boolean inclusive) { return new UnmodifiableNavigableSet<>( ns.tailSet(fromElement, inclusive)); @@ -1549,36 +1612,54 @@ static class UnmodifiableList extends UnmodifiableCollection this.list = list; } + @Pure public boolean equals(Object o) {return o == this || list.equals(o);} + @Pure public int hashCode() {return list.hashCode();} + @Pure public E get(int index) {return list.get(index);} + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(int index, E element) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(int index, E element) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(int index) { throw new UnsupportedOperationException(); } + @Pure public int indexOf(Object o) {return list.indexOf(o);} + @Pure public int lastIndexOf(Object o) {return list.lastIndexOf(o);} + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { throw new UnsupportedOperationException(); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { throw new UnsupportedOperationException(); } public @PolyGrowShrink @PolyNonEmpty ListIterator listIterator(@PolyGrowShrink @PolyNonEmpty UnmodifiableList this) {return listIterator(0);} + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public ListIterator listIterator(final int index) { return new ListIterator<>() { private final ListIterator i @@ -1587,21 +1668,30 @@ public ListIterator listIterator(final int index) { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean hasNext() {return i.hasNext();} - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(/*@NonEmpty ListIterator this*/) {return i.next();} @Pure public boolean hasPrevious() {return i.hasPrevious();} - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public E previous() {return i.previous();} + @Pure public int nextIndex() {return i.nextIndex();} + @Pure public int previousIndex() {return i.previousIndex();} + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { throw new UnsupportedOperationException(); } @@ -1718,18 +1808,27 @@ private static class UnmodifiableMap implements Map, Serializable { public boolean containsKey(@UnknownSignedness Object key) {return m.containsKey(key);} @Pure public boolean containsValue(@UnknownSignedness Object val) {return m.containsValue(val);} + @Pure public V get(Object key) {return m.get(key);} + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresKeyFor(value={"#1"}, map={"this"}) public V put(K key, V value) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V remove(Object key) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putAll(Map m) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { throw new UnsupportedOperationException(); } @@ -1757,7 +1856,9 @@ public Collection values() { return values; } + @Pure public boolean equals(Object o) {return o == this || m.equals(o);} + @Pure public int hashCode() {return m.hashCode();} public String toString() {return m.toString();} @@ -1776,10 +1877,13 @@ public void forEach(BiConsumer action) { } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresKeyFor(value={"#1"}, map={"this"}) @Override public V putIfAbsent(K key, V value) { @@ -1787,38 +1891,48 @@ public V putIfAbsent(K key, V value) { } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object key, @UnknownSignedness Object value) { throw new UnsupportedOperationException(); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { throw new UnsupportedOperationException(); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V replace(K key, V value) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfAbsent(K key, Function mappingFunction) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V compute(K key, BiFunction remappingFunction) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { throw new UnsupportedOperationException(); @@ -1931,10 +2045,13 @@ public Iterator> iterator() { public boolean hasNext() { return i.hasNext(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry next(/*@NonEmpty Iterator> this*/) { return new UnmodifiableEntry<>(i.next()); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { throw new UnsupportedOperationException(); } @@ -1978,6 +2095,7 @@ public Object[] toArray() { * that the equality-candidate is Map.Entry and calls its * setValue method. */ + @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@UnknownSignedness Object o) { if (!(o instanceof Map.Entry)) @@ -1999,6 +2117,7 @@ public boolean containsAll(Collection coll) } return true; } + @Pure public boolean equals(Object o) { if (o == this) return true; @@ -2021,12 +2140,16 @@ private static class UnmodifiableEntry implements Map.Entry { UnmodifiableEntry(Map.Entry e) {this.e = Objects.requireNonNull(e);} + @Pure public K getKey() {return e.getKey();} + @Pure public V getValue() {return e.getValue();} public V setValue(V value) { throw new UnsupportedOperationException(); } + @Pure public int hashCode() {return e.hashCode();} + @Pure public boolean equals(Object o) { if (this == o) return true; @@ -2088,18 +2211,26 @@ public SequencedMap reversed() { return new UnmodifiableSequencedMap<>(sm().reversed()); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Entry pollFirstEntry() { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Entry pollLastEntry() { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putFirst(K k, V v) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putLast(K k, V v) { throw new UnsupportedOperationException(); } @@ -2145,6 +2276,7 @@ static class UnmodifiableSortedMap private final SortedMap sm; UnmodifiableSortedMap(SortedMap m) {super(m); sm = m; } + @Pure public Comparator comparator() { return sm.comparator(); } @SideEffectFree public SortedMap subMap(K fromKey, K toKey) @@ -2288,8 +2420,12 @@ public Entry lastEntry() { : null; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Entry pollFirstEntry() { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Entry pollLastEntry() { throw new UnsupportedOperationException(); } @SideEffectFree @@ -2399,7 +2535,6 @@ public boolean contains(@UnknownSignedness Object o) { public @PolyNull @PolySigned Object[] toArray(Collections.SynchronizedCollection<@PolyNull @PolySigned E> this) { synchronized (mutex) {return c.toArray();} } - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { synchronized (mutex) {return c.toArray(a);} } @@ -2412,10 +2547,14 @@ public Iterator iterator() { return c.iterator(); // Must be manually synched by user! } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresNonEmpty("this") public boolean add(E e) { synchronized (mutex) {return c.add(e);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { synchronized (mutex) {return c.remove(o);} } @@ -2424,15 +2563,23 @@ public boolean remove(@UnknownSignedness Object o) { public boolean containsAll(Collection coll) { synchronized (mutex) {return c.containsAll(coll);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection coll) { synchronized (mutex) {return c.addAll(coll);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection coll) { synchronized (mutex) {return c.removeAll(coll);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection coll) { synchronized (mutex) {return c.retainAll(coll);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { synchronized (mutex) {c.clear();} } @@ -2445,6 +2592,8 @@ public void forEach(Consumer consumer) { synchronized (mutex) {c.forEach(consumer);} } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { synchronized (mutex) {return c.removeIf(filter);} } @@ -2518,11 +2667,13 @@ static class SynchronizedSet super(s, mutex); } + @Pure public boolean equals(Object o) { if (this == o) return true; synchronized (mutex) {return c.equals(o);} } + @Pure public int hashCode() { synchronized (mutex) {return c.hashCode();} } @@ -2593,6 +2744,7 @@ static class SynchronizedSortedSet ss = s; } + @Pure public Comparator comparator() { synchronized (mutex) {return ss.comparator();} } @@ -2693,7 +2845,11 @@ static class SynchronizedNavigableSet public E floor(E e) { synchronized (mutex) {return ns.floor(e);} } public E ceiling(E e) { synchronized (mutex) {return ns.ceiling(e);} } public E higher(E e) { synchronized (mutex) {return ns.higher(e);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E pollFirst() { synchronized (mutex) {return ns.pollFirst();} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E pollLast() { synchronized (mutex) {return ns.pollLast();} } public NavigableSet descendingSet() { @@ -2800,35 +2956,48 @@ static class SynchronizedList this.list = list; } + @Pure public boolean equals(Object o) { if (this == o) return true; synchronized (mutex) {return list.equals(o);} } + @Pure public int hashCode() { synchronized (mutex) {return list.hashCode();} } + @Pure public E get(int index) { synchronized (mutex) {return list.get(index);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(int index, E element) { synchronized (mutex) {return list.set(index, element);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(int index, E element) { synchronized (mutex) {list.add(index, element);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(int index) { synchronized (mutex) {return list.remove(index);} } + @Pure public int indexOf(Object o) { synchronized (mutex) {return list.indexOf(o);} } + @Pure public int lastIndexOf(Object o) { synchronized (mutex) {return list.lastIndexOf(o);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { synchronized (mutex) {return list.addAll(index, c);} } @@ -2849,10 +3018,13 @@ public List subList(int fromIndex, int toIndex) { } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { synchronized (mutex) {list.replaceAll(operator);} } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { synchronized (mutex) {list.sort(c);} } @@ -2989,20 +3161,29 @@ public boolean containsKey(@UnknownSignedness Object key) { public boolean containsValue(@UnknownSignedness Object value) { synchronized (mutex) {return m.containsValue(value);} } + @Pure public V get(Object key) { synchronized (mutex) {return m.get(key);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresKeyFor(value={"#1"}, map={"this"}) public V put(K key, V value) { synchronized (mutex) {return m.put(key, value);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V remove(Object key) { synchronized (mutex) {return m.remove(key);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putAll(Map map) { synchronized (mutex) {m.putAll(map);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { synchronized (mutex) {m.clear();} } @@ -3036,11 +3217,13 @@ public Collection values() { } } + @Pure public boolean equals(Object o) { if (this == o) return true; synchronized (mutex) {return m.equals(o);} } + @Pure public int hashCode() { synchronized (mutex) {return m.hashCode();} } @@ -3059,42 +3242,55 @@ public void forEach(BiConsumer action) { synchronized (mutex) {m.forEach(action);} } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { synchronized (mutex) {m.replaceAll(function);} } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresKeyFor(value={"#1"}, map={"this"}) @Override public V putIfAbsent(K key, V value) { synchronized (mutex) {return m.putIfAbsent(key, value);} } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object key, @UnknownSignedness Object value) { synchronized (mutex) {return m.remove(key, value);} } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { synchronized (mutex) {return m.replace(key, oldValue, newValue);} } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V replace(K key, V value) { synchronized (mutex) {return m.replace(key, value);} } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfAbsent(K key, Function mappingFunction) { synchronized (mutex) {return m.computeIfAbsent(key, mappingFunction);} } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { synchronized (mutex) {return m.computeIfPresent(key, remappingFunction);} } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V compute(K key, BiFunction remappingFunction) { synchronized (mutex) {return m.compute(key, remappingFunction);} } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { synchronized (mutex) {return m.merge(key, value, remappingFunction);} @@ -3177,6 +3373,7 @@ static class SynchronizedSortedMap sm = m; } + @Pure public Comparator comparator() { synchronized (mutex) {return sm.comparator();} } @@ -3304,8 +3501,12 @@ public Entry firstEntry() { synchronized (mutex) { return nm.firstEntry(); } } public Entry lastEntry() { synchronized (mutex) { return nm.lastEntry(); } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Entry pollFirstEntry() { synchronized (mutex) { return nm.pollFirstEntry(); } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Entry pollLastEntry() { synchronized (mutex) { return nm.pollLastEntry(); } } @@ -3493,20 +3694,27 @@ private String badElementMsg(Object o) { public boolean contains(@UnknownSignedness Object o) { return c.contains(o); } @SideEffectFree public @PolyNull @PolySigned Object[] toArray(Collections.CheckedCollection<@PolyNull @PolySigned E> this) { return c.toArray(); } - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { return c.toArray(a); } public T[] toArray(IntFunction f) { return c.toArray(f); } public String toString() { return c.toString(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { return c.remove(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { c.clear(); } @Pure public boolean containsAll(Collection coll) { return c.containsAll(coll); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection coll) { return c.removeAll(coll); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection coll) { return c.retainAll(coll); } @@ -3520,8 +3728,11 @@ public Iterator iterator() { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean hasNext() { return it.hasNext(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(/*@NonEmpty Iterator this*/) { return it.next(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { it.remove(); } public void forEachRemaining(Consumer action) { it.forEachRemaining(action); @@ -3529,6 +3740,8 @@ public void forEachRemaining(Consumer action) { }; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresNonEmpty("this") public boolean add(E e) { return c.add(typeCheck(e)); } @@ -3563,6 +3776,8 @@ Collection checkedCopyOf(Collection coll) { return (Collection) Arrays.asList(a); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection coll) { // Doing things this way insulates us from concurrent changes // in the contents of coll and provides all-or-nothing @@ -3575,6 +3790,8 @@ public boolean addAll(Collection coll) { @Override public void forEach(Consumer action) {c.forEach(action);} @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { return c.removeIf(filter); } @@ -3635,6 +3852,7 @@ static class CheckedQueue this.queue = queue; } + @Pure public E element() {return queue.element();} @Pure public boolean equals(Object o) {return o == this || c.equals(o);} @@ -3642,8 +3860,14 @@ static class CheckedQueue public int hashCode() {return c.hashCode();} @Pure public E peek() {return queue.peek();} + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E poll() {return queue.poll();} + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove() {return queue.remove();} + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) {return queue.offer(typeCheck(e));} } @@ -3689,7 +3913,9 @@ static class CheckedSet extends CheckedCollection CheckedSet(Set s, Class elementType) { super(s, elementType); } + @Pure public boolean equals(Object o) { return o == this || c.equals(o); } + @Pure public int hashCode() { return c.hashCode(); } } @@ -3743,6 +3969,7 @@ static class CheckedSortedSet extends CheckedSet ss = s; } + @Pure public Comparator comparator() { return ss.comparator(); } public E first() { return ss.first(); } public E last() { return ss.last(); } @@ -3892,21 +4119,34 @@ static class CheckedList this.list = list; } + @Pure public boolean equals(Object o) { return o == this || list.equals(o); } + @Pure public int hashCode() { return list.hashCode(); } + @Pure public E get(int index) { return list.get(index); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(int index) { return list.remove(index); } + @Pure public int indexOf(Object o) { return list.indexOf(o); } + @Pure public int lastIndexOf(Object o) { return list.lastIndexOf(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(int index, E element) { return list.set(index, typeCheck(element)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(int index, E element) { list.add(index, typeCheck(element)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { return list.addAll(index, checkedCopyOf(c)); } @@ -3919,18 +4159,28 @@ public ListIterator listIterator(final int index) { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean hasNext() { return i.hasNext(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(/*@NonEmpty ListIterator this*/) { return i.next(); } + @Pure public boolean hasPrevious() { return i.hasPrevious(); } public E previous() { return i.previous(); } + @Pure public int nextIndex() { return i.nextIndex(); } + @Pure public int previousIndex() { return i.previousIndex(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { i.remove(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { i.set(typeCheck(e)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { i.add(typeCheck(e)); } @@ -3955,12 +4205,15 @@ public List subList(int fromIndex, int toIndex) { * already been replaced. */ @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { Objects.requireNonNull(operator); list.replaceAll(e -> typeCheck(operator.apply(e))); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { list.sort(c); } @@ -4088,21 +4341,32 @@ private String badValueMsg(Object value) { public boolean containsKey(@UnknownSignedness Object key) { return m.containsKey(key); } @Pure public boolean containsValue(@UnknownSignedness Object v) { return m.containsValue(v); } + @Pure public V get(Object key) { return m.get(key); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V remove(Object key) { return m.remove(key); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } public Set keySet() { return m.keySet(); } public Collection values() { return m.values(); } + @Pure public boolean equals(Object o) { return o == this || m.equals(o); } + @Pure public int hashCode() { return m.hashCode(); } public String toString() { return m.toString(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresKeyFor(value={"#1"}, map={"this"}) public V put(K key, V value) { typeCheck(key, value); return m.put(key, value); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @SuppressWarnings("unchecked") public void putAll(Map t) { // Satisfy the following goals: @@ -4140,10 +4404,13 @@ public void forEach(BiConsumer action) { } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { m.replaceAll(typeCheck(function)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresKeyFor(value={"#1"}, map={"this"}) @Override public V putIfAbsent(K key, V value) { @@ -4152,23 +4419,30 @@ public V putIfAbsent(K key, V value) { } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object key, @UnknownSignedness Object value) { return m.remove(key, value); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { typeCheck(key, newValue); return m.replace(key, oldValue, newValue); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V replace(K key, V value) { typeCheck(key, value); return m.replace(key, value); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfAbsent(K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); @@ -4180,6 +4454,7 @@ public V replace(K key, V value) { } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { return m.computeIfPresent(key, typeCheck(remappingFunction)); @@ -4192,6 +4467,7 @@ public V replace(K key, V value) { } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -4224,14 +4500,22 @@ static class CheckedEntrySet implements Set> { @Pure @EnsuresNonEmptyIf(result = false, expression = "this") public boolean isEmpty() { return s.isEmpty(); } + @SideEffectFree public String toString() { return s.toString(); } + @Pure public int hashCode() { return s.hashCode(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { s.clear(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresNonEmpty("this") public boolean add(Map.Entry e) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection> coll) { throw new UnsupportedOperationException(); } @@ -4243,9 +4527,12 @@ public Iterator> iterator() { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean hasNext() { return i.hasNext(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { i.remove(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry next(/*@NonEmpty Iterator> this*/) { return checkedEntry(i.next(), valueType); } @@ -4321,6 +4608,8 @@ public boolean containsAll(Collection c) { return true; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { if (!(o instanceof Map.Entry)) return false; @@ -4328,9 +4617,13 @@ public boolean remove(@UnknownSignedness Object o) { <>((Map.Entry)o)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return batchRemove(c, false); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { return batchRemove(c, true); } @@ -4347,6 +4640,7 @@ private boolean batchRemove(Collection c, boolean complement) { return modified; } + @Pure public boolean equals(Object o) { if (o == this) return true; @@ -4376,8 +4670,11 @@ private static class CheckedEntry implements Map.Entry { this.valueType = Objects.requireNonNull(valueType); } + @Pure public K getKey() { return e.getKey(); } + @Pure public V getValue() { return e.getValue(); } + @Pure public int hashCode() { return e.hashCode(); } public String toString() { return e.toString(); } @@ -4392,6 +4689,7 @@ private String badValueMsg(Object value) { " value into map with value type " + valueType; } + @Pure public boolean equals(Object o) { if (o == this) return true; @@ -4464,6 +4762,7 @@ static class CheckedSortedMap extends CheckedMap sm = m; } + @Pure public Comparator comparator() { return sm.comparator(); } public K firstKey() { return sm.firstKey(); } public K lastKey() { return sm.lastKey(); } @@ -4543,6 +4842,7 @@ static class CheckedNavigableMap extends CheckedSortedMap nm = m; } + @Pure public Comparator comparator() { return nm.comparator(); } public K firstKey() { return nm.firstKey(); } public K lastKey() { return nm.lastKey(); } @@ -4597,6 +4897,8 @@ public Entry lastEntry() { : null; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Entry pollFirstEntry() { Entry entry = nm.pollFirstEntry(); return (null == entry) @@ -4604,6 +4906,8 @@ public Entry pollFirstEntry() { : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Entry pollLastEntry() { Entry entry = nm.pollLastEntry(); return (null == entry) @@ -4699,8 +5003,11 @@ private static class EmptyIterator implements Iterator { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean hasNext() { return false; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty EmptyIterator this) { throw new NoSuchElementException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove(@NonEmpty EmptyIterator this) { throw new IllegalStateException(); } @Override public void forEachRemaining(Consumer action) { @@ -4747,11 +5054,18 @@ private static class EmptyListIterator static final EmptyListIterator EMPTY_ITERATOR = new EmptyListIterator<>(); + @Pure public boolean hasPrevious() { return false; } public E previous() { throw new NoSuchElementException(); } + @Pure public int nextIndex() { return 0; } + @Pure public int previousIndex() { return -1; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { throw new IllegalStateException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { throw new UnsupportedOperationException(); } } @@ -4782,6 +5096,7 @@ private static class EmptyEnumeration implements Enumeration { static final EmptyEnumeration EMPTY_ENUMERATION = new EmptyEnumeration<>(); + @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean hasMoreElements() { return false; } public E nextElement(@NonEmpty EmptyEnumeration this) { throw new NoSuchElementException(); } @@ -4850,7 +5165,6 @@ public void clear() {} @SideEffectFree public @PolyNull @PolySigned Object[] toArray(Collections.EmptySet<@PolyNull @PolySigned E> this) { return new Object[0]; } - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { if (a.length > 0) a[0] = null; @@ -4878,6 +5192,7 @@ private Object readResolve() { } @Override + @Pure public int hashCode() { return 0; } @@ -4994,21 +5309,23 @@ public void clear() {} @SideEffectFree public @PolyNull @PolySigned Object[] toArray(Collections.EmptyList<@PolyNull @PolySigned E> this) { return new Object[0]; } - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { if (a.length > 0) a[0] = null; return a; } + @Pure public E get(int index) { throw new IndexOutOfBoundsException("Index: "+index); } + @Pure public boolean equals(Object o) { return (o instanceof List) && ((List)o).isEmpty(); } + @Pure public int hashCode() { return 1; } @Override @@ -5139,16 +5456,19 @@ public void clear() {} public boolean containsKey(@UnknownSignedness Object key) {return false;} @Pure public boolean containsValue(@UnknownSignedness Object value) {return false;} + @Pure public V get(Object key) {return null;} public Set keySet() {return emptySet();} public Collection values() {return emptySet();} @SideEffectFree public Set> entrySet() {return emptySet();} + @Pure public boolean equals(Object o) { return (o instanceof Map) && ((Map)o).isEmpty(); } + @Pure public int hashCode() {return 0;} // Override default methods in Map @@ -5168,6 +5488,8 @@ public void replaceAll(BiFunction function) { Objects.requireNonNull(function); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresKeyFor(value={"#1"}, map={"this"}) @Override public V putIfAbsent(K key, V value) { @@ -5175,39 +5497,49 @@ public V putIfAbsent(K key, V value) { } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object key, @UnknownSignedness Object value) { throw new UnsupportedOperationException(); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { throw new UnsupportedOperationException(); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V replace(K key, V value) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfAbsent(K key, Function mappingFunction) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V compute(K key, BiFunction remappingFunction) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { throw new UnsupportedOperationException(); @@ -5242,7 +5574,8 @@ static Iterator singletonIterator(final E e) { public boolean hasNext() { return hasNext; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(/*@NonEmpty Iterator this*/) { if (hasNext) { hasNext = false; @@ -5250,6 +5583,8 @@ public E next(/*@NonEmpty Iterator this*/) { } throw new NoSuchElementException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { throw new UnsupportedOperationException(); } @@ -5348,10 +5683,13 @@ public Spliterator spliterator() { return singletonSpliterator(element); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { throw new UnsupportedOperationException(); } @Override + @Pure public int hashCode() { return Objects.hashCode(element); } @@ -5399,6 +5737,7 @@ public Iterator iterator() { @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@UnknownSignedness Object obj) {return eq(obj, element);} + @Pure public E get(int index) { if (index != 0) throw new IndexOutOfBoundsException("Index: "+index+", Size: 1"); @@ -5411,10 +5750,13 @@ public void forEach(Consumer action) { action.accept(element); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { throw new UnsupportedOperationException(); } @@ -5427,6 +5769,7 @@ public Spliterator spliterator() { return singletonSpliterator(element); } @Override + @Pure public int hashCode() { return 31 + Objects.hashCode(element); } @@ -5477,6 +5820,7 @@ private static class SingletonMap public boolean containsKey(@UnknownSignedness Object key) {return eq(key, k);} @Pure public boolean containsValue(@UnknownSignedness Object value) {return eq(value, v);} + @Pure public V get(Object key) {return (eq(key, k) ? v : null);} private transient Set keySet; @@ -5516,10 +5860,13 @@ public void forEach(BiConsumer action) { } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresKeyFor(value={"#1"}, map={"this"}) @Override public V putIfAbsent(K key, V value) { @@ -5527,45 +5874,56 @@ public V putIfAbsent(K key, V value) { } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object key, @UnknownSignedness Object value) { throw new UnsupportedOperationException(); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { throw new UnsupportedOperationException(); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V replace(K key, V value) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfAbsent(K key, Function mappingFunction) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V compute(K key, BiFunction remappingFunction) { throw new UnsupportedOperationException(); } @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { throw new UnsupportedOperationException(); } @Override + @Pure public int hashCode() { return Objects.hashCode(k) ^ Objects.hashCode(v); } @@ -5627,14 +5985,17 @@ public boolean contains(@UnknownSignedness Object obj) { return n != 0 && eq(obj, element); } + @Pure public int indexOf(Object o) { return contains(o) ? 0 : -1; } + @Pure public int lastIndexOf(Object o) { return contains(o) ? n - 1 : -1; } + @Pure public E get(int index) { Objects.checkIndex(index, n); return element; @@ -5687,6 +6048,7 @@ public List subList(int fromIndex, int toIndex) { } @Override + @Pure public int hashCode() { if (n == 0) return 1; // hashCode of n repeating elements is 31^n + elementHash * Sum(31^k, k = 0..n-1) @@ -5706,6 +6068,7 @@ public int hashCode() { } @Override + @Pure public boolean equals(Object o) { if (o == this) return true; @@ -5882,12 +6245,14 @@ public int compare(T t1, T t2) { return cmp.compare(t2, t1); } + @Pure public boolean equals(Object o) { return (o == this) || (o instanceof ReverseComparator2 that && cmp.equals(that.cmp)); } + @Pure public int hashCode() { return cmp.hashCode() ^ Integer.MIN_VALUE; } @@ -5917,6 +6282,7 @@ public static Enumeration enumeration(final Collection c) { return new Enumeration<>() { private final Iterator i = c.iterator(); + @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean hasMoreElements() { return i.hasNext(); @@ -6180,10 +6546,11 @@ private static class SetFromMap extends AbstractSet public Iterator iterator() { return s.iterator(); } @SideEffectFree public @PolyNull @PolySigned Object[] toArray(Collections.SetFromMap<@PolyNull @PolySigned E> this) { return s.toArray(); } - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { return s.toArray(a); } public String toString() { return s.toString(); } + @Pure public int hashCode() { return s.hashCode(); } + @Pure public boolean equals(Object o) { return o == this || s.equals(o); } @Pure public boolean containsAll(Collection c) {return s.containsAll(c);} @@ -6297,7 +6664,9 @@ private SequencedMap map() { public void addFirst(E e) { map().putFirst(e, Boolean.TRUE); } public void addLast(E e) { map().putLast(e, Boolean.TRUE); } + @Pure public E getFirst() { return nsee(map().firstEntry()); } + @Pure public E getLast() { return nsee(map().lastEntry()); } public E removeFirst() { return nsee(map().pollFirstEntry()); } public E removeLast() { return nsee(map().pollLastEntry()); } @@ -6350,6 +6719,7 @@ static class AsLIFOQueue extends AbstractQueue public E remove() { return q.removeFirst(); } @Pure public E peek() { return q.peekFirst(); } + @Pure public E element() { return q.getFirst(); } public void clear() { q.clear(); } @Pure @@ -6365,7 +6735,6 @@ static class AsLIFOQueue extends AbstractQueue public Iterator iterator() { return q.iterator(); } @SideEffectFree public @PolyNull @PolySigned Object[] toArray(Collections.AsLIFOQueue<@PolyNull @PolySigned E> this) { return q.toArray(); } - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { return q.toArray(a); } public T[] toArray(IntFunction f) { return q.toArray(f); } public String toString() { return q.toString(); } diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index 342f7b9cd63..bed7ffd180a 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -49,6 +49,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * A linear collection that supports element insertion and removal at @@ -237,6 +238,8 @@ public interface Deque extends Queue, SequencedCollection { * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void addFirst(@GuardSatisfied Deque this, E e); /** @@ -259,6 +262,8 @@ public interface Deque extends Queue, SequencedCollection { * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void addLast(@GuardSatisfied Deque this, E e); /** @@ -277,6 +282,8 @@ public interface Deque extends Queue, SequencedCollection { * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offerFirst(E e); /** @@ -295,6 +302,8 @@ public interface Deque extends Queue, SequencedCollection { * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offerLast(E e); /** @@ -305,6 +314,8 @@ public interface Deque extends Queue, SequencedCollection { * @return the head of this deque * @throws NoSuchElementException if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E removeFirst(@GuardSatisfied @NonEmpty @CanShrink Deque this); /** @@ -315,6 +326,8 @@ public interface Deque extends Queue, SequencedCollection { * @return the tail of this deque * @throws NoSuchElementException if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E removeLast(@GuardSatisfied @NonEmpty @CanShrink Deque this); /** @@ -323,6 +336,8 @@ public interface Deque extends Queue, SequencedCollection { * * @return the head of this deque, or {@code null} if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable E pollFirst(@GuardSatisfied @CanShrink Deque this); /** @@ -331,6 +346,8 @@ public interface Deque extends Queue, SequencedCollection { * * @return the tail of this deque, or {@code null} if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable E pollLast(@GuardSatisfied @CanShrink Deque this); /** @@ -342,6 +359,7 @@ public interface Deque extends Queue, SequencedCollection { * @return the head of this deque * @throws NoSuchElementException if this deque is empty */ + @Pure @EnsuresNonEmpty("this") E getFirst(@GuardSatisfied @NonEmpty @CanShrink Deque this); @@ -353,6 +371,7 @@ public interface Deque extends Queue, SequencedCollection { * @return the tail of this deque * @throws NoSuchElementException if this deque is empty */ + @Pure @EnsuresNonEmpty("this") E getLast(@GuardSatisfied @NonEmpty @CanShrink Deque this); @@ -362,6 +381,9 @@ public interface Deque extends Queue, SequencedCollection { * * @return the head of this deque, or {@code null} if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @Pure @Nullable E peekFirst(); /** @@ -370,6 +392,9 @@ public interface Deque extends Queue, SequencedCollection { * * @return the tail of this deque, or {@code null} if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @Pure @Nullable E peekLast(); /** @@ -389,6 +414,8 @@ public interface Deque extends Queue, SequencedCollection { * deque does not permit null elements * ({@linkplain Collection##optional-restrictions optional}) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean removeFirstOccurrence(@GuardSatisfied @CanShrink Deque this, Object o); /** @@ -408,6 +435,8 @@ public interface Deque extends Queue, SequencedCollection { * deque does not permit null elements * ({@linkplain Collection##optional-restrictions optional}) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean removeLastOccurrence(@GuardSatisfied @CanShrink Deque this, Object o); // *** Queue methods *** @@ -435,6 +464,8 @@ public interface Deque extends Queue, SequencedCollection { * element prevents it from being added to this deque */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean add(@GuardSatisfied Deque this, E e); /** @@ -458,6 +489,8 @@ public interface Deque extends Queue, SequencedCollection { * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offer(E e); /** @@ -471,6 +504,8 @@ public interface Deque extends Queue, SequencedCollection { * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E remove(@GuardSatisfied @NonEmpty @CanShrink Deque this); /** @@ -483,6 +518,8 @@ public interface Deque extends Queue, SequencedCollection { * @return the first element of this deque, or {@code null} if * this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable E poll(@GuardSatisfied @CanShrink Deque this); /** @@ -496,6 +533,9 @@ public interface Deque extends Queue, SequencedCollection { * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @Pure E element(@GuardSatisfied @NonEmpty Deque this); /** @@ -508,6 +548,9 @@ public interface Deque extends Queue, SequencedCollection { * @return the head of the queue represented by this deque, or * {@code null} if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @Pure @Nullable E peek(); /** @@ -534,6 +577,8 @@ public interface Deque extends Queue, SequencedCollection { * @throws IllegalArgumentException if some property of an element of the * specified collection prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean addAll(Collection c); // *** Stack methods *** @@ -556,6 +601,8 @@ public interface Deque extends Queue, SequencedCollection { * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void push(@GuardSatisfied Deque this, E e); /** @@ -568,6 +615,8 @@ public interface Deque extends Queue, SequencedCollection { * of the stack represented by this deque) * @throws NoSuchElementException if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E pop(@GuardSatisfied @NonEmpty @CanShrink Deque this); @@ -592,6 +641,8 @@ public interface Deque extends Queue, SequencedCollection { * deque does not permit null elements * ({@linkplain Collection##optional-restrictions optional}) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean remove(@GuardSatisfied @CanShrink Deque this, @UnknownSignedness Object o); /** @@ -637,6 +688,8 @@ public interface Deque extends Queue, SequencedCollection { * @return an iterator over the elements in this deque in reverse * sequence */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") Iterator descendingIterator(); /** @@ -655,6 +708,8 @@ public interface Deque extends Queue, SequencedCollection { * @return a reverse-ordered view of this collection, as a {@code Deque} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default Deque reversed() { return ReverseOrderDequeView.of(this); } diff --git a/src/java.base/share/classes/java/util/EnumMap.java b/src/java.base/share/classes/java/util/EnumMap.java index 880386c3749..3ea7ee73194 100644 --- a/src/java.base/share/classes/java/util/EnumMap.java +++ b/src/java.base/share/classes/java/util/EnumMap.java @@ -41,6 +41,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import jdk.internal.access.SharedSecrets; @@ -127,10 +128,12 @@ public class EnumMap, V> extends AbstractMap * Distinguished non-null value for representing null values. */ private static final Object NULL = new Object() { + @Pure public int hashCode() { return 0; } + @SideEffectFree public String toString() { return "java.util.EnumMap.NULL"; } @@ -238,8 +241,8 @@ public boolean containsValue(@GuardSatisfied @Nullable @UnknownSignedness Object * @return {@code true} if this map contains a mapping for the specified * key */ - @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) @Pure + @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) public boolean containsKey(@GuardSatisfied @UnknownSignedness Object key) { return isValidKey(key) && vals[((Enum)key).ordinal()] != null; } @@ -264,6 +267,7 @@ private boolean containsMapping(@GuardSatisfied @UnknownSignedness Object key, @ * The {@link #containsKey containsKey} operation may be used to * distinguish these two cases. */ + @Pure public @Nullable V get(@UnknownSignedness @Nullable Object key) { return (isValidKey(key) ? unmaskNull(vals[((Enum)key).ordinal()]) : null); @@ -286,6 +290,8 @@ private boolean containsMapping(@GuardSatisfied @UnknownSignedness Object key, @ * @throws NullPointerException if the specified key is null */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(K key, V value) { typeCheck(key); @@ -306,6 +312,8 @@ private boolean containsMapping(@GuardSatisfied @UnknownSignedness Object key, @ * return can also indicate that the map previously associated * {@code null} with the specified key.) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V remove(@GuardSatisfied @UnknownSignedness Object key) { if (!isValidKey(key)) return null; @@ -358,6 +366,8 @@ private boolean isValidKey(@GuardSatisfied @UnknownSignedness Object key) { "and vals are private class members for EnumMap and are absent in AbstractMap."}) @SuppressWarnings({"nullness:contracts.precondition.override.invalid"}) @RequiresNonNull({"keyUniverse", "vals"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putAll(@UnknownInitialization EnumMap this, Map m) { if (m instanceof EnumMap em) { if (em.keyType != keyType) { @@ -382,6 +392,8 @@ public void putAll(@UnknownInitialization EnumMap this, Map keySet() { Set ks = keySet; if (ks == null) { @@ -428,11 +441,15 @@ public Iterator iterator() { public boolean contains(@Nullable @UnknownSignedness Object o) { return containsKey(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { int oldSize = size; EnumMap.this.remove(o); return size != oldSize; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { EnumMap.this.clear(); } @@ -448,6 +465,7 @@ public void clear() { * * @return a collection view of the values contained in this map */ + @SideEffectFree public Collection values() { Collection vs = values; if (vs == null) { @@ -471,6 +489,8 @@ public Iterator iterator() { public boolean contains(@Nullable @UnknownSignedness Object o) { return containsValue(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { o = maskNull(o); @@ -483,6 +503,8 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { } return false; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { EnumMap.this.clear(); } @@ -518,6 +540,8 @@ public boolean contains(@Nullable @UnknownSignedness Object o) { return o instanceof Map.Entry entry && containsMapping(entry.getKey(), entry.getValue()); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { return o instanceof Map.Entry entry && removeMapping(entry.getKey(), entry.getValue()); @@ -526,6 +550,8 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { public @NonNegative int size() { return size; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { EnumMap.this.clear(); } @@ -578,6 +604,8 @@ public boolean hasNext() { return index != vals.length; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { checkLastReturnedIndex(); @@ -595,6 +623,8 @@ private void checkLastReturnedIndex() { } private class KeyIterator extends EnumMapIterator { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K next(@NonEmpty KeyIterator this) { if (!hasNext()) throw new NoSuchElementException(); @@ -607,6 +637,8 @@ private class ValueIterator extends EnumMapIterator { @CFComment({"nullness: Value returned by unmaskNull", "will be of type V (not @Nullable V) for mapped value"}) @SuppressWarnings({"nullness:return"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V next(@NonEmpty ValueIterator this) { if (!hasNext()) throw new NoSuchElementException(); @@ -618,6 +650,8 @@ public V next(@NonEmpty ValueIterator this) { private class EntryIterator extends EnumMapIterator> { private Entry lastReturnedEntry; + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry next(@NonEmpty EntryIterator this) { if (!hasNext()) throw new NoSuchElementException(); @@ -625,6 +659,8 @@ public Map.Entry next(@NonEmpty EntryIterator this) { return lastReturnedEntry; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { lastReturnedIndex = ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index); @@ -640,6 +676,7 @@ private Entry(int index) { this.index = index; } + @Pure public K getKey() { checkIndexForEntryUse(); return keyUniverse[index]; @@ -648,6 +685,7 @@ public K getKey() { @CFComment({"nullness: Value returned by unmaskNull", "will be of type V (not @Nullable V) for mapped value"}) @SuppressWarnings("nullness:return") + @Pure public V getValue() { checkIndexForEntryUse(); return unmaskNull(vals[index]); @@ -663,6 +701,7 @@ public V setValue(V value) { return oldValue; } + @Pure public boolean equals(Object o) { if (index < 0) return o == this; @@ -677,6 +716,7 @@ public boolean equals(Object o) { (ourValue != null && ourValue.equals(hisValue)))); } + @Pure public int hashCode() { if (index < 0) return super.hashCode(); @@ -684,6 +724,7 @@ public int hashCode() { return entryHashCode(index); } + @SideEffectFree public String toString() { if (index < 0) return super.toString(); @@ -710,6 +751,7 @@ private void checkIndexForEntryUse() { * @param o the object to be compared for equality with this map * @return {@code true} if the specified object is equal to this map */ + @Pure public boolean equals(@Nullable Object o) { if (this == o) return true; @@ -738,6 +780,7 @@ public boolean equals(@Nullable Object o) { return true; } + @Pure private boolean equals(EnumMap em) { if (em.size != size) return false; @@ -760,6 +803,7 @@ private boolean equals(EnumMap em) { * Returns the hash code value for this map. The hash code of a map is * defined to be the sum of the hash codes of each entry in the map. */ + @Pure public int hashCode() { int h = 0; @@ -785,6 +829,7 @@ private int entryHashCode(int index) { * @return a shallow copy of this enum map */ @SuppressWarnings("unchecked") + @SideEffectFree public EnumMap clone() { EnumMap result = null; try { diff --git a/src/java.base/share/classes/java/util/EnumSet.java b/src/java.base/share/classes/java/util/EnumSet.java index 9a64d87cbe7..c85dc5fe670 100644 --- a/src/java.base/share/classes/java/util/EnumSet.java +++ b/src/java.base/share/classes/java/util/EnumSet.java @@ -26,7 +26,9 @@ package java.util; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import jdk.internal.access.SharedSecrets; @@ -144,6 +146,8 @@ public static > EnumSet allOf(Class elementType) { * Adds all of the elements from the appropriate enum type to this enum * set, which is empty prior to the call. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") abstract void addAll(); /** @@ -155,6 +159,7 @@ public static > EnumSet allOf(Class elementType) { * @return A copy of the specified enum set. * @throws NullPointerException if {@code s} is null */ + @SideEffectFree public static > EnumSet copyOf(EnumSet s) { return s.clone(); } @@ -173,6 +178,7 @@ public static > EnumSet copyOf(EnumSet s) { * {@code EnumSet} instance and contains no elements * @throws NullPointerException if {@code c} is null */ + @SideEffectFree public static > EnumSet copyOf(Collection c) { if (c instanceof EnumSet) { return ((EnumSet)c).clone(); @@ -218,6 +224,7 @@ public static > EnumSet complementOf(EnumSet s) { * @throws NullPointerException if {@code e} is null * @return an enum set initially containing the specified element */ + @SideEffectFree public static > EnumSet of(E e) { EnumSet result = noneOf(e.getDeclaringClass()); result.add(e); @@ -239,6 +246,7 @@ public static > EnumSet of(E e) { * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ + @SideEffectFree public static > EnumSet of(E e1, E e2) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); @@ -262,6 +270,7 @@ public static > EnumSet of(E e1, E e2) { * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ + @SideEffectFree public static > EnumSet of(E e1, E e2, E e3) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); @@ -287,6 +296,7 @@ public static > EnumSet of(E e1, E e2, E e3) { * @throws NullPointerException if any parameters are null * @return an enum set initially containing the specified elements */ + @SideEffectFree public static > EnumSet of(E e1, E e2, E e3, E e4) { EnumSet result = noneOf(e1.getDeclaringClass()); result.add(e1); @@ -341,6 +351,7 @@ public static > EnumSet of(E e1, E e2, E e3, E e4, * @return an enum set initially containing the specified elements */ @SafeVarargs + @SideEffectFree public static > EnumSet of(E first, E... rest) { EnumSet result = noneOf(first.getDeclaringClass()); result.add(first); @@ -375,6 +386,8 @@ public static > EnumSet range(E from, E to) { * Adds the specified range to this enum set, which is empty prior * to the call. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") abstract void addRange(E from, E to); /** @@ -383,6 +396,9 @@ public static > EnumSet range(E from, E to) { * @return a copy of this set */ @SuppressWarnings("unchecked") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @SideEffectFree public EnumSet clone() { try { return (EnumSet) super.clone(); @@ -394,6 +410,8 @@ public EnumSet clone() { /** * Complements the contents of this enum set. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") abstract void complement(); /** diff --git a/src/java.base/share/classes/java/util/Enumeration.java b/src/java.base/share/classes/java/util/Enumeration.java index 5a51f493177..3ae284e8d52 100644 --- a/src/java.base/share/classes/java/util/Enumeration.java +++ b/src/java.base/share/classes/java/util/Enumeration.java @@ -29,8 +29,9 @@ import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * An object that implements the Enumeration interface generates a @@ -133,7 +134,8 @@ default Iterator asIterator() { @Override public boolean hasNext() { return hasMoreElements(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Override public E next(/*@NonEmpty Iterator this*/) { return nextElement(); } diff --git a/src/java.base/share/classes/java/util/HashMap.java b/src/java.base/share/classes/java/util/HashMap.java index 36f9d1e33bb..5ea19f87393 100644 --- a/src/java.base/share/classes/java/util/HashMap.java +++ b/src/java.base/share/classes/java/util/HashMap.java @@ -39,9 +39,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.IOException; import java.io.InvalidObjectException; @@ -310,20 +311,27 @@ static class Node implements Map.Entry { this.next = next; } + @Pure public final K getKey() { return key; } + @Pure public final V getValue() { return value; } + @SideEffectFree public final String toString() { return key + "=" + value; } + @Pure public final int hashCode() { return Objects.hashCode(key) ^ Objects.hashCode(value); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final V setValue(V newValue) { V oldValue = value; value = newValue; return oldValue; } + @Pure public final boolean equals(Object o) { if (o == this) return true; @@ -621,8 +629,8 @@ final Node getNode(@Nullable Object key) { * @return {@code true} if this map contains a mapping for the specified * key. */ - @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) @Pure + @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) public boolean containsKey(@GuardSatisfied HashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { return getNode(key) != null; } @@ -640,6 +648,8 @@ public boolean containsKey(@GuardSatisfied HashMap this, @GuardSatisfied @ * previously associated {@code null} with {@code key}.) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(@GuardSatisfied HashMap this, K key, V value) { return putVal(hash(key), key, value, false, true); } @@ -814,6 +824,8 @@ else if ((e = tab[index = (n - 1) & hash]) != null) { * @param m mappings to be stored in this map * @throws NullPointerException if the specified map is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putAll(@GuardSatisfied HashMap this, Map m) { putMapEntries(m, true); } @@ -827,6 +839,8 @@ public void putAll(@GuardSatisfied HashMap this, Map this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Node e; return (e = removeNode(hash(key), key, null, false, true)) == null ? @@ -888,6 +902,8 @@ else if (node == p) * Removes all of the mappings from this map. * The map will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied HashMap this) { Node[] tab; modCount++; @@ -1017,12 +1033,16 @@ T[] valuesToArray(T[] a) { final class KeySet extends AbstractSet { @Pure public final @NonNegative int size() { return size; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void clear() { HashMap.this.clear(); } @SideEffectFree public final Iterator iterator() { return new KeyIterator(); } @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public final boolean contains(@Nullable @UnknownSignedness Object o) { return containsKey(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final boolean remove(@Nullable @UnknownSignedness Object key) { return removeNode(hash(key), key, null, false, true) != null; } @@ -1031,6 +1051,7 @@ public final Spliterator spliterator() { return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0); } + @SideEffectFree public Object[] toArray() { return keysToArray(new Object[size]); } @@ -1039,6 +1060,7 @@ public Object[] toArray() { return keysToArray(prepareArray(a)); } + @DoesNotUnrefineReceiver("modifiability") public final void forEach(Consumer action) { Node[] tab; if (action == null) @@ -1083,6 +1105,8 @@ public Collection values(@GuardSatisfied HashMap this) { final class Values extends AbstractCollection { @Pure public final @NonNegative int size() { return size; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void clear() { HashMap.this.clear(); } @SideEffectFree public final Iterator iterator() { return new ValueIterator(); } @@ -1094,6 +1118,7 @@ public final Spliterator spliterator() { return new ValueSpliterator<>(HashMap.this, 0, -1, 0, 0); } + @SideEffectFree public Object[] toArray() { return valuesToArray(new Object[size]); } @@ -1143,6 +1168,8 @@ public final void forEach(Consumer action) { final class EntrySet extends AbstractSet> { @Pure public final @NonNegative int size() { return size; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void clear() { HashMap.this.clear(); } @SideEffectFree public final Iterator> iterator() { @@ -1157,6 +1184,8 @@ public final boolean contains(@Nullable @UnknownSignedness Object o) { Node candidate = getNode(key); return candidate != null && candidate.equals(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final boolean remove(@Nullable @UnknownSignedness Object o) { if (o instanceof Map.Entry e) { Object key = e.getKey(); @@ -1169,6 +1198,7 @@ public final boolean remove(@Nullable @UnknownSignedness Object o) { public final Spliterator> spliterator() { return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0); } + @DoesNotUnrefineReceiver("modifiability") public final void forEach(Consumer> action) { Node[] tab; if (action == null) @@ -1196,16 +1226,22 @@ public V getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object key, V @EnsuresKeyFor(value={"#1"}, map={"this"}) @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V putIfAbsent(K key, V value) { return putVal(hash(key), key, value, true, true); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value) { return removeNode(hash(key), key, value, true, true) != null; } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { Node e; V v; if ((e = getNode(key)) != null && @@ -1218,6 +1254,8 @@ public boolean replace(K key, V oldValue, V newValue) { } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V replace(K key, V value) { Node e; if ((e = getNode(key)) != null) { @@ -1240,6 +1278,7 @@ public boolean replace(K key, V oldValue, V newValue) { * mapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfAbsent(K key, Function mappingFunction) { if (mappingFunction == null) @@ -1306,6 +1345,7 @@ else if (t != null) * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { if (remappingFunction == null) @@ -1340,6 +1380,7 @@ else if (t != null) * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V compute(K key, BiFunction remappingFunction) { if (remappingFunction == null) @@ -1405,6 +1446,7 @@ else if (v != null) { * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { if (value == null || remappingFunction == null) @@ -1466,6 +1508,7 @@ else if (v != null) { } @Override + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { Node[] tab; if (action == null) @@ -1482,6 +1525,7 @@ public void forEach(BiConsumer action) { } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { Node[] tab; if (function == null) @@ -1649,7 +1693,7 @@ public final boolean hasNext() { return next != null; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") final Node nextNode(@NonEmpty HashIterator this) { Node[] t; Node e = next; @@ -1663,6 +1707,8 @@ final Node nextNode(@NonEmpty HashIterator this) { return e; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void remove() { Node p = current; if (p == null) @@ -1677,16 +1723,22 @@ public final void remove() { final class KeyIterator extends HashIterator implements Iterator { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final K next(@NonEmpty KeyIterator this) { return nextNode().key; } } final class ValueIterator extends HashIterator implements Iterator { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final V next(@NonEmpty ValueIterator this) { return nextNode().value; } } final class EntryIterator extends HashIterator implements Iterator> { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final Map.Entry next(@NonEmpty EntryIterator this) { return nextNode(); } } diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 8cb8c1c1180..cdf44f001e5 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -37,8 +37,9 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.InvalidObjectException; import jdk.internal.access.SharedSecrets; @@ -247,8 +248,10 @@ public boolean contains(@GuardSatisfied HashSet this, @GuardSatisfied @Nullab * @return {@code true} if this set did not already contain the specified * element */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@GuardSatisfied HashSet this, E e) { return map.put(e, PRESENT)==null; } @@ -265,7 +268,8 @@ public boolean add(@GuardSatisfied HashSet this, E e) { * @param o object to be removed from this set, if present * @return {@code true} if the set contained the specified element */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied HashSet this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return map.remove(o)==PRESENT; } @@ -274,7 +278,8 @@ public boolean remove(@GuardSatisfied HashSet this, @GuardSatisfied @Nullable * Removes all of the elements from this set. * The set will be empty after this call returns. */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied HashSet this) { map.clear(); } @@ -394,11 +399,15 @@ private void readObject(java.io.ObjectInputStream s) * @return a {@code Spliterator} over the elements in this set * @since 1.8 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @SideEffectFree public Spliterator spliterator() { return new HashMap.KeySpliterator<>(map, 0, -1, 0, 0); } @Override + @SideEffectFree public Object[] toArray() { return map.keysToArray(new Object[map.size()]); } diff --git a/src/java.base/share/classes/java/util/Hashtable.java b/src/java.base/share/classes/java/util/Hashtable.java index dac8d241449..402eece52ad 100644 --- a/src/java.base/share/classes/java/util/Hashtable.java +++ b/src/java.base/share/classes/java/util/Hashtable.java @@ -39,9 +39,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.*; import java.util.function.BiConsumer; @@ -293,6 +294,7 @@ public synchronized boolean isEmpty(@GuardSatisfied Hashtable this) { * @see #keySet() * @see Map */ + @SideEffectFree public synchronized Enumeration<@KeyFor({"this"}) K> keys() { return this.getEnumeration(KEYS); } @@ -309,6 +311,7 @@ public synchronized boolean isEmpty(@GuardSatisfied Hashtable this) { * @see #values() * @see Map */ + @SideEffectFree public synchronized Enumeration elements() { return this.getEnumeration(VALUES); } @@ -374,8 +377,8 @@ public boolean containsValue(@GuardSatisfied Hashtable this, @GuardSatisfi * @throws NullPointerException if the key is {@code null} * @see #contains(Object) */ - @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) @Pure + @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) public synchronized boolean containsKey(@GuardSatisfied Hashtable this, @GuardSatisfied @UnknownSignedness Object key) { Entry tab[] = table; int hash = key.hashCode(); @@ -403,8 +406,8 @@ public synchronized boolean containsKey(@GuardSatisfied Hashtable this, @G * @throws NullPointerException if the specified key is null * @see #put(Object, Object) */ - @Pure @SuppressWarnings("unchecked") + @Pure public synchronized @Nullable V get(@GuardSatisfied Hashtable this, @UnknownSignedness @GuardSatisfied Object key) { Entry tab[] = table; int hash = key.hashCode(); @@ -500,6 +503,8 @@ private void addEntry(int hash, K key, V value, int index) { * @see #get(Object) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized @Nullable V put(@GuardSatisfied Hashtable this, K key, V value) { // Make sure the value is not null if (value == null) { @@ -533,6 +538,8 @@ private void addEntry(int hash, K key, V value, int index) { * or {@code null} if the key did not have a mapping * @throws NullPointerException if the key is {@code null} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized @Nullable V remove(@GuardSatisfied Hashtable this, @GuardSatisfied @UnknownSignedness Object key) { Entry tab[] = table; int hash = key.hashCode(); @@ -565,6 +572,8 @@ private void addEntry(int hash, K key, V value, int index) { * @throws NullPointerException if the specified map is null * @since 1.2 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized void putAll(@GuardSatisfied Hashtable this, Map t) { for (Map.Entry e : t.entrySet()) put(e.getKey(), e.getValue()); @@ -573,6 +582,8 @@ public synchronized void putAll(@GuardSatisfied Hashtable this, Map this) { Entry tab[] = table; for (int index = tab.length; --index >= 0; ) @@ -623,6 +634,7 @@ final Hashtable cloneHashtable() { * * @return a string representation of this hashtable */ + @SideEffectFree public synchronized String toString(@GuardSatisfied Hashtable this) { int max = size() - 1; if (max == -1) @@ -710,9 +722,13 @@ public Iterator iterator() { public boolean contains(@UnknownSignedness Object o) { return containsKey(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { return Hashtable.this.remove(o) != null; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { Hashtable.this.clear(); } @@ -748,6 +764,8 @@ public Iterator> iterator() { } @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(Map.Entry o) { return super.add(o); } @@ -768,6 +786,8 @@ public boolean contains(@UnknownSignedness Object o) { return false; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { if (!(o instanceof Map.Entry entry)) return false; @@ -799,6 +819,8 @@ public boolean remove(@UnknownSignedness Object o) { return count; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { Hashtable.this.clear(); } @@ -841,6 +863,8 @@ public Iterator iterator() { public boolean contains(@UnknownSignedness Object o) { return containsValue(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { Hashtable.this.clear(); } @@ -932,6 +956,7 @@ public synchronized V getOrDefault(@GuardSatisfied @UnknownSignedness Object key @SuppressWarnings("unchecked") @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void forEach(BiConsumer action) { Objects.requireNonNull(action); // explicit check required in case // table is empty. @@ -952,6 +977,7 @@ public synchronized void forEach(BiConsumer action) { @SuppressWarnings("unchecked") @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void replaceAll(BiFunction function) { Objects.requireNonNull(function); // explicit check required in case // table is empty. @@ -973,6 +999,8 @@ public synchronized void replaceAll(BiFunction tab[] = table; @@ -1072,6 +1106,7 @@ public synchronized V replace(K key, V value) { * mapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull V computeIfAbsent(K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); @@ -1108,6 +1143,7 @@ public synchronized V replace(K key, V value) { * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1150,6 +1186,7 @@ public synchronized V replace(K key, V value) { * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull V compute(K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1201,6 +1238,7 @@ public synchronized V replace(K key, V value) { * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1437,14 +1475,18 @@ protected Object clone() { // Map.Entry Ops + @Pure public K getKey() { return key; } + @Pure public V getValue() { return value; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V setValue(V value) { if (value == null) throw new NullPointerException(); @@ -1454,6 +1496,7 @@ public V setValue(V value) { return oldValue; } + @Pure public boolean equals(Object o) { if (!(o instanceof Map.Entry e)) return false; @@ -1462,10 +1505,12 @@ public boolean equals(Object o) { (value==null ? e.getValue()==null : value.equals(e.getValue())); } + @Pure public int hashCode() { return hash ^ Objects.hashCode(value); } + @SideEffectFree public String toString() { return key.toString()+"="+value.toString(); } @@ -1508,6 +1553,7 @@ private class Enumerator implements Enumeration, Iterator { this.iterator = iterator; } + @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean hasMoreElements() { Entry e = entry; @@ -1523,6 +1569,8 @@ public boolean hasMoreElements() { } @SuppressWarnings("unchecked") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public T nextElement(@NonEmpty Enumerator this) { Entry et = entry; int i = index; @@ -1548,13 +1596,16 @@ public boolean hasNext() { return hasMoreElements(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public T next(@NonEmpty Enumerator this) { if (Hashtable.this.modCount != expectedModCount) throw new ConcurrentModificationException(); return nextElement(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (!iterator) throw new UnsupportedOperationException(); diff --git a/src/java.base/share/classes/java/util/IdentityHashMap.java b/src/java.base/share/classes/java/util/IdentityHashMap.java index 6b70ff06197..94be828c390 100644 --- a/src/java.base/share/classes/java/util/IdentityHashMap.java +++ b/src/java.base/share/classes/java/util/IdentityHashMap.java @@ -37,9 +37,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -353,8 +354,8 @@ private static int nextKeyIndex(int i, int len) { * * @see #put(Object, Object) */ - @Pure @SuppressWarnings("unchecked") + @Pure public @Nullable V get(@GuardSatisfied IdentityHashMap this, @UnknownSignedness @GuardSatisfied @Nullable Object key) { Object k = maskNull(key); Object[] tab = table; @@ -380,8 +381,8 @@ private static int nextKeyIndex(int i, int len) { * in this map * @see #containsValue(Object) */ - @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) @Pure + @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) public boolean containsKey(@GuardSatisfied IdentityHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Object k = maskNull(key); Object[] tab = table; @@ -457,6 +458,8 @@ private boolean containsMapping(@UnknownSignedness @GuardSatisfied @Nullable Obj * @see #containsKey(Object) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(@GuardSatisfied IdentityHashMap this, K key, V value) { final Object k = maskNull(key); @@ -538,6 +541,8 @@ private boolean resize(int newCapacity) { * @param m mappings to be stored in this map * @throws NullPointerException if the specified map is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putAll(@GuardSatisfied IdentityHashMap this, Map m) { int n = m.size(); if (n == 0) @@ -560,6 +565,8 @@ public void putAll(@GuardSatisfied IdentityHashMap this, Map this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Object k = maskNull(key); Object[] tab = table; @@ -656,6 +663,8 @@ private void closeDeletion(int d) { * Removes all of the mappings from this map. * The map will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied IdentityHashMap this) { modCount++; Object[] tab = table; @@ -782,7 +791,8 @@ public boolean hasNext() { return false; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @Pure protected int nextIndex(@NonEmpty IdentityHashMapIterator this) { if (modCount != expectedModCount) throw new ConcurrentModificationException(); @@ -795,6 +805,8 @@ protected int nextIndex(@NonEmpty IdentityHashMapIterator this) { return lastReturnedIndex; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastReturnedIndex == -1) throw new IllegalStateException(); @@ -875,6 +887,8 @@ public void remove() { private class KeyIterator extends IdentityHashMapIterator { @SuppressWarnings("unchecked") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K next(@NonEmpty KeyIterator this) { return (K) unmaskNull(traversalTable[nextIndex()]); } @@ -882,6 +896,8 @@ public K next(@NonEmpty KeyIterator this) { private class ValueIterator extends IdentityHashMapIterator { @SuppressWarnings("unchecked") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V next(@NonEmpty ValueIterator this) { return (V) traversalTable[nextIndex() + 1]; } @@ -892,11 +908,15 @@ private class EntryIterator { private Entry lastReturnedEntry; + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry next(@NonEmpty EntryIterator this) { lastReturnedEntry = new Entry(nextIndex()); return lastReturnedEntry; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { lastReturnedIndex = ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index); @@ -913,18 +933,22 @@ private Entry(int index) { } @SuppressWarnings("unchecked") + @Pure public K getKey() { checkIndexForEntryUse(); return (K) unmaskNull(traversalTable[index]); } @SuppressWarnings("unchecked") + @Pure public V getValue() { checkIndexForEntryUse(); return (V) traversalTable[index+1]; } @SuppressWarnings("unchecked") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V setValue(V value) { checkIndexForEntryUse(); V oldValue = (V) traversalTable[index+1]; @@ -935,6 +959,7 @@ public V setValue(V value) { return oldValue; } + @Pure public boolean equals(@Nullable Object o) { if (index < 0) return super.equals(o); @@ -944,6 +969,7 @@ public boolean equals(@Nullable Object o) { && e.getValue() == traversalTable[index+1]; } + @Pure public int hashCode() { if (lastReturnedIndex < 0) return super.hashCode(); @@ -952,6 +978,7 @@ public int hashCode() { System.identityHashCode(traversalTable[index+1])); } + @SideEffectFree public String toString() { if (index < 0) return super.toString(); @@ -1038,6 +1065,8 @@ public Iterator iterator() { public boolean contains(@Nullable @UnknownSignedness Object o) { return containsKey(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { int oldSize = size; IdentityHashMap.this.remove(o); @@ -1048,6 +1077,8 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { * the former contains an optimization that results in incorrect * behavior when c is a smaller "normal" (non-identity-based) Set. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { Objects.requireNonNull(c); boolean modified = false; @@ -1059,9 +1090,12 @@ public boolean removeAll(Collection c) { } return modified; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { IdentityHashMap.this.clear(); } + @Pure public int hashCode() { int result = 0; for (K key : this) @@ -1073,7 +1107,6 @@ public Object[] toArray() { return toArray(new Object[0]); } @SuppressWarnings("unchecked") - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { int expectedModCount = modCount; int size = size(); @@ -1152,6 +1185,8 @@ public Iterator iterator() { public boolean contains(@Nullable @UnknownSignedness Object o) { return containsValue(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { for (Iterator i = iterator(); i.hasNext(); ) { if (i.next() == o) { @@ -1161,6 +1196,8 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { } return false; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { IdentityHashMap.this.clear(); } @@ -1169,7 +1206,6 @@ public Object[] toArray() { return toArray(new Object[0]); } @SuppressWarnings("unchecked") - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { int expectedModCount = modCount; int size = size(); @@ -1263,6 +1299,8 @@ public boolean contains(@Nullable @UnknownSignedness Object o) { return o instanceof Entry entry && containsMapping(entry.getKey(), entry.getValue()); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { return o instanceof Entry entry && removeMapping(entry.getKey(), entry.getValue()); @@ -1271,6 +1309,8 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { public @NonNegative int size() { return size; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { IdentityHashMap.this.clear(); } @@ -1279,6 +1319,8 @@ public void clear() { * the former contains an optimization that results in incorrect * behavior when c is a smaller "normal" (non-identity-based) Set. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { Objects.requireNonNull(c); boolean modified = false; @@ -1297,7 +1339,6 @@ public Object[] toArray() { } @SuppressWarnings("unchecked") - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { int expectedModCount = modCount; int size = size(); @@ -1439,6 +1480,7 @@ public void forEach(BiConsumer action) { @SuppressWarnings("unchecked") @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { Objects.requireNonNull(function); int expectedModCount = modCount; @@ -1466,6 +1508,8 @@ public void replaceAll(BiFunction function) { * {@code false}. */ @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(Object key, Object value) { return removeMapping(key, value); } @@ -1480,6 +1524,8 @@ public boolean remove(Object key, Object value) { * otherwise it returns {@code false}. */ @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { Object k = maskNull(key); Object[] tab = table; diff --git a/src/java.base/share/classes/java/util/ImmutableCollections.java b/src/java.base/share/classes/java/util/ImmutableCollections.java index 293e8c22448..f4310924b44 100644 --- a/src/java.base/share/classes/java/util/ImmutableCollections.java +++ b/src/java.base/share/classes/java/util/ImmutableCollections.java @@ -34,7 +34,8 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.IOException; import java.io.InvalidObjectException; @@ -312,6 +313,7 @@ public ListIterator listIterator(final int index) { } @Override + @Pure public boolean equals(Object o) { if (o == this) { return true; @@ -331,6 +333,7 @@ public boolean equals(Object o) { } @Override + @Pure public int hashCode() { int hash = 1; for (int i = 0, s = size(); i < s; i++) { @@ -389,7 +392,8 @@ public boolean hasNext() { return cursor != size; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty ListItr this) { try { int i = cursor; @@ -405,6 +409,7 @@ public void remove() { throw uoe(); } + @Pure public boolean hasPrevious() { if (!isListIterator) { throw uoe(); @@ -426,6 +431,7 @@ public E previous() { } } + @Pure public int nextIndex() { if (!isListIterator) { throw uoe(); @@ -433,6 +439,7 @@ public int nextIndex() { return cursor; } + @Pure public int previousIndex() { if (!isListIterator) { throw uoe(); @@ -483,6 +490,7 @@ static SubList fromList(AbstractImmutableList list, int fromIndex, int return new SubList<>(list, fromIndex, toIndex - fromIndex); } + @Pure public E get(int index) { Objects.checkIndex(index, size); return root.get(offset + index); @@ -518,6 +526,7 @@ private boolean allowNulls() { } @Override + @Pure public int indexOf(Object o) { if (!allowNulls() && o == null) { throw new NullPointerException(); @@ -531,6 +540,7 @@ public int indexOf(Object o) { } @Override + @Pure public int lastIndexOf(Object o) { if (!allowNulls() && o == null) { throw new NullPointerException(); @@ -597,6 +607,7 @@ public int size() { } @Override + @Pure @EnsuresNonEmptyIf(result = false, expression = "this") public boolean isEmpty() { return false; @@ -604,6 +615,7 @@ public boolean isEmpty() { @Override @SuppressWarnings("unchecked") + @Pure public E get(int index) { if (index == 0) { return e0; @@ -614,6 +626,7 @@ public E get(int index) { } @Override + @Pure public int indexOf(Object o) { Objects.requireNonNull(o); if (o.equals(e0)) { @@ -626,6 +639,7 @@ public int indexOf(Object o) { } @Override + @Pure public int lastIndexOf(Object o) { Objects.requireNonNull(o); if (e1 != EMPTY && o.equals(e1)) { @@ -707,6 +721,7 @@ public int size() { } @Override + @Pure public E get(int index) { return elements[index]; } @@ -742,6 +757,7 @@ public Object[] toArray() { } @Override + @Pure public int indexOf(Object o) { if (!allowNulls && o == null) { throw new NullPointerException(); @@ -756,6 +772,7 @@ public int indexOf(Object o) { } @Override + @Pure public int lastIndexOf(Object o) { if (!allowNulls && o == null) { throw new NullPointerException(); @@ -777,6 +794,7 @@ abstract static class AbstractImmutableSet extends AbstractImmutableCollectio implements Set { @Override + @Pure public boolean equals(Object o) { if (o == this) { return true; @@ -797,6 +815,7 @@ public boolean equals(Object o) { } @Override + @Pure public abstract int hashCode(); } @@ -833,6 +852,7 @@ public int size() { } @Override + @Pure @EnsuresNonEmptyIf(result = false, expression = "this") public boolean isEmpty() { return false; @@ -846,6 +866,7 @@ public boolean contains(@UnknownSignedness Object o) { } @Override + @Pure public int hashCode() { return e0.hashCode() + (e1 == EMPTY ? 0 : e1.hashCode()); } @@ -863,7 +884,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @SuppressWarnings("unchecked") public E next(/*@NonEmpty Iterator this*/) { if (idx == 1) { @@ -967,6 +989,7 @@ public int size() { } @Override + @Pure @EnsuresNonEmptyIf(result = false, expression = "this") public boolean isEmpty() { return size == 0; @@ -1001,7 +1024,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty SetNIterator this) { if (remaining > 0) { E element; @@ -1034,6 +1058,7 @@ public Iterator iterator() { } @Override + @Pure public int hashCode() { int h = 0; for (E e : elements) { @@ -1130,6 +1155,7 @@ abstract static class AbstractImmutableMap extends AbstractMap impleme * value should be returned. */ @Override + @Pure public V getOrDefault(Object key, V defaultValue) { V v; return ((v = get(key)) != null) @@ -1157,6 +1183,7 @@ public Set> entrySet() { } @Override + @Pure public V get(Object o) { return o.equals(k0) ? v0 : null; // implicit nullcheck of o } @@ -1174,11 +1201,13 @@ public boolean containsValue(@UnknownSignedness Object o) { } @Override + @Pure public int size() { return 1; } @Override + @Pure @EnsuresNonEmptyIf(result = false, expression = "this") public boolean isEmpty() { return false; @@ -1195,6 +1224,7 @@ private Object writeReplace() { } @Override + @Pure public int hashCode() { return k0.hashCode() ^ v0.hashCode(); } @@ -1265,6 +1295,7 @@ public boolean containsValue(@UnknownSignedness Object o) { } @Override + @Pure public int hashCode() { int hash = 0; for (int i = 0; i < table.length; i += 2) { @@ -1278,6 +1309,7 @@ public int hashCode() { @Override @SuppressWarnings("unchecked") + @Pure public V get(Object o) { if (size == 0) { Objects.requireNonNull(o); @@ -1298,6 +1330,7 @@ public int size() { } @Override + @Pure @EnsuresNonEmptyIf(result = false, expression = "this") public boolean isEmpty() { return size == 0; @@ -1323,7 +1356,9 @@ public boolean hasNext() { return remaining > 0; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @Pure private int nextIndex() { int idx = this.idx; if (REVERSE) { diff --git a/src/java.base/share/classes/java/util/Iterator.java b/src/java.base/share/classes/java/util/Iterator.java index 192ae2d21d3..912863723d8 100644 --- a/src/java.base/share/classes/java/util/Iterator.java +++ b/src/java.base/share/classes/java/util/Iterator.java @@ -30,10 +30,11 @@ import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; import org.checkerframework.framework.qual.Covariant; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.function.Consumer; @@ -88,7 +89,8 @@ public interface Iterator { * @return the next element in the iteration * @throws NoSuchElementException if the iteration has no more elements */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E next(@GuardSatisfied @NonEmpty Iterator this); /** @@ -116,6 +118,8 @@ public interface Iterator { * been called after the last call to the {@code next} * method */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default void remove(@GuardSatisfied @CanShrink Iterator this) { throw new UnsupportedOperationException("remove"); } @@ -145,6 +149,7 @@ default void remove(@GuardSatisfied @CanShrink Iterator this) { * @throws NullPointerException if the specified action is null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(Consumer action) { Objects.requireNonNull(action); while (hasNext()) diff --git a/src/java.base/share/classes/java/util/JumboEnumSet.java b/src/java.base/share/classes/java/util/JumboEnumSet.java index 6005a4c5bd0..1f41985d3be 100644 --- a/src/java.base/share/classes/java/util/JumboEnumSet.java +++ b/src/java.base/share/classes/java/util/JumboEnumSet.java @@ -37,7 +37,8 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.dataflow.qual.Pure; @@ -71,6 +72,8 @@ final class JumboEnumSet> extends EnumSet { elements = new long[(universe.length + 63) >>> 6]; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void addRange(E from, E to) { int fromIndex = from.ordinal() >>> 6; int toIndex = to.ordinal() >>> 6; @@ -87,6 +90,8 @@ void addRange(E from, E to) { size = to.ordinal() - from.ordinal() + 1; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void addAll() { for (int i = 0; i < elements.length; i++) elements[i] = -1; @@ -94,6 +99,8 @@ void addAll() { size = universe.length; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void complement() { for (int i = 0; i < elements.length; i++) elements[i] = ~elements[i]; @@ -110,6 +117,7 @@ void complement() { * * @return an iterator over the elements contained in this set */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty JumboEnumSet this) { return new EnumSetIterator<>(); } @@ -152,7 +160,8 @@ public boolean hasNext() { @Override @SuppressWarnings("unchecked") - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty EnumSetIterator this) { if (!hasNext()) throw new NoSuchElementException(); @@ -164,6 +173,8 @@ public E next(@NonEmpty EnumSetIterator this) { } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastReturned == 0) throw new IllegalStateException(); @@ -227,6 +238,8 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object e) { * @throws NullPointerException if {@code e} is null */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { typeCheck(e); @@ -247,6 +260,8 @@ public boolean add(E e) { * @param e element to be removed from this set, if present * @return {@code true} if the set contained the specified element */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object e) { if (e == null) return false; @@ -297,6 +312,8 @@ public boolean containsAll(Collection c) { * @throws NullPointerException if the specified collection or any of * its elements are null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { if (!(c instanceof JumboEnumSet es)) return super.addAll(c); @@ -322,6 +339,8 @@ public boolean addAll(Collection c) { * @return {@code true} if this set changed as a result of the call * @throws NullPointerException if the specified collection is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { if (!(c instanceof JumboEnumSet es)) return super.removeAll(c); @@ -342,6 +361,8 @@ public boolean removeAll(Collection c) { * @return {@code true} if this set changed as a result of the call * @throws NullPointerException if the specified collection is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { if (!(c instanceof JumboEnumSet es)) return super.retainAll(c); @@ -360,6 +381,8 @@ public boolean retainAll(Collection c) { /** * Removes all of the elements from this set. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { Arrays.fill(elements, 0); size = 0; @@ -398,6 +421,7 @@ private boolean recalculateSize() { return size != oldSize; } + @SideEffectFree public EnumSet clone() { JumboEnumSet result = (JumboEnumSet) super.clone(); result.elements = result.elements.clone(); diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 1f58fb94550..34cf94e8491 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -36,8 +36,9 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.function.Consumer; import java.util.function.BiConsumer; @@ -404,6 +405,8 @@ void afterNodeAccess(Node e) { * * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putFirst(K k, V v) { try { putMode = PUT_FIRST; @@ -421,6 +424,8 @@ public V putFirst(K k, V v) { * * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putLast(K k, V v) { try { putMode = PUT_LAST; @@ -573,6 +578,8 @@ public V getOrDefault(@Nullable Object key, V defaultValue) { /** * {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied LinkedHashMap this) { super.clear(); head = tail = null; @@ -715,6 +722,8 @@ final class LinkedKeySet extends AbstractSet implements SequencedSet { LinkedKeySet(boolean reversed) { this.reversed = reversed; } @Pure public final int size() { return size; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void clear() { LinkedHashMap.this.clear(); } @SideEffectFree public final Iterator iterator() { @@ -723,6 +732,8 @@ public final Iterator iterator() { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public final boolean contains(@Nullable @UnknownSignedness Object o) { return containsKey(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final boolean remove(@Nullable @UnknownSignedness Object key) { return removeNode(hash(key), key, null, false, true) != null; } @@ -733,6 +744,7 @@ public final Spliterator spliterator() { Spliterator.DISTINCT); } + @SideEffectFree public Object[] toArray() { return keysToArray(new Object[size], reversed); } @@ -741,6 +753,7 @@ public Object[] toArray() { return keysToArray(prepareArray(a), reversed); } + @DoesNotUnrefineReceiver("modifiability") public final void forEach(Consumer action) { if (action == null) throw new NullPointerException(); @@ -757,13 +770,19 @@ public final void forEach(Consumer action) { } public final void addFirst(K k) { throw new UnsupportedOperationException(); } public final void addLast(K k) { throw new UnsupportedOperationException(); } + @Pure public final K getFirst() { return nsee(reversed ? tail : head).key; } + @Pure public final K getLast() { return nsee(reversed ? head : tail).key; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final K removeFirst() { var node = nsee(reversed ? tail : head); removeNode(node.hash, node.key, null, false, false); return node.key; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final K removeLast() { var node = nsee(reversed ? head : tail); removeNode(node.hash, node.key, null, false, false); @@ -797,6 +816,7 @@ public SequencedSet reversed() { * * @return a view of the values contained in this map */ + @SideEffectFree public Collection values() { return sequencedValues(); } @@ -828,6 +848,8 @@ final class LinkedValues extends AbstractCollection implements SequencedColle LinkedValues(boolean reversed) { this.reversed = reversed; } @Pure public final int size() { return size; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void clear() { LinkedHashMap.this.clear(); } @SideEffectFree public final Iterator iterator() { @@ -842,6 +864,7 @@ public final Spliterator spliterator() { Spliterator.ORDERED); } + @SideEffectFree public Object[] toArray() { return valuesToArray(new Object[size], reversed); } @@ -850,6 +873,7 @@ public Object[] toArray() { return valuesToArray(prepareArray(a), reversed); } + @DoesNotUnrefineReceiver("modifiability") public final void forEach(Consumer action) { if (action == null) throw new NullPointerException(); @@ -866,13 +890,19 @@ public final void forEach(Consumer action) { } public final void addFirst(V v) { throw new UnsupportedOperationException(); } public final void addLast(V v) { throw new UnsupportedOperationException(); } + @Pure public final V getFirst() { return nsee(reversed ? tail : head).value; } + @Pure public final V getLast() { return nsee(reversed ? head : tail).value; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final V removeFirst() { var node = nsee(reversed ? tail : head); removeNode(node.hash, node.key, null, false, false); return node.value; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final V removeLast() { var node = nsee(reversed ? head : tail); removeNode(node.hash, node.key, null, false, false); @@ -940,6 +970,8 @@ final class LinkedEntrySet extends AbstractSet> LinkedEntrySet(boolean reversed) { this.reversed = reversed; } @Pure public final int size() { return size; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void clear() { LinkedHashMap.this.clear(); } @SideEffectFree public final Iterator> iterator() { @@ -954,6 +986,8 @@ public final boolean contains(@Nullable @UnknownSignedness Object o) { Node candidate = getNode(key); return candidate != null && candidate.equals(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final boolean remove(@Nullable @UnknownSignedness Object o) { if (o instanceof Map.Entry e) { Object key = e.getKey(); @@ -968,6 +1002,7 @@ public final Spliterator> spliterator() { Spliterator.ORDERED | Spliterator.DISTINCT); } + @DoesNotUnrefineReceiver("modifiability") public final void forEach(Consumer> action) { if (action == null) throw new NullPointerException(); @@ -990,13 +1025,19 @@ final Node nsee(Node e) { } public final void addFirst(Map.Entry e) { throw new UnsupportedOperationException(); } public final void addLast(Map.Entry e) { throw new UnsupportedOperationException(); } + @Pure public final Map.Entry getFirst() { return nsee(reversed ? tail : head); } + @Pure public final Map.Entry getLast() { return nsee(reversed ? head : tail); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final Map.Entry removeFirst() { var node = nsee(reversed ? tail : head); removeNode(node.hash, node.key, null, false, false); return node; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final Map.Entry removeLast() { var node = nsee(reversed ? head : tail); removeNode(node.hash, node.key, null, false, false); @@ -1013,6 +1054,7 @@ public SequencedSet> reversed() { // Map overrides + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { if (action == null) throw new NullPointerException(); @@ -1023,6 +1065,7 @@ public void forEach(BiConsumer action) { throw new ConcurrentModificationException(); } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { if (function == null) throw new NullPointerException(); @@ -1054,7 +1097,7 @@ public final boolean hasNext() { return next != null; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") final LinkedHashMap.Entry nextNode(@NonEmpty LinkedHashIterator this) { LinkedHashMap.Entry e = next; if (modCount != expectedModCount) @@ -1066,6 +1109,8 @@ final LinkedHashMap.Entry nextNode(@NonEmpty LinkedHashIterator this) { return e; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void remove() { Node p = current; if (p == null) @@ -1081,18 +1126,25 @@ public final void remove() { final class LinkedKeyIterator extends LinkedHashIterator implements Iterator { LinkedKeyIterator(boolean reversed) { super(reversed); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @Pure public final K next(@NonEmpty LinkedKeyIterator this) { return nextNode().getKey(); } } final class LinkedValueIterator extends LinkedHashIterator implements Iterator { LinkedValueIterator(boolean reversed) { super(reversed); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final V next(@NonEmpty LinkedValueIterator this) { return nextNode().value; } } final class LinkedEntryIterator extends LinkedHashIterator implements Iterator> { LinkedEntryIterator(boolean reversed) { super(reversed); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final Map.Entry next(@NonEmpty LinkedEntryIterator this) { return nextNode(); } } @@ -1143,68 +1195,88 @@ static class ReversedLinkedHashMapView extends AbstractMap // Object // inherit toString() from AbstractMap; it depends on entrySet() + @Pure public boolean equals(Object o) { return base.equals(o); } + @Pure public int hashCode() { return base.hashCode(); } // Map + @Pure public int size() { return base.size(); } + @Pure public boolean isEmpty() { return base.isEmpty(); } + @Pure public boolean containsKey(Object key) { return base.containsKey(key); } + @Pure public boolean containsValue(Object value) { return base.containsValue(value); } + @Pure public V get(Object key) { return base.get(key); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V put(K key, V value) { return base.put(key, value); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V remove(Object key) { return base.remove(key); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putAll(Map m) { base.putAll(m); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { base.clear(); } + @SideEffectFree public Set keySet() { return base.sequencedKeySet().reversed(); } + @SideEffectFree public Collection values() { return base.sequencedValues().reversed(); } + @SideEffectFree public Set> entrySet() { return base.sequencedEntrySet().reversed(); } + @Pure public V getOrDefault(Object key, V defaultValue) { return base.getOrDefault(key, defaultValue); } + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { if (action == null) throw new NullPointerException(); @@ -1215,6 +1287,7 @@ public void forEach(BiConsumer action) { throw new ConcurrentModificationException(); } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { if (function == null) throw new NullPointerException(); @@ -1225,34 +1298,46 @@ public void replaceAll(BiFunction function) { throw new ConcurrentModificationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putIfAbsent(K key, V value) { return base.putIfAbsent(key, value); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(Object key, Object value) { return base.remove(key, value); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { return base.replace(key, oldValue, newValue); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V replace(K key, V value) { return base.replace(key, value); } + @DoesNotUnrefineReceiver("modifiability") public V computeIfAbsent(K key, Function mappingFunction) { return base.computeIfAbsent(key, mappingFunction); } + @DoesNotUnrefineReceiver("modifiability") public V computeIfPresent(K key, BiFunction remappingFunction) { return base.computeIfPresent(key, remappingFunction); } + @DoesNotUnrefineReceiver("modifiability") public V compute(K key, BiFunction remappingFunction) { return base.compute(key, remappingFunction); } + @DoesNotUnrefineReceiver("modifiability") public V merge(K key, V value, BiFunction remappingFunction) { return base.merge(key, value, remappingFunction); } @@ -1271,18 +1356,26 @@ public Entry lastEntry() { return base.firstEntry(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Entry pollFirstEntry() { return base.pollLastEntry(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Entry pollLastEntry() { return base.pollFirstEntry(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putFirst(K k, V v) { return base.putLast(k, v); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putLast(K k, V v) { return base.putFirst(k, v); } diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index dc0110b6b67..feb93687f02 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -25,8 +25,12 @@ package java.util; +import org.checkerframework.dataflow.qual.Deterministic; +import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** *

    Hash table and linked list implementation of the {@code Set} interface, @@ -207,6 +211,9 @@ public LinkedHashSet(Collection c) { * @since 1.8 */ @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @SideEffectFree public Spliterator spliterator() { return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED); } @@ -231,6 +238,7 @@ public static LinkedHashSet newLinkedHashSet(int numElements) { } @SuppressWarnings("unchecked") + @Deterministic LinkedHashMap map() { return (LinkedHashMap) map; } @@ -243,6 +251,8 @@ LinkedHashMap map() { * * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { map().putFirst(e, PRESENT); } @@ -255,6 +265,8 @@ public void addFirst(E e) { * * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { map().putLast(e, PRESENT); } @@ -265,6 +277,7 @@ public void addLast(E e) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getFirst() { return map().sequencedKeySet().getFirst(); } @@ -275,6 +288,7 @@ public E getFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getLast() { return map().sequencedKeySet().getLast(); } @@ -285,6 +299,8 @@ public E getLast() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeFirst() { return map().sequencedKeySet().removeFirst(); } @@ -295,6 +311,8 @@ public E removeFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeLast() { return map().sequencedKeySet().removeLast(); } @@ -308,18 +326,26 @@ public E removeLast() { * @return {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public SequencedSet reversed() { class ReverseLinkedHashSetView extends AbstractSet implements SequencedSet { + @Pure public int size() { return LinkedHashSet.this.size(); } + @SideEffectFree public Iterator iterator() { return map().sequencedKeySet().reversed().iterator(); } public boolean add(E e) { return LinkedHashSet.this.add(e); } public void addFirst(E e) { LinkedHashSet.this.addLast(e); } public void addLast(E e) { LinkedHashSet.this.addFirst(e); } + @Pure public E getFirst() { return LinkedHashSet.this.getLast(); } + @Pure public E getLast() { return LinkedHashSet.this.getFirst(); } public E removeFirst() { return LinkedHashSet.this.removeLast(); } public E removeLast() { return LinkedHashSet.this.removeFirst(); } public SequencedSet reversed() { return LinkedHashSet.this; } + @Pure + @SideEffectFree public Object[] toArray() { return map().keysToArray(new Object[map.size()], true); } public T[] toArray(T[] a) { return map().keysToArray(map.prepareArray(a), true); } } diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index b86c45c789d..6740c068eb5 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -41,9 +41,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.IOException; import java.io.ObjectInput; @@ -271,6 +272,7 @@ E unlink(Node x) { * @return the first element in this list * @throws NoSuchElementException if this list is empty */ + @Pure public E getFirst(@GuardSatisfied @NonEmpty LinkedList this) { final Node f = first; if (f == null) @@ -284,6 +286,7 @@ public E getFirst(@GuardSatisfied @NonEmpty LinkedList this) { * @return the last element in this list * @throws NoSuchElementException if this list is empty */ + @Pure public E getLast(@GuardSatisfied @NonEmpty LinkedList this) { final Node l = last; if (l == null) @@ -297,6 +300,8 @@ public E getLast(@GuardSatisfied @NonEmpty LinkedList this) { * @return the first element from this list * @throws NoSuchElementException if this list is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { final Node f = first; if (f == null) @@ -310,6 +315,8 @@ public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { * @return the last element from this list * @throws NoSuchElementException if this list is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeLast(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { final Node l = last; if (l == null) @@ -322,6 +329,8 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { * * @param e the element to add */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(@GuardSatisfied LinkedList this, E e) { linkFirst(e); } @@ -333,6 +342,8 @@ public void addFirst(@GuardSatisfied LinkedList this, E e) { * * @param e the element to add */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(@GuardSatisfied LinkedList this, E e) { linkLast(e); } @@ -372,6 +383,8 @@ public boolean contains(@GuardSatisfied LinkedList this, @GuardSatisfied @Nul */ @ReleasesNoLocks @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@GuardSatisfied LinkedList this, E e) { linkLast(e); return true; @@ -391,6 +404,8 @@ public boolean add(@GuardSatisfied LinkedList this, E e) { * @return {@code true} if this list contained the specified element */ @ReleasesNoLocks + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) { for (Node x = first; x != null; x = x.next) { @@ -422,6 +437,8 @@ public boolean remove(@GuardSatisfied @CanShrink LinkedList this, @GuardSatis * @return {@code true} if this list changed as a result of the call * @throws NullPointerException if the specified collection is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@GuardSatisfied LinkedList this, Collection c) { return addAll(size, c); } @@ -441,6 +458,8 @@ public boolean addAll(@GuardSatisfied LinkedList this, Collection this, @NonNegative int index, Collection c) { checkPositionIndex(index); @@ -484,6 +503,8 @@ public boolean addAll(@GuardSatisfied LinkedList this, @NonNegative int index * Removes all of the elements from this list. * The list will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink LinkedList this) { // Clearing all of the links between nodes is "unnecessary", but: // - helps a generational GC if the discarded nodes inhabit @@ -526,6 +547,8 @@ public E get(@GuardSatisfied LinkedList this, @NonNegative int index) { * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(@GuardSatisfied LinkedList this, @NonNegative int index, E element) { checkElementIndex(index); Node x = node(index); @@ -543,6 +566,8 @@ public E set(@GuardSatisfied LinkedList this, @NonNegative int index, E eleme * @param element element to be inserted * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(@GuardSatisfied LinkedList this, @NonNegative int index, E element) { checkPositionIndex(index); @@ -561,6 +586,8 @@ public void add(@GuardSatisfied LinkedList this, @NonNegative int index, E el * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(@GuardSatisfied @CanShrink LinkedList this, @NonNegative int index) { checkElementIndex(index); return unlink(node(index)); @@ -702,6 +729,7 @@ Node node(@NonNegative int index) { * @throws NoSuchElementException if this list is empty * @since 1.5 */ + @Pure public E element(@GuardSatisfied @NonEmpty LinkedList this) { return getFirst(); } @@ -712,6 +740,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { * @return the head of this list, or {@code null} if this list is empty * @since 1.5 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink LinkedList this) { final Node f = first; return (f == null) ? null : unlinkFirst(f); @@ -724,6 +754,8 @@ public E element(@GuardSatisfied @NonEmpty LinkedList this) { * @throws NoSuchElementException if this list is empty * @since 1.5 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { return removeFirst(); } @@ -735,6 +767,8 @@ public E remove(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { * @return {@code true} (as specified by {@link Queue#offer}) * @since 1.5 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { return add(e); } @@ -747,6 +781,8 @@ public boolean offer(E e) { * @return {@code true} (as specified by {@link Deque#offerFirst}) * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(E e) { addFirst(e); return true; @@ -759,6 +795,8 @@ public boolean offerFirst(E e) { * @return {@code true} (as specified by {@link Deque#offerLast}) * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(E e) { addLast(e); return true; @@ -800,6 +838,8 @@ public boolean offerLast(E e) { * this list is empty * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@GuardSatisfied @CanShrink LinkedList this) { final Node f = first; return (f == null) ? null : unlinkFirst(f); @@ -813,6 +853,8 @@ public boolean offerLast(E e) { * this list is empty * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@GuardSatisfied @CanShrink LinkedList this) { final Node l = last; return (l == null) ? null : unlinkLast(l); @@ -827,6 +869,8 @@ public boolean offerLast(E e) { * @param e the element to push * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void push(@GuardSatisfied LinkedList this, E e) { addFirst(e); } @@ -842,6 +886,8 @@ public void push(@GuardSatisfied LinkedList this, E e) { * @throws NoSuchElementException if this list is empty * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E pop(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { return removeFirst(); } @@ -855,6 +901,8 @@ public E pop(@GuardSatisfied @NonEmpty @CanShrink LinkedList this) { * @return {@code true} if the list contained the specified element * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeFirstOccurrence(@GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return remove(o); } @@ -868,6 +916,8 @@ public boolean removeFirstOccurrence(@GuardSatisfied @CanShrink LinkedList th * @return {@code true} if the list contained the specified element * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeLastOccurrence(@GuardSatisfied @CanShrink LinkedList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) { for (Node x = last; x != null; x = x.prev) { @@ -931,7 +981,8 @@ public boolean hasNext() { return nextIndex < size; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty ListItr this) { checkForComodification(); if (!hasNext()) @@ -943,10 +994,13 @@ public E next(@NonEmpty ListItr this) { return lastReturned.item; } + @Pure public boolean hasPrevious() { return nextIndex > 0; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E previous() { checkForComodification(); if (!hasPrevious()) @@ -957,14 +1011,18 @@ public E previous() { return lastReturned.item; } + @Pure public int nextIndex() { return nextIndex; } + @Pure public int previousIndex() { return nextIndex - 1; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { checkForComodification(); if (lastReturned == null) @@ -980,6 +1038,8 @@ public void remove() { expectedModCount++; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { if (lastReturned == null) throw new IllegalStateException(); @@ -987,6 +1047,8 @@ public void set(E e) { lastReturned.item = e; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { checkForComodification(); lastReturned = null; @@ -1044,10 +1106,13 @@ private class DescendingIterator implements Iterator { public boolean hasNext() { return itr.hasPrevious(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty DescendingIterator this) { return itr.previous(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { itr.remove(); } @@ -1344,22 +1409,29 @@ static class ReverseOrderLinkedListView extends LinkedList implements java this.rdeque = rdeque; } + @SideEffectFree public String toString() { return rlist.toString(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { return rlist.retainAll(c); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return rlist.removeAll(c); } + @Pure public boolean containsAll(Collection c) { return rlist.containsAll(c); } + @Pure public boolean isEmpty() { return rlist.isEmpty(); } @@ -1372,6 +1444,8 @@ public Stream stream() { return rlist.stream(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { return rlist.removeIf(filter); } @@ -1384,18 +1458,22 @@ public void forEach(Consumer action) { rlist.forEach(action); } + @SideEffectFree public Iterator iterator() { return rlist.iterator(); } + @Pure public int hashCode() { return rlist.hashCode(); } + @Pure public boolean equals(Object o) { return rlist.equals(o); } + @SideEffectFree public List subList(int fromIndex, int toIndex) { return rlist.subList(fromIndex, toIndex); } @@ -1404,10 +1482,13 @@ public ListIterator listIterator() { return rlist.listIterator(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { rlist.sort(c); } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { rlist.replaceAll(operator); } @@ -1416,6 +1497,7 @@ public LinkedList reversed() { return list; } + @SideEffectFree public Spliterator spliterator() { return rlist.spliterator(); } @@ -1424,6 +1506,7 @@ public T[] toArray(T[] a) { return rlist.toArray(a); } + @SideEffectFree public Object[] toArray() { return rlist.toArray(); } @@ -1436,138 +1519,195 @@ public ListIterator listIterator(int index) { return rlist.listIterator(index); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeLastOccurrence(Object o) { return rdeque.removeLastOccurrence(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeFirstOccurrence(Object o) { return rdeque.removeFirstOccurrence(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E pop() { return rdeque.pop(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void push(E e) { rdeque.push(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E pollLast() { return rdeque.pollLast(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E pollFirst() { return rdeque.pollFirst(); } + @Pure public E peekLast() { return rdeque.peekLast(); } + @Pure public E peekFirst() { return rdeque.peekFirst(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(E e) { return rdeque.offerLast(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(E e) { return rdeque.offerFirst(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { return rdeque.offer(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove() { return rdeque.remove(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E poll() { return rdeque.poll(); } + @Pure public E element() { return rdeque.element(); } + @Pure public E peek() { return rdeque.peek(); } + @Pure public int lastIndexOf(Object o) { return rlist.lastIndexOf(o); } + @Pure public int indexOf(Object o) { return rlist.indexOf(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(int index) { return rlist.remove(index); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(int index, E element) { rlist.add(index, element); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(int index, E element) { return rlist.set(index, element); } + @Pure public E get(int index) { return rlist.get(index); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { rlist.clear(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { return rlist.addAll(index, c); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { return rlist.addAll(c); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(Object o) { return rlist.remove(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { return rlist.add(e); } + @Pure public int size() { return rlist.size(); } + @Pure public boolean contains(Object o) { return rlist.contains(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { rdeque.addLast(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { rdeque.addFirst(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeLast() { return rdeque.removeLast(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeFirst() { return rdeque.removeFirst(); } + @Pure public E getLast() { return rdeque.getLast(); } + @Pure public E getFirst() { return rdeque.getFirst(); } diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 301a5f4d4d9..70970580865 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -43,9 +43,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.function.UnaryOperator; @@ -269,7 +270,6 @@ public interface List extends SequencedCollection { * this list * @throws NullPointerException if the specified array is null */ - @SideEffectFree @Nullable T[] toArray(@PolyNull T[] a); @@ -298,7 +298,8 @@ public interface List extends SequencedCollection { * prevents it from being added to this list */ @ReleasesNoLocks - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresNonEmpty("this") boolean add(@GuardSatisfied List this, E e); @@ -323,7 +324,8 @@ public interface List extends SequencedCollection { * @throws UnsupportedOperationException if the {@code remove} operation * is not supported by this list */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean remove(@GuardSatisfied @CanShrink List this, @UnknownSignedness Object o); @@ -371,7 +373,8 @@ public interface List extends SequencedCollection { * specified collection prevents it from being added to this list * @see #add(Object) */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresNonEmptyIf(result = true, expression = "this") boolean addAll(@GuardSatisfied List this, Collection c); @@ -402,7 +405,8 @@ public interface List extends SequencedCollection { * @throws IndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index > size()}) */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresNonEmptyIf(result = true, expression = "this") boolean addAll(@GuardSatisfied List this, @IndexOrHigh({"this"}) int index, Collection c); @@ -424,6 +428,8 @@ public interface List extends SequencedCollection { * @see #remove(Object) * @see #contains(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean removeAll(@GuardSatisfied @CanShrink List this, Collection c); /** @@ -446,6 +452,8 @@ public interface List extends SequencedCollection { * @see #remove(Object) * @see #contains(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean retainAll(@GuardSatisfied @CanShrink List this, Collection c); /** @@ -477,6 +485,7 @@ public interface List extends SequencedCollection { * (optional) * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default void replaceAll(UnaryOperator operator) { Objects.requireNonNull(operator); final ListIterator li = this.listIterator(); @@ -545,6 +554,8 @@ default void replaceAll(UnaryOperator operator) { * @since 1.8 */ @SuppressWarnings({"unchecked", "rawtypes"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default void sort(Comparator c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); @@ -562,6 +573,8 @@ default void sort(Comparator c) { * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this list */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void clear(@GuardSatisfied @CanShrink List this); @@ -636,6 +649,8 @@ default void sort(Comparator c) { * @throws IndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E set(@GuardSatisfied List this, @IndexFor({"this"}) int index, E element); /** @@ -658,7 +673,8 @@ default void sort(Comparator c) { * ({@code index < 0 || index > size()}) */ @ReleasesNoLocks - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void add(@GuardSatisfied List this, @IndexOrHigh({"this"}) int index, E element); /** @@ -675,6 +691,8 @@ default void sort(Comparator c) { * ({@code index < 0 || index >= size()}) */ @ReleasesNoLocks + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E remove(@GuardSatisfied @CanShrink List this, @IndexFor({"this"}) int index); @@ -843,6 +861,8 @@ default Spliterator spliterator() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default void addFirst(E e) { this.add(0, e); } @@ -857,6 +877,8 @@ default void addFirst(E e) { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default void addLast(E e) { this.add(e); } @@ -871,6 +893,7 @@ default void addLast(E e) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure default E getFirst() { if (this.isEmpty()) { throw new NoSuchElementException(); @@ -889,6 +912,7 @@ default E getFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure default E getLast() { if (this.isEmpty()) { throw new NoSuchElementException(); @@ -908,6 +932,8 @@ default E getLast() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default E removeFirst() { if (this.isEmpty()) { throw new NoSuchElementException(); @@ -927,6 +953,8 @@ default E removeFirst() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default E removeLast() { if (this.isEmpty()) { throw new NoSuchElementException(); @@ -967,6 +995,7 @@ default List reversed() { * * @since 9 */ + @SideEffectFree @SuppressWarnings("unchecked") static List of() { return (List) ImmutableCollections.EMPTY_LIST; @@ -984,6 +1013,7 @@ static List of() { * * @since 9 */ + @SideEffectFree static @NonEmpty List of(E e1) { return new ImmutableCollections.List12<>(e1); } @@ -1001,6 +1031,7 @@ static List of() { * * @since 9 */ + @SideEffectFree static @NonEmpty List of(E e1, E e2) { return new ImmutableCollections.List12<>(e1, e2); } @@ -1019,6 +1050,7 @@ static List of() { * * @since 9 */ + @SideEffectFree static @NonEmpty List of(E e1, E e2, E e3) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3); } @@ -1038,6 +1070,7 @@ static List of() { * * @since 9 */ + @SideEffectFree static @NonEmpty List of(E e1, E e2, E e3, E e4) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4); } @@ -1058,6 +1091,7 @@ static List of() { * * @since 9 */ + @SideEffectFree static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5); } @@ -1079,6 +1113,7 @@ static List of() { * * @since 9 */ + @SideEffectFree static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5, e6); @@ -1102,6 +1137,7 @@ static List of() { * * @since 9 */ + @SideEffectFree static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5, e6, e7); @@ -1126,6 +1162,7 @@ static List of() { * * @since 9 */ + @SideEffectFree static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5, e6, e7, e8); @@ -1151,6 +1188,7 @@ static List of() { * * @since 9 */ + @SideEffectFree static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5, e6, e7, e8, e9); @@ -1177,6 +1215,7 @@ static List of() { * * @since 9 */ + @SideEffectFree static @NonEmpty List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { return ImmutableCollections.listFromTrustedArray(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); @@ -1207,6 +1246,7 @@ static List of() { * * @since 9 */ + @SideEffectFree @SafeVarargs @SuppressWarnings("varargs") static @PolyNonEmpty List of(E @PolyNonEmpty... elements) { @@ -1240,6 +1280,7 @@ static List of() { * @throws NullPointerException if coll is null, or if it contains any nulls * @since 10 */ + @SideEffectFree static @PolyNonEmpty List copyOf(@PolyNonEmpty Collection coll) { return ImmutableCollections.listCopy(coll); } diff --git a/src/java.base/share/classes/java/util/ListIterator.java b/src/java.base/share/classes/java/util/ListIterator.java index b44e644f1d3..ec6b6e86334 100644 --- a/src/java.base/share/classes/java/util/ListIterator.java +++ b/src/java.base/share/classes/java/util/ListIterator.java @@ -31,9 +31,10 @@ import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * An iterator for lists that allows the programmer @@ -96,7 +97,8 @@ public interface ListIterator extends Iterator { * @return the next element in the list * @throws NoSuchElementException if the iteration has no next element */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E next(@GuardSatisfied @NonEmpty ListIterator this); /** @@ -123,6 +125,8 @@ public interface ListIterator extends Iterator { * @throws NoSuchElementException if the iteration has no previous * element */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E previous(@GuardSatisfied ListIterator this); /** @@ -166,6 +170,8 @@ public interface ListIterator extends Iterator { * {@code add} have been called after the last call to * {@code next} or {@code previous} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void remove(@GuardSatisfied ListIterator this); /** @@ -188,6 +194,8 @@ public interface ListIterator extends Iterator { * {@code add} have been called after the last call to * {@code next} or {@code previous} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void set(@GuardSatisfied ListIterator this, E e); /** @@ -210,5 +218,7 @@ public interface ListIterator extends Iterator { * @throws IllegalArgumentException if some aspect of this element * prevents it from being added to this list */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void add(@GuardSatisfied ListIterator this, E e); } diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 64297dd01c7..a4894dfa10a 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -45,6 +45,7 @@ import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; import org.checkerframework.framework.qual.Covariant; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.function.BiConsumer; import java.util.function.BiFunction; @@ -222,8 +223,8 @@ public interface Map { */ @CFComment("nullness: key is not @Nullable because this map might not permit null values") @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) - @EnsuresNonEmptyIf(result=true, expression={"this"}) @Pure + @EnsuresNonEmptyIf(result=true, expression={"this"}) boolean containsKey(@GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); /** @@ -242,8 +243,8 @@ public interface Map { * @throws NullPointerException if the specified value is null and this * map does not permit null values ({@linkplain Collection##optional-restrictions optional}) */ - @EnsuresNonEmptyIf(result=true, expression={"this"}) @Pure + @EnsuresNonEmptyIf(result=true, expression={"this"}) boolean containsValue(@GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object value); /** @@ -302,6 +303,8 @@ public interface Map { @ReleasesNoLocks @EnsuresKeyFor(value={"#1"}, map={"this"}) @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable V put(@GuardSatisfied Map this, K key, V value); /** @@ -333,6 +336,8 @@ public interface Map { * map does not permit null keys ({@linkplain Collection##optional-restrictions optional}) */ @CFComment("nullness: key is not @Nullable because this map might not permit null values") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable V remove(@GuardSatisfied Map this, @GuardSatisfied @UnknownSignedness Object key); @@ -359,6 +364,8 @@ public interface Map { * @throws IllegalArgumentException if some property of a key or value in * the specified map prevents it from being stored in this map */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void putAll(@GuardSatisfied Map this, Map m); /** @@ -368,6 +375,8 @@ public interface Map { * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this map */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void clear(@GuardSatisfied Map this); @@ -532,6 +541,8 @@ interface Entry { * required to, throw this exception if the entry has been * removed from the backing map. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") V setValue(Map.@GuardSatisfied Entry this, V value); /** @@ -672,6 +683,7 @@ public static Comparator> comparingByValue(Comparator Map.Entry copyOf(Map.Entry e) { Objects.requireNonNull(e); if (e instanceof KeyValueHolder) { @@ -696,6 +708,7 @@ public static Comparator> comparingByValue(Comparator this, @GuardSatisfied @Nullable Object o); /** @@ -711,6 +724,7 @@ public static Comparator> comparingByValue(Comparator this); // Defaultable methods @@ -768,6 +782,7 @@ default V getOrDefault(@GuardSatisfied @UnknownSignedness Object key, V defaultV * removed during iteration * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default void forEach(@NonLeaked BiConsumer action) { Objects.requireNonNull(action); for (Map.Entry entry : entrySet()) { @@ -818,6 +833,7 @@ default void forEach(@NonLeaked BiConsumer action) { * removed during iteration * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default void replaceAll(BiFunction function) { Objects.requireNonNull(function); for (Map.Entry entry : entrySet()) { @@ -885,6 +901,8 @@ default void replaceAll(BiFunction function) * @since 1.8 */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default @Nullable V putIfAbsent(K key, V value) { V v = get(key); if (v == null) { @@ -929,6 +947,8 @@ default void replaceAll(BiFunction function) * @since 1.8 */ @CFComment("nullness: key and value are not @Nullable because this map might not permit null values") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { Object curValue = get(key); if (!Objects.equals(curValue, value) || @@ -979,6 +999,8 @@ default boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSati * or value prevents it from being stored in this map * @since 1.8 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default boolean replace(K key, V oldValue, V newValue) { Object curValue = get(key); if (!Objects.equals(curValue, oldValue) || @@ -1027,6 +1049,8 @@ default boolean replace(K key, V oldValue, V newValue) { * or value prevents it from being stored in this map * @since 1.8 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default @Nullable V replace(K key, V value) { V curValue; if (((curValue = get(key)) != null) || containsKey(key)) { @@ -1109,6 +1133,7 @@ default boolean replace(K key, V oldValue, V newValue) { * ({@linkplain Collection##optional-restrictions optional}) * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default @PolyNull V computeIfAbsent(K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); @@ -1186,6 +1211,7 @@ default boolean replace(K key, V oldValue, V newValue) { * ({@linkplain Collection##optional-restrictions optional}) * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default @Nullable V computeIfPresent(K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1272,6 +1298,7 @@ default boolean replace(K key, V oldValue, V newValue) { * ({@linkplain Collection##optional-restrictions optional}) * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default @Nullable V compute(K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1370,6 +1397,7 @@ default boolean replace(K key, V oldValue, V newValue) { * null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") default @Nullable V merge(K key, @NonNull V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -1396,6 +1424,7 @@ default boolean replace(K key, V oldValue, V newValue) { * @since 9 */ @SuppressWarnings("unchecked") + @SideEffectFree static Map of() { return (Map) ImmutableCollections.EMPTY_MAP; } @@ -1413,6 +1442,7 @@ static Map of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Map of(K k1, V v1) { return new ImmutableCollections.Map1<>(k1, v1); } @@ -1433,6 +1463,7 @@ static Map of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Map of(K k1, V v1, K k2, V v2) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2); } @@ -1455,6 +1486,7 @@ static Map of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3); } @@ -1479,6 +1511,7 @@ static Map of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4); } @@ -1505,6 +1538,7 @@ static Map of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5); } @@ -1791,6 +1825,7 @@ static Map of() { * @since 10 */ @SuppressWarnings({"rawtypes","unchecked"}) + @SideEffectFree static @PolyNonEmpty Map copyOf(@PolyNonEmpty Map map) { if (map instanceof ImmutableCollections.AbstractImmutableMap) { return (Map)map; diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 6fd455e0255..12653e71537 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -41,6 +41,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * A {@link SortedMap} extended with navigation methods returning the @@ -251,6 +252,8 @@ public interface NavigableMap extends SortedMap { * @return the removed first entry of this map, * or {@code null} if this map is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") Map.@Nullable Entry pollFirstEntry(@GuardSatisfied NavigableMap this); /** @@ -260,6 +263,8 @@ public interface NavigableMap extends SortedMap { * @return the removed last entry of this map, * or {@code null} if this map is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") Map.@Nullable Entry pollLastEntry(@GuardSatisfied NavigableMap this); /** diff --git a/src/java.base/share/classes/java/util/NavigableSet.java b/src/java.base/share/classes/java/util/NavigableSet.java index 3bcdf187920..fd6b8d14e49 100644 --- a/src/java.base/share/classes/java/util/NavigableSet.java +++ b/src/java.base/share/classes/java/util/NavigableSet.java @@ -42,6 +42,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * A {@link SortedSet} extended with navigation methods reporting @@ -160,6 +161,8 @@ public interface NavigableSet extends SortedSet { * * @return the first element, or {@code null} if this set is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable E pollFirst(@GuardSatisfied NavigableSet this); /** @@ -168,6 +171,8 @@ public interface NavigableSet extends SortedSet { * * @return the last element, or {@code null} if this set is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable E pollLast(@GuardSatisfied NavigableSet this); /** @@ -193,6 +198,8 @@ public interface NavigableSet extends SortedSet { * * @return a reverse order view of this set */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") NavigableSet descendingSet(); /** @@ -201,6 +208,8 @@ public interface NavigableSet extends SortedSet { * * @return an iterator over the elements in this set, in descending order */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") Iterator descendingIterator(); /** @@ -349,6 +358,8 @@ NavigableSet subSet(@GuardSatisfied NavigableSet this, @GuardSatisfied E f * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default E removeFirst() { if (this.isEmpty()) { throw new NoSuchElementException(); @@ -368,6 +379,8 @@ default E removeFirst() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default E removeLast() { if (this.isEmpty()) { throw new NoSuchElementException(); @@ -388,6 +401,8 @@ default E removeLast() { * @return a reverse-ordered view of this collection, as a {@code NavigableSet} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default NavigableSet reversed() { return this.descendingSet(); } diff --git a/src/java.base/share/classes/java/util/Objects.java b/src/java.base/share/classes/java/util/Objects.java index 9544c1cce49..c33b12a0604 100644 --- a/src/java.base/share/classes/java/util/Objects.java +++ b/src/java.base/share/classes/java/util/Objects.java @@ -301,8 +301,8 @@ public static int compare(@GuardSatisfied @Nullable @UnknownSignedness T a, * @see java.util.function.Predicate * @since 1.8 */ - @EnsuresNonNullIf(expression={"#1"}, result=false) @Pure + @EnsuresNonNullIf(expression={"#1"}, result=false) public static boolean isNull(@GuardSatisfied @Nullable @UnknownSignedness Object obj) { return obj == null; } @@ -321,8 +321,8 @@ public static boolean isNull(@GuardSatisfied @Nullable @UnknownSignedness Object * @see java.util.function.Predicate * @since 1.8 */ - @EnsuresNonNullIf(expression={"#1"}, result=true) @Pure + @EnsuresNonNullIf(expression={"#1"}, result=true) public static boolean nonNull(@GuardSatisfied @Nullable @UnknownSignedness Object obj) { return obj != null; } @@ -385,8 +385,8 @@ public static boolean nonNull(@GuardSatisfied @Nullable @UnknownSignedness Objec * @throws NullPointerException if {@code obj} is {@code null} * @since 1.8 */ - @EnsuresNonNull("#1") @Pure + @EnsuresNonNull("#1") public static @NonNull T requireNonNull(@GuardSatisfied @NonNull @UnknownSignedness T obj, @GuardSatisfied Supplier messageSupplier) { if (obj == null) throw new NullPointerException(messageSupplier == null ? diff --git a/src/java.base/share/classes/java/util/PrimitiveIterator.java b/src/java.base/share/classes/java/util/PrimitiveIterator.java index ed9efa28db2..61ead18c699 100644 --- a/src/java.base/share/classes/java/util/PrimitiveIterator.java +++ b/src/java.base/share/classes/java/util/PrimitiveIterator.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.function.Consumer; import java.util.function.DoubleConsumer; @@ -90,6 +91,7 @@ public interface PrimitiveIterator extends Iterator { * @throws NullPointerException if the specified action is null */ @SuppressWarnings("overloads") + @DoesNotUnrefineReceiver("modifiability") void forEachRemaining(T_CONS action); /** @@ -105,6 +107,8 @@ public static interface OfInt extends PrimitiveIterator { * @return the next {@code int} element in the iteration * @throws NoSuchElementException if the iteration has no more elements */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") int nextInt(@NonEmpty OfInt this); /** @@ -116,6 +120,7 @@ public static interface OfInt extends PrimitiveIterator { * action.accept(nextInt()); * } */ + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(IntConsumer action) { Objects.requireNonNull(action); while (hasNext()) @@ -129,6 +134,8 @@ default void forEachRemaining(IntConsumer action) { * {@link #nextInt()}, and returns that boxed result. */ @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default Integer next(PrimitiveIterator.@GuardSatisfied OfInt this) { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.nextInt()"); @@ -145,6 +152,7 @@ default Integer next(PrimitiveIterator.@GuardSatisfied OfInt this) { * and then passed to {@link #forEachRemaining}. */ @Override + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(Consumer action) { if (action instanceof IntConsumer) { forEachRemaining((IntConsumer) action); @@ -173,6 +181,8 @@ public static interface OfLong extends PrimitiveIterator { * @return the next {@code long} element in the iteration * @throws NoSuchElementException if the iteration has no more elements */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") long nextLong(@NonEmpty OfLong this); /** @@ -184,6 +194,7 @@ public static interface OfLong extends PrimitiveIterator { * action.accept(nextLong()); * } */ + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(LongConsumer action) { Objects.requireNonNull(action); while (hasNext()) @@ -197,6 +208,8 @@ default void forEachRemaining(LongConsumer action) { * {@link #nextLong()}, and returns that boxed result. */ @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default Long next(PrimitiveIterator.@GuardSatisfied OfLong this) { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.nextLong()"); @@ -213,6 +226,7 @@ default Long next(PrimitiveIterator.@GuardSatisfied OfLong this) { * and then passed to {@link #forEachRemaining}. */ @Override + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(Consumer action) { if (action instanceof LongConsumer) { forEachRemaining((LongConsumer) action); @@ -240,6 +254,8 @@ public static interface OfDouble extends PrimitiveIterator */ + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(DoubleConsumer action) { Objects.requireNonNull(action); while (hasNext()) @@ -264,6 +281,8 @@ default void forEachRemaining(DoubleConsumer action) { * {@link #nextDouble()}, and returns that boxed result. */ @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default Double next(PrimitiveIterator.@GuardSatisfied OfDouble this) { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.nextLong()"); @@ -281,6 +300,7 @@ default Double next(PrimitiveIterator.@GuardSatisfied OfDouble this) { * {@link #forEachRemaining}. */ @Override + @DoesNotUnrefineReceiver("modifiability") default void forEachRemaining(Consumer action) { if (action instanceof DoubleConsumer) { forEachRemaining((DoubleConsumer) action); diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index 4222f19858b..b972e27762c 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -41,9 +41,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.function.Consumer; import java.util.function.Predicate; @@ -330,6 +331,8 @@ private void grow(int minCapacity) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@GuardSatisfied PriorityQueue this, E e) { return offer(e); } @@ -343,6 +346,8 @@ public boolean add(@GuardSatisfied PriorityQueue this, E e) { * according to the priority queue's ordering * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { if (e == null) throw new NullPointerException(); @@ -360,6 +365,7 @@ public boolean offer(E e) { return (E) queue[0]; } + @Pure private int indexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o != null) { final Object[] es = queue; @@ -381,6 +387,8 @@ private int indexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @CanShrink PriorityQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { int i = indexOf(o); if (i == -1) @@ -474,7 +482,6 @@ public boolean contains(@GuardSatisfied PriorityQueue this, @GuardSatisfied @ * this queue * @throws NullPointerException if the specified array is null */ - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { final int size = this.size; if (a.length < size) @@ -546,7 +553,8 @@ public boolean hasNext() { (forgetMeNot != null && !forgetMeNot.isEmpty()); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty Itr this) { if (expectedModCount != modCount) throw new ConcurrentModificationException(); @@ -561,6 +569,8 @@ public E next(@NonEmpty Itr this) { throw new NoSuchElementException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (expectedModCount != modCount) throw new ConcurrentModificationException(); @@ -593,6 +603,8 @@ public void remove() { * Removes all of the elements from this priority queue. * The queue will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink PriorityQueue this) { modCount++; final Object[] es = queue; @@ -601,6 +613,8 @@ public void clear(@GuardSatisfied @CanShrink PriorityQueue this) { size = 0; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink PriorityQueue this) { final Object[] es; final E result; @@ -849,6 +863,7 @@ private void readObject(java.io.ObjectInputStream s) * @return a {@code Spliterator} over the elements in this queue * @since 1.8 */ + @SideEffectFree public final Spliterator spliterator() { return new PriorityQueueSpliterator(0, -1, 0); } @@ -924,6 +939,8 @@ public int characteristics() { /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@GuardSatisfied @CanShrink PriorityQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -932,6 +949,8 @@ public boolean removeIf(@GuardSatisfied @CanShrink PriorityQueue this, Predic /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@GuardSatisfied @CanShrink PriorityQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -940,6 +959,8 @@ public boolean removeAll(@GuardSatisfied @CanShrink PriorityQueue this, Colle /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(@GuardSatisfied @CanShrink PriorityQueue this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); @@ -995,6 +1016,7 @@ private boolean bulkRemove(Predicate filter) { /** * @throws NullPointerException {@inheritDoc} */ + @DoesNotUnrefineReceiver("modifiability") public void forEach(Consumer action) { Objects.requireNonNull(action); final int expectedModCount = modCount; diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index a25c6f4be6f..c6bd98b91b8 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -35,6 +35,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.IOException; import java.io.PrintStream; @@ -238,6 +239,8 @@ private Properties(Properties defaults, int initialCapacity) { * @see #getProperty * @since 1.2 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized @Nullable Object setProperty(@GuardSatisfied Properties this, @PropertyKey String key, String value) { return put(key, value); } @@ -1327,12 +1330,14 @@ public boolean isEmpty() { } @Override + @SideEffectFree public Enumeration keys() { // CHM.keys() returns Iterator w/ remove() - instead wrap keySet() return Collections.enumeration(map.keySet()); } @Override + @SideEffectFree public Enumeration elements() { // CHM.elements() returns Iterator w/ remove() - instead wrap values() return Collections.enumeration(map.values()); @@ -1358,41 +1363,53 @@ public boolean containsKey(@GuardSatisfied @Nullable @UnknownSignedness Object k } @Override + @Pure public @Nullable Object get(Object key) { return map.get(key); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized Object put(Object key, Object value) { return map.put(key, value); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized Object remove(@GuardSatisfied @Nullable @UnknownSignedness Object key) { return map.remove(key); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized void putAll(Map t) { map.putAll(t); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized void clear() { map.clear(); } @Override + @SideEffectFree public synchronized String toString() { return map.toString(); } @Override + @SideEffectFree public Set<@KeyFor("this") Object> keySet() { return Collections.synchronizedSet(map.keySet(), this); } @Override + @SideEffectFree public Collection values() { return Collections.synchronizedCollection(map.values(), this); } @@ -1415,16 +1432,22 @@ private EntrySet(Set> entrySet) { this.entrySet = entrySet; } - @Pure @Override public int size() { return entrySet.size(); } + @Pure + @Override public int size() { return entrySet.size(); } @Pure @EnsuresNonEmptyIf(result = false, expression = "this") @Override public boolean isEmpty() { return entrySet.isEmpty(); } @Pure @EnsuresNonEmptyIf(result = true, expression = "this") @Override public boolean contains(@UnknownSignedness Object o) { return entrySet.contains(o); } + @SideEffectFree @Override public Object[] toArray() { return entrySet.toArray(); } @Override public @Nullable T[] toArray(@PolyNull T[] a) { return entrySet.toArray(a); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Override public void clear() { entrySet.clear(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Override public boolean remove(@UnknownSignedness Object o) { return entrySet.remove(o); } @Override @@ -1444,42 +1467,52 @@ public boolean containsAll(Collection c) { } @Override + @Pure public boolean equals(Object o) { return o == this || entrySet.equals(o); } @Override + @Pure public int hashCode() { return entrySet.hashCode(); } @Override + @SideEffectFree public String toString() { return entrySet.toString(); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return entrySet.removeAll(c); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { return entrySet.retainAll(c); } @Override + @SideEffectFree public Iterator> iterator() { return entrySet.iterator(); } } @Override + @Pure public synchronized boolean equals(Object o) { return map.equals(o); } @Override + @Pure public synchronized int hashCode() { return map.hashCode(); } @@ -1491,54 +1524,68 @@ public Object getOrDefault(@GuardSatisfied @Nullable @UnknownSignedness Object k } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void forEach(BiConsumer action) { map.forEach(action); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void replaceAll(BiFunction function) { map.replaceAll(function); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized Object putIfAbsent(Object key, Object value) { return map.putIfAbsent(key, value); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object key, @GuardSatisfied @Nullable @UnknownSignedness Object value) { return map.remove(key, value); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean replace(Object key, Object oldValue, Object newValue) { return map.replace(key, oldValue, newValue); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized Object replace(Object key, Object value) { return map.replace(key, value); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull Object computeIfAbsent(Object key, Function mappingFunction) { return map.computeIfAbsent(key, mappingFunction); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull Object computeIfPresent(Object key, BiFunction remappingFunction) { return map.computeIfPresent(key, remappingFunction); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @PolyNull Object compute(Object key, BiFunction remappingFunction) { return map.compute(key, remappingFunction); } @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized @Nullable Object merge(Object key, Object value, BiFunction remappingFunction) { return map.merge(key, value, remappingFunction); @@ -1551,6 +1598,7 @@ public synchronized Object replace(Object key, Object value) { protected void rehash() { /* no-op */ } @Override + @SideEffectFree public synchronized Object clone() { Properties clone = (Properties) cloneHashtable(); clone.map = new ConcurrentHashMap<>(map); diff --git a/src/java.base/share/classes/java/util/Queue.java b/src/java.base/share/classes/java/util/Queue.java index 056c4488001..c3051c1b748 100644 --- a/src/java.base/share/classes/java/util/Queue.java +++ b/src/java.base/share/classes/java/util/Queue.java @@ -44,6 +44,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * A collection designed for holding elements prior to processing. @@ -166,6 +167,8 @@ public interface Queue extends Collection { * prevents it from being added to this queue */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean add(@GuardSatisfied Queue this, E e); /** @@ -185,6 +188,8 @@ public interface Queue extends Collection { * @throws IllegalArgumentException if some property of this element * prevents it from being added to this queue */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offer(E e); /** @@ -195,6 +200,8 @@ public interface Queue extends Collection { * @return the head of this queue * @throws NoSuchElementException if this queue is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E remove(@GuardSatisfied @NonEmpty @CanShrink Queue this); /** @@ -203,6 +210,8 @@ public interface Queue extends Collection { * * @return the head of this queue, or {@code null} if this queue is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable E poll(@GuardSatisfied @CanShrink Queue this); /** @@ -213,6 +222,7 @@ public interface Queue extends Collection { * @return the head of this queue * @throws NoSuchElementException if this queue is empty */ + @Pure E element(@GuardSatisfied @NonEmpty Queue this); /** @@ -221,5 +231,8 @@ public interface Queue extends Collection { * * @return the head of this queue, or {@code null} if this queue is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @Pure @Nullable E peek(); } diff --git a/src/java.base/share/classes/java/util/RegularEnumSet.java b/src/java.base/share/classes/java/util/RegularEnumSet.java index a898d1090df..353c772665b 100644 --- a/src/java.base/share/classes/java/util/RegularEnumSet.java +++ b/src/java.base/share/classes/java/util/RegularEnumSet.java @@ -38,8 +38,9 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * Private implementation class for EnumSet, for "regular sized" enum types @@ -63,15 +64,21 @@ final class RegularEnumSet> extends EnumSet { super(elementType, universe); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void addRange(E from, E to) { elements = (-1L >>> (from.ordinal() - to.ordinal() - 1)) << from.ordinal(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void addAll() { if (universe.length != 0) elements = -1L >>> -universe.length; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void complement() { if (universe.length != 0) { elements = ~elements; @@ -89,6 +96,8 @@ void complement() { * * @return an iterator over the elements contained in this set */ + @DoesNotUnrefineReceiver("modifiability") + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty RegularEnumSet this) { return new EnumSetIterator<>(); } @@ -116,7 +125,8 @@ public boolean hasNext() { return unseen != 0; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @SuppressWarnings("unchecked") public E next(@NonEmpty EnumSetIterator this) { if (unseen == 0) @@ -126,6 +136,8 @@ public E next(@NonEmpty EnumSetIterator this) { return (E) universe[Long.numberOfTrailingZeros(lastReturned)]; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastReturned == 0) throw new IllegalStateException(); @@ -184,6 +196,8 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object e) { * @throws NullPointerException if {@code e} is null */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { typeCheck(e); @@ -198,6 +212,8 @@ public boolean add(E e) { * @param e element to be removed from this set, if present * @return {@code true} if the set contained the specified element */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object e) { if (e == null) return false; @@ -240,6 +256,8 @@ public boolean containsAll(Collection c) { * @throws NullPointerException if the specified collection or any * of its elements are null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { if (!(c instanceof RegularEnumSet es)) return super.addAll(c); @@ -265,6 +283,8 @@ public boolean addAll(Collection c) { * @return {@code true} if this set changed as a result of the call * @throws NullPointerException if the specified collection is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { if (!(c instanceof RegularEnumSet es)) return super.removeAll(c); @@ -285,6 +305,8 @@ public boolean removeAll(Collection c) { * @return {@code true} if this set changed as a result of the call * @throws NullPointerException if the specified collection is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { if (!(c instanceof RegularEnumSet es)) return super.retainAll(c); @@ -303,6 +325,8 @@ public boolean retainAll(Collection c) { /** * Removes all of the elements from this set. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { elements = 0; } diff --git a/src/java.base/share/classes/java/util/ReverseOrderDequeView.java b/src/java.base/share/classes/java/util/ReverseOrderDequeView.java index 695db6a74dc..eb419d87feb 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderDequeView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderDequeView.java @@ -25,11 +25,14 @@ package java.util; +import org.checkerframework.dataflow.qual.SideEffectFree; + import java.util.function.Consumer; import java.util.function.IntFunction; import java.util.stream.Stream; import java.util.stream.StreamSupport; import jdk.internal.util.ArraysSupport; +import org.checkerframework.dataflow.qual.Pure; /** * Provides a reverse-ordered view of any Deque. Not serializable. @@ -41,6 +44,7 @@ private ReverseOrderDequeView(Deque deque) { base = deque; } + @SideEffectFree public static Deque of(Deque deque) { if (deque instanceof ReverseOrderDequeView rodv) { return rodv.base; @@ -56,10 +60,12 @@ public void forEach(Consumer action) { action.accept(e); } + @SideEffectFree public Iterator iterator() { return base.descendingIterator(); } + @SideEffectFree public Spliterator spliterator() { return Spliterators.spliterator(this, Spliterator.ORDERED); } @@ -84,14 +90,17 @@ public void clear() { base.clear(); } + @Pure public boolean contains(Object o) { return base.contains(o); } + @Pure public boolean containsAll(Collection c) { return base.containsAll(c); } + @Pure public boolean isEmpty() { return base.isEmpty(); } @@ -149,6 +158,7 @@ public boolean retainAll(Collection c) { return modified; } + @Pure public int size() { return base.size(); } @@ -157,6 +167,7 @@ public Stream stream() { return StreamSupport.stream(spliterator(), false); } + @SideEffectFree public Object[] toArray() { return ArraysSupport.reverse(base.toArray()); } @@ -170,6 +181,7 @@ public T[] toArray(IntFunction generator) { return ArraysSupport.reverse(base.toArray(generator)); } + @SideEffectFree // copied from AbstractCollection public String toString() { Iterator it = iterator(); @@ -201,14 +213,17 @@ public Iterator descendingIterator() { return base.iterator(); } + @Pure public E element() { return base.getLast(); } + @Pure public E getFirst() { return base.getLast(); } + @Pure public E getLast() { return base.getFirst(); } @@ -225,14 +240,17 @@ public boolean offerLast(E e) { return base.offerFirst(e); } + @Pure public E peek() { return base.peekLast(); } + @Pure public E peekFirst() { return base.peekLast(); } + @Pure public E peekLast() { return base.peekFirst(); } diff --git a/src/java.base/share/classes/java/util/ReverseOrderListView.java b/src/java.base/share/classes/java/util/ReverseOrderListView.java index 42b57e2d8b9..b8ad70a665f 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderListView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderListView.java @@ -25,6 +25,10 @@ package java.util; +import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.dataflow.qual.SideEffectFree; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; + import java.util.Objects; import java.util.function.Consumer; import java.util.function.IntFunction; @@ -42,6 +46,7 @@ class ReverseOrderListView implements List { final List base; final boolean modifiable; + @SideEffectFree public static List of(List list, boolean modifiable) { if (list instanceof ReverseOrderListView rolv) { return rolv.base; @@ -80,6 +85,7 @@ void checkModifiable() { class DescendingIterator implements Iterator { final ListIterator it = base.listIterator(base.size()); + @Pure public boolean hasNext() { return it.hasPrevious(); } public E next() { return it.previous(); } public void remove() { @@ -98,6 +104,7 @@ class DescendingListIterator implements ListIterator { it = base.listIterator(size - pos); } + @Pure public boolean hasNext() { return it.hasPrevious(); } @@ -106,6 +113,7 @@ public E next() { return it.previous(); } + @Pure public boolean hasPrevious() { return it.hasNext(); } @@ -114,10 +122,12 @@ public E previous() { return it.next(); } + @Pure public int nextIndex() { return base.size() - it.nextIndex(); } + @Pure public int previousIndex() { return nextIndex() - 1; } @@ -146,10 +156,12 @@ public void forEach(Consumer action) { action.accept(e); } + @SideEffectFree public Iterator iterator() { return new DescendingIterator(); } + @SideEffectFree public Spliterator spliterator() { return Spliterators.spliterator(this, Spliterator.ORDERED); } @@ -180,15 +192,18 @@ public void clear() { base.clear(); } + @Pure public boolean contains(Object o) { return base.contains(o); } + @Pure public boolean containsAll(Collection c) { return base.containsAll(c); } // copied from AbstractList + @Pure public boolean equals(Object o) { if (o == this) return true; @@ -207,6 +222,7 @@ public boolean equals(Object o) { } // copied from AbstractList + @Pure public int hashCode() { int hashCode = 1; for (E e : this) @@ -214,6 +230,7 @@ public int hashCode() { return hashCode; } + @Pure public boolean isEmpty() { return base.isEmpty(); } @@ -274,6 +291,7 @@ public boolean retainAll(Collection c) { return modified; } + @Pure public int size() { return base.size(); } @@ -282,6 +300,7 @@ public Stream stream() { return StreamSupport.stream(spliterator(), false); } + @SideEffectFree public Object[] toArray() { return ArraysSupport.reverse(base.toArray()); } @@ -296,6 +315,7 @@ public T[] toArray(IntFunction generator) { } // copied from AbstractCollection + @SideEffectFree public String toString() { Iterator it = iterator(); if (! it.hasNext()) @@ -335,17 +355,20 @@ public boolean addAll(int index, Collection c) { } } + @Pure public E get(int i) { int size = base.size(); Objects.checkIndex(i, size); return base.get(size - i - 1); } + @Pure public int indexOf(Object o) { int i = base.lastIndexOf(o); return i == -1 ? -1 : base.size() - i - 1; } + @Pure public int lastIndexOf(Object o) { int i = base.indexOf(o); return i == -1 ? -1 : base.size() - i - 1; @@ -373,6 +396,7 @@ public boolean removeIf(Predicate filter) { return base.removeIf(filter); } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { checkModifiable(); base.replaceAll(operator); @@ -390,6 +414,7 @@ public E set(int index, E element) { return base.set(size - index - 1, element); } + @SideEffectFree public List subList(int fromIndex, int toIndex) { int size = base.size(); Objects.checkFromToIndex(fromIndex, toIndex, size); diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java index 404950e8fd5..ffef3f2a837 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -25,6 +25,9 @@ package java.util; +import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.dataflow.qual.SideEffectFree; + /** * Provides a reversed-ordered view of a SortedMap. Not serializable. * @@ -39,6 +42,7 @@ private ReverseOrderSortedMapView(SortedMap map) { cmp = Collections.reverseOrder(map.comparator()); } + @SideEffectFree public static SortedMap of(SortedMap map) { if (map instanceof ReverseOrderSortedMapView rosmv) { return rosmv.base; @@ -53,6 +57,7 @@ public static SortedMap of(SortedMap map) { // hashCode: inherited from AbstractMap + @SideEffectFree public String toString() { return toString(this, descendingEntryIterator(base)); } @@ -63,18 +68,22 @@ public void clear() { base.clear(); } + @Pure public boolean containsKey(Object key) { return base.containsKey(key); } + @Pure public boolean containsValue(Object value) { return base.containsValue(value); } + @Pure public V get(Object key) { return base.get(key); } + @Pure public boolean isEmpty() { return base.isEmpty(); } @@ -91,38 +100,51 @@ public V remove(Object key) { return base.remove(key); } + @Pure public int size() { return base.size(); } + @SideEffectFree public Set keySet() { return new AbstractSet<>() { // inherit add(), which throws UOE + @SideEffectFree public Iterator iterator() { return descendingKeyIterator(base); } + @Pure public int size() { return base.size(); } public void clear() { base.keySet().clear(); } + @Pure public boolean contains(Object o) { return base.keySet().contains(o); } public boolean remove(Object o) { return base.keySet().remove(o); } }; } + @SideEffectFree public Collection values() { return new AbstractCollection<>() { // inherit add(), which throws UOE + @SideEffectFree public Iterator iterator() { return descendingValueIterator(base); } + @Pure public int size() { return base.size(); } public void clear() { base.values().clear(); } + @Pure public boolean contains(Object o) { return base.values().contains(o); } public boolean remove(Object o) { return base.values().remove(o); } }; } + @SideEffectFree public Set> entrySet() { return new AbstractSet<>() { // inherit add(), which throws UOE + @SideEffectFree public Iterator> iterator() { return descendingEntryIterator(base); } + @Pure public int size() { return base.size(); } public void clear() { base.entrySet().clear(); } + @Pure public boolean contains(Object o) { return base.entrySet().contains(o); } public boolean remove(Object o) { return base.entrySet().remove(o); } }; @@ -168,10 +190,12 @@ public V putLast(K k, V v) { // ========== SortedMap ========== + @Pure public Comparator comparator() { return cmp; } + @SideEffectFree public SortedMap subMap(K fromKey, K toKey) { if (cmp.compare(fromKey, toKey) <= 0) { return new Submap(fromKey, toKey); @@ -180,10 +204,12 @@ public SortedMap subMap(K fromKey, K toKey) { } } + @SideEffectFree public SortedMap headMap(K toKey) { return new Submap(null, toKey); } + @SideEffectFree public SortedMap tailMap(K fromKey) { return new Submap(fromKey, null); } @@ -196,6 +222,7 @@ static Iterator descendingKeyIterator(SortedMap map) { SortedMap view = map; K prev = null; + @Pure public boolean hasNext() { return ! view.isEmpty(); } @@ -223,6 +250,7 @@ static Iterator descendingValueIterator(SortedMap map) { return new Iterator<>() { Iterator keyIterator = descendingKeyIterator(map); + @Pure public boolean hasNext() { return keyIterator.hasNext(); } @@ -241,6 +269,7 @@ static Iterator> descendingEntryIterator(SortedMap return new Iterator<>() { Iterator keyIterator = descendingKeyIterator(map); + @Pure public boolean hasNext() { return keyIterator.hasNext(); } @@ -267,26 +296,32 @@ static class ViewEntry implements Map.Entry { this.value = value; } + @Pure public K getKey() { return key; } + @Pure public V getValue() { return value; } public V setValue(V newValue) { return map.put(key, newValue); } + @Pure public boolean equals(Object o) { return o instanceof Map.Entry e && Objects.equals(key, e.getKey()) && Objects.equals(value, e.getValue()); } + @Pure public int hashCode() { return Objects.hashCode(key) ^ Objects.hashCode(value); } + @SideEffectFree public String toString() { return key + "=" + value; } } // copied and modified from AbstractMap + @SideEffectFree static String toString(Map thisMap, Iterator> i) { if (! i.hasNext()) return "{}"; @@ -337,6 +372,7 @@ Iterator> entryIterator() { boolean dead = false; Iterator> it = descendingEntryIterator(base); + @Pure public boolean hasNext() { if (dead) return false; @@ -387,16 +423,20 @@ public void remove() { // hashCode: inherited from AbstractMap + @SideEffectFree public String toString() { return ReverseOrderSortedMapView.toString(this, entryIterator()); } + @SideEffectFree public Set> entrySet() { return new AbstractSet<>() { + @SideEffectFree public Iterator> iterator() { return entryIterator(); } + @Pure public int size() { int sz = 0; for (var it = entryIterator(); it.hasNext();) { @@ -424,10 +464,12 @@ public V remove(Object o) { return null; } + @Pure public int size() { return entrySet().size(); } + @Pure public Comparator comparator() { return cmp; } @@ -446,6 +488,7 @@ public K lastKey() { return last.getKey(); } + @SideEffectFree public SortedMap subMap(K from, K to) { if (aboveHead(from) && belowTail(from) && aboveHead(to) && belowTail(to) && @@ -456,6 +499,7 @@ public SortedMap subMap(K from, K to) { } } + @SideEffectFree public SortedMap headMap(K to) { if (aboveHead(to) && belowTail(to)) return new Submap(head, to); @@ -463,6 +507,7 @@ public SortedMap headMap(K to) { throw new IllegalArgumentException(); } + @SideEffectFree public SortedMap tailMap(K from) { if (aboveHead(from) && belowTail(from)) return new Submap(from, tail); diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java index 3719852e2a5..24b08c1099e 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java @@ -25,11 +25,14 @@ package java.util; +import org.checkerframework.dataflow.qual.SideEffectFree; + import java.util.function.Consumer; import java.util.function.IntFunction; import java.util.stream.Stream; import java.util.stream.StreamSupport; import jdk.internal.util.ArraysSupport; +import org.checkerframework.dataflow.qual.Pure; /** * Provides a reversed-ordered view of a SortedSet. Not serializable. @@ -43,6 +46,7 @@ private ReverseOrderSortedSetView(SortedSet set) { comp = Collections.reverseOrder(set.comparator()); } + @SideEffectFree public static SortedSet of(SortedSet set) { if (set instanceof ReverseOrderSortedSetView rossv) { return rossv.base; @@ -54,6 +58,7 @@ public static SortedSet of(SortedSet set) { // ========== Object ========== // copied from AbstractSet + @Pure public boolean equals(Object o) { if (o == this) return true; @@ -71,6 +76,7 @@ public boolean equals(Object o) { } // copied from AbstractSet + @Pure public int hashCode() { int h = 0; Iterator i = iterator(); @@ -83,6 +89,7 @@ public int hashCode() { } // copied from AbstractCollection + @SideEffectFree public String toString() { Iterator it = iterator(); if (! it.hasNext()) @@ -106,10 +113,12 @@ public void forEach(Consumer action) { action.accept(e); } + @SideEffectFree public Iterator iterator() { return descendingIterator(base); } + @SideEffectFree public Spliterator spliterator() { return Spliterators.spliterator(this, Spliterator.ORDERED); } @@ -129,14 +138,17 @@ public void clear() { base.clear(); } + @Pure public boolean contains(Object o) { return base.contains(o); } + @Pure public boolean containsAll(Collection c) { return base.containsAll(c); } + @Pure public boolean isEmpty() { return base.isEmpty(); } @@ -158,6 +170,7 @@ public boolean retainAll(Collection c) { return base.retainAll(c); } + @Pure public int size() { return base.size(); } @@ -166,6 +179,7 @@ public Stream stream() { return StreamSupport.stream(spliterator(), false); } + @SideEffectFree public Object[] toArray() { return ArraysSupport.reverse(base.toArray()); } @@ -181,6 +195,7 @@ public T[] toArray(IntFunction generator) { // ========== SortedSet ========== + @Pure public Comparator comparator() { return comp; } @@ -189,14 +204,17 @@ public Comparator comparator() { public E last() { return base.first(); } + @SideEffectFree public SortedSet headSet(E to) { return new Subset(null, to); } + @SideEffectFree public SortedSet subSet(E from, E to) { return new Subset(from, to); } + @SideEffectFree public SortedSet tailSet(E from) { return new Subset(from, null); } @@ -209,6 +227,7 @@ static Iterator descendingIterator(SortedSet set) { SortedSet view = set; T prev = null; + @Pure public boolean hasNext() { return ! view.isEmpty(); } @@ -261,12 +280,14 @@ boolean belowTail(E e) { return tail == null || cmp.compare(e, tail) < 0; } + @SideEffectFree public Iterator iterator() { return new Iterator<>() { E cache = null; boolean dead = false; Iterator it = descendingIterator(base); + @Pure public boolean hasNext() { if (dead) return false; @@ -320,6 +341,7 @@ public boolean remove(Object o) { return false; } + @Pure public int size() { int sz = 0; for (E e : this) @@ -327,14 +349,17 @@ public int size() { return sz; } + @Pure public Comparator comparator() { return ReverseOrderSortedSetView.this.comparator(); } + @SideEffectFree public E first() { return this.iterator().next(); } + @SideEffectFree public E last() { var it = this.iterator(); if (! it.hasNext()) @@ -345,6 +370,7 @@ public E last() { return last; } + @SideEffectFree public SortedSet subSet(E from, E to) { if (aboveHead(from) && belowTail(from) && aboveHead(to) && belowTail(to) && @@ -355,6 +381,7 @@ public SortedSet subSet(E from, E to) { } } + @SideEffectFree public SortedSet headSet(E to) { if (aboveHead(to) && belowTail(to)) return ReverseOrderSortedSetView.this.new Subset(head, to); @@ -362,6 +389,7 @@ public SortedSet headSet(E to) { throw new IllegalArgumentException(); } + @SideEffectFree public SortedSet tailSet(E from) { if (aboveHead(from) && belowTail(from)) return ReverseOrderSortedSetView.this.new Subset(null, tail); diff --git a/src/java.base/share/classes/java/util/Scanner.java b/src/java.base/share/classes/java/util/Scanner.java index bf688f497b5..2d030b46712 100644 --- a/src/java.base/share/classes/java/util/Scanner.java +++ b/src/java.base/share/classes/java/util/Scanner.java @@ -39,8 +39,9 @@ import org.checkerframework.common.value.qual.IntRange; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.*; import java.math.*; @@ -1490,7 +1491,8 @@ public boolean hasNext(@GuardSatisfied Scanner this) { * @throws IllegalStateException if this scanner is closed * @see java.util.Iterator */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public String next(@GuardSatisfied @NonEmpty Scanner this) { ensureOpen(); clearCaches(); @@ -1516,6 +1518,8 @@ public String next(@GuardSatisfied @NonEmpty Scanner this) { * @throws UnsupportedOperationException if this method is invoked. * @see java.util.Iterator */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove(@GuardSatisfied Scanner this) { throw new UnsupportedOperationException(); } @@ -1553,7 +1557,8 @@ public boolean hasNext(@GuardSatisfied Scanner this, String pattern) { * @throws NoSuchElementException if no such tokens are available * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public String next(@GuardSatisfied @NonEmpty Scanner this, String pattern) { return next(patternCache.forName(pattern)); } @@ -1604,7 +1609,8 @@ public boolean hasNext(@GuardSatisfied Scanner this, Pattern pattern) { * @throws NoSuchElementException if no more tokens are available * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public String next(@GuardSatisfied @NonEmpty Scanner this, Pattern pattern) { ensureOpen(); if (pattern == null) @@ -1678,7 +1684,7 @@ public boolean hasNextLine() { * @throws NoSuchElementException if no line was found * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public String nextLine(@GuardSatisfied @NonEmpty Scanner this) { modCount++; if (hasNextPattern == linePattern()) @@ -1928,7 +1934,7 @@ public boolean hasNextBoolean(@GuardSatisfied Scanner this) { * @throws NoSuchElementException if input is exhausted * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public boolean nextBoolean(@GuardSatisfied @NonEmpty Scanner this) { clearCaches(); return Boolean.parseBoolean(next(boolPattern())); @@ -1995,7 +2001,7 @@ public boolean hasNextByte(@GuardSatisfied Scanner this, @Positive @IntRange(fro * @throws NoSuchElementException if input is exhausted * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public @PolySigned byte nextByte(@GuardSatisfied @NonEmpty Scanner this) { return nextByte(defaultRadix); } @@ -2031,7 +2037,7 @@ public boolean hasNextByte(@GuardSatisfied Scanner this, @Positive @IntRange(fro * @throws IllegalStateException if this scanner is closed * @throws IllegalArgumentException if the radix is out of range */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public @PolySigned byte nextByte(@GuardSatisfied @NonEmpty Scanner this, @Positive @IntRange(from = 2, to = 36) int radix) { // Check cached result if ((typeCache != null) && (typeCache instanceof Byte) @@ -2115,7 +2121,7 @@ public boolean hasNextShort(@GuardSatisfied Scanner this, @Positive @IntRange(fr * @throws NoSuchElementException if input is exhausted * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public @PolySigned short nextShort(@GuardSatisfied @NonEmpty Scanner this) { return nextShort(defaultRadix); } @@ -2151,7 +2157,7 @@ public boolean hasNextShort(@GuardSatisfied Scanner this, @Positive @IntRange(fr * @throws IllegalStateException if this scanner is closed * @throws IllegalArgumentException if the radix is out of range */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public @PolySigned short nextShort(@GuardSatisfied @NonEmpty Scanner this, @Positive @IntRange(from = 2, to = 36) int radix) { // Check cached result if ((typeCache != null) && (typeCache instanceof Short) @@ -2259,7 +2265,7 @@ private String processIntegerToken(String token) { * @throws NoSuchElementException if input is exhausted * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public @PolySigned int nextInt(@GuardSatisfied @NonEmpty Scanner this) { return nextInt(defaultRadix); } @@ -2295,7 +2301,7 @@ private String processIntegerToken(String token) { * @throws IllegalStateException if this scanner is closed * @throws IllegalArgumentException if the radix is out of range */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public @PolySigned int nextInt(@GuardSatisfied @NonEmpty Scanner this, @Positive @IntRange(from = 2, to = 36) int radix) { // Check cached result if ((typeCache != null) && (typeCache instanceof Integer) @@ -2379,7 +2385,7 @@ public boolean hasNextLong(@GuardSatisfied Scanner this, @Positive @IntRange(fro * @throws NoSuchElementException if input is exhausted * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public @PolySigned long nextLong(@GuardSatisfied @NonEmpty Scanner this) { return nextLong(defaultRadix); } @@ -2415,7 +2421,7 @@ public boolean hasNextLong(@GuardSatisfied Scanner this, @Positive @IntRange(fro * @throws IllegalStateException if this scanner is closed * @throws IllegalArgumentException if the radix is out of range */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public @PolySigned long nextLong(@GuardSatisfied @NonEmpty Scanner this, @Positive @IntRange(from = 2, to = 36) int radix) { // Check cached result if ((typeCache != null) && (typeCache instanceof Long) @@ -2541,7 +2547,7 @@ public boolean hasNextFloat(@GuardSatisfied Scanner this) { * @throws NoSuchElementException if input is exhausted * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public float nextFloat(@GuardSatisfied @NonEmpty Scanner this) { // Check cached result if ((typeCache != null) && (typeCache instanceof Float)) { @@ -2610,7 +2616,7 @@ public boolean hasNextDouble(@GuardSatisfied Scanner this) { * @throws NoSuchElementException if the input is exhausted * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public double nextDouble(@GuardSatisfied @NonEmpty Scanner this) { // Check cached result if ((typeCache != null) && (typeCache instanceof Double)) { @@ -2695,7 +2701,7 @@ public boolean hasNextBigInteger(@GuardSatisfied Scanner this, @IntRange(from = * @throws NoSuchElementException if the input is exhausted * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public BigInteger nextBigInteger(@GuardSatisfied @NonEmpty Scanner this) { return nextBigInteger(defaultRadix); } @@ -2726,7 +2732,7 @@ public BigInteger nextBigInteger(@GuardSatisfied @NonEmpty Scanner this) { * @throws IllegalStateException if this scanner is closed * @throws IllegalArgumentException if the radix is out of range */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public BigInteger nextBigInteger(@GuardSatisfied @NonEmpty Scanner this, @IntRange(from = 2, to = 36) int radix) { // Check cached result if ((typeCache != null) && (typeCache instanceof BigInteger val) @@ -2793,7 +2799,7 @@ public boolean hasNextBigDecimal(@GuardSatisfied Scanner this) { * @throws NoSuchElementException if the input is exhausted * @throws IllegalStateException if this scanner is closed */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public BigDecimal nextBigDecimal(@GuardSatisfied @NonEmpty Scanner this) { // Check cached result if ((typeCache != null) && (typeCache instanceof BigDecimal val)) { diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java index 54237c7a3f7..a424be88c58 100644 --- a/src/java.base/share/classes/java/util/SequencedCollection.java +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -25,6 +25,9 @@ package java.util; +import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; + /** * A collection that has a well-defined encounter order, that supports operations at both ends, * and that is reversible. The elements of a sequenced collection have an @@ -87,6 +90,8 @@ public interface SequencedCollection extends Collection { * * @return a reverse-ordered view of this collection */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") SequencedCollection reversed(); /** @@ -103,6 +108,8 @@ public interface SequencedCollection extends Collection { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default void addFirst(E e) { throw new UnsupportedOperationException(); } @@ -121,6 +128,8 @@ default void addFirst(E e) { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default void addLast(E e) { throw new UnsupportedOperationException(); } @@ -137,6 +146,7 @@ default void addLast(E e) { * @return the retrieved element * @throws NoSuchElementException if this collection is empty */ + @Pure default E getFirst() { return this.iterator().next(); } @@ -153,6 +163,7 @@ default E getFirst() { * @return the retrieved element * @throws NoSuchElementException if this collection is empty */ + @Pure default E getLast() { return this.reversed().iterator().next(); } @@ -172,6 +183,8 @@ default E getLast() { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default E removeFirst() { var it = this.iterator(); E e = it.next(); @@ -194,6 +207,8 @@ default E removeFirst() { * @throws UnsupportedOperationException if this collection implementation * does not support this operation */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default E removeLast() { var it = this.reversed().iterator(); E e = it.next(); diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index 6bff204b65d..5241bcad1d7 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -25,6 +25,9 @@ package java.util; +import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; + import jdk.internal.util.NullableKeyValueHolder; /** @@ -134,6 +137,8 @@ public interface SequencedMap extends Map { * * @return a reverse-ordered view of this map */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") SequencedMap reversed(); /** @@ -184,6 +189,8 @@ default Map.Entry lastEntry() { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default Map.Entry pollFirstEntry() { var it = entrySet().iterator(); if (it.hasNext()) { @@ -209,6 +216,8 @@ default Map.Entry pollFirstEntry() { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default Map.Entry pollLastEntry() { var it = reversed().entrySet().iterator(); if (it.hasNext()) { @@ -235,6 +244,8 @@ default Map.Entry pollLastEntry() { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -254,6 +265,8 @@ default V putFirst(K k, V v) { * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default V putLast(K k, V v) { throw new UnsupportedOperationException(); } @@ -272,6 +285,8 @@ default V putLast(K k, V v) { * * @return a {@code SequencedSet} view of this map's {@code keySet} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default SequencedSet sequencedKeySet() { class SeqKeySet extends AbstractMap.ViewCollection implements SequencedSet { Collection view() { @@ -280,9 +295,11 @@ Collection view() { public SequencedSet reversed() { return SequencedMap.this.reversed().sequencedKeySet(); } + @Pure public boolean equals(Object other) { return view().equals(other); } + @Pure public int hashCode() { return view().hashCode(); } @@ -305,6 +322,8 @@ public int hashCode() { * * @return a {@code SequencedCollection} view of this map's {@code values} collection */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default SequencedCollection sequencedValues() { class SeqValues extends AbstractMap.ViewCollection implements SequencedCollection { Collection view() { @@ -331,6 +350,8 @@ public SequencedCollection reversed() { * * @return a {@code SequencedSet} view of this map's {@code entrySet} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default SequencedSet> sequencedEntrySet() { class SeqEntrySet extends AbstractMap.ViewCollection> implements SequencedSet> { @@ -340,9 +361,11 @@ Collection> view() { public SequencedSet> reversed() { return SequencedMap.this.reversed().sequencedEntrySet(); } + @Pure public boolean equals(Object other) { return view().equals(other); } + @Pure public int hashCode() { return view().hashCode(); } diff --git a/src/java.base/share/classes/java/util/SequencedSet.java b/src/java.base/share/classes/java/util/SequencedSet.java index c02bfc123ff..6a65d046fee 100644 --- a/src/java.base/share/classes/java/util/SequencedSet.java +++ b/src/java.base/share/classes/java/util/SequencedSet.java @@ -25,6 +25,8 @@ package java.util; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; + /** * A collection that is both a {@link SequencedCollection} and a {@link Set}. As such, * it can be thought of either as a {@code Set} that also has a well-defined @@ -54,5 +56,7 @@ public interface SequencedSet extends SequencedCollection, Set { * * @return a reverse-ordered view of this collection, as a {@code SequencedSet} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") SequencedSet reversed(); } diff --git a/src/java.base/share/classes/java/util/ServiceLoader.java b/src/java.base/share/classes/java/util/ServiceLoader.java index f8574ad10e6..3a43f94a57b 100644 --- a/src/java.base/share/classes/java/util/ServiceLoader.java +++ b/src/java.base/share/classes/java/util/ServiceLoader.java @@ -32,8 +32,9 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.BufferedReader; import java.io.IOException; @@ -733,6 +734,7 @@ public Class type() { } @Override + @Pure public S get() { if (factoryMethod != null) { return invokeFactoryMethod(); @@ -832,11 +834,13 @@ public S run() throws Exception { // when running with a security manager. @Override + @Pure public int hashCode() { return Objects.hash(service, type, acc); } @Override + @Pure public boolean equals(Object ob) { return ob instanceof @SuppressWarnings("unchecked")ProviderImpl that && this.service == that.service @@ -978,7 +982,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Provider next(@NonEmpty LayerLookupIterator this) { if (!hasNext()) throw new NoSuchElementException(); @@ -1299,7 +1304,8 @@ public boolean hasNext() { @SuppressWarnings("removal") @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Provider next(@NonEmpty LazyClassPathLookupIterator this) { if (acc == null) { return nextService(); @@ -1330,7 +1336,8 @@ public boolean hasNext() { return (first.hasNext() || second.hasNext()); } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Provider next(/*@NonEmpty Iterator> this*/) { if (first.hasNext()) { return first.next(); @@ -1419,7 +1426,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public S next(/*@NonEmpty Iterator this*/) { checkReloadCount(); S next; diff --git a/src/java.base/share/classes/java/util/Set.java b/src/java.base/share/classes/java/util/Set.java index 914bfe89d5d..54ac68a1f87 100644 --- a/src/java.base/share/classes/java/util/Set.java +++ b/src/java.base/share/classes/java/util/Set.java @@ -40,6 +40,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * A collection that contains no duplicate elements. More formally, sets @@ -242,7 +243,6 @@ public interface Set extends Collection { * set * @throws NullPointerException if the specified array is null */ - @SideEffectFree @Nullable T [] toArray(@PolyNull T[] a); @@ -468,6 +468,7 @@ public interface Set extends Collection { * @since 1.8 */ @Override + @SideEffectFree default Spliterator spliterator() { return Spliterators.spliterator(this, Spliterator.DISTINCT); } @@ -482,6 +483,7 @@ default Spliterator spliterator() { * @since 9 */ @SuppressWarnings("unchecked") + @SideEffectFree static Set of() { return (Set) ImmutableCollections.EMPTY_SET; } @@ -497,6 +499,7 @@ static Set of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Set of(E e1) { return new ImmutableCollections.Set12<>(e1); } @@ -514,6 +517,7 @@ static Set of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Set of(E e1, E e2) { return new ImmutableCollections.Set12<>(e1, e2); } @@ -532,6 +536,7 @@ static Set of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Set of(E e1, E e2, E e3) { return new ImmutableCollections.SetN<>(e1, e2, e3); } @@ -551,6 +556,7 @@ static Set of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Set of(E e1, E e2, E e3, E e4) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4); } @@ -571,6 +577,7 @@ static Set of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5); } @@ -592,6 +599,7 @@ static Set of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5, e6); @@ -615,6 +623,7 @@ static Set of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5, e6, e7); @@ -639,6 +648,7 @@ static Set of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5, e6, e7, e8); @@ -664,6 +674,7 @@ static Set of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5, e6, e7, e8, e9); @@ -690,6 +701,7 @@ static Set of() { * * @since 9 */ + @SideEffectFree static @NonEmpty Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) { return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); @@ -723,6 +735,7 @@ static Set of() { */ @SafeVarargs @SuppressWarnings("varargs") + @SideEffectFree static Set of(E... elements) { switch (elements.length) { // implicit null check of elements case 0: @@ -756,6 +769,7 @@ static Set of(E... elements) { * @since 10 */ @SuppressWarnings("unchecked") + @SideEffectFree static @PolyNonEmpty Set copyOf(@PolyNonEmpty Collection coll) { if (coll instanceof ImmutableCollections.AbstractImmutableSet) { return (Set)coll; diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index aaeedaa7cf2..e604e5d9b2c 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -33,6 +33,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * A {@link Map} that further provides a total ordering on its keys. @@ -313,6 +314,8 @@ public interface SortedMap extends SequencedMap { * @throws UnsupportedOperationException always * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -328,6 +331,8 @@ default V putFirst(K k, V v) { * @throws UnsupportedOperationException always * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default V putLast(K k, V v) { throw new UnsupportedOperationException(); } @@ -348,6 +353,8 @@ default V putLast(K k, V v) { * @return a reverse-ordered view of this map, as a {@code SortedMap} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default SortedMap reversed() { return ReverseOrderSortedMapView.of(this); } diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index a39c8db41d6..c62727518a3 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -32,6 +32,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * A {@link Set} that further provides a total ordering on its elements. @@ -268,6 +269,9 @@ public interface SortedSet extends Set, SequencedSet { * @since 1.8 */ @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @SideEffectFree default Spliterator spliterator() { return new Spliterators.IteratorSpliterator( this, Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED) { @@ -291,6 +295,8 @@ public Comparator getComparator() { * @throws UnsupportedOperationException always * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default void addFirst(E e) { throw new UnsupportedOperationException(); } @@ -306,6 +312,8 @@ default void addFirst(E e) { * @throws UnsupportedOperationException always * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default void addLast(E e) { throw new UnsupportedOperationException(); } @@ -319,6 +327,7 @@ default void addLast(E e) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure default E getFirst() { return this.first(); } @@ -332,6 +341,7 @@ default E getFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure default E getLast() { return this.last(); } @@ -348,6 +358,8 @@ default E getLast() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default E removeFirst() { E e = this.first(); this.remove(e); @@ -366,6 +378,8 @@ default E removeFirst() { * @throws UnsupportedOperationException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default E removeLast() { E e = this.last(); this.remove(e); @@ -388,6 +402,8 @@ default E removeLast() { * @return a reverse-ordered view of this collection, as a {@code SortedSet} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") default SortedSet reversed() { return ReverseOrderSortedSetView.of(this); } diff --git a/src/java.base/share/classes/java/util/Spliterators.java b/src/java.base/share/classes/java/util/Spliterators.java index 512f6296a3b..673ef3ae22e 100644 --- a/src/java.base/share/classes/java/util/Spliterators.java +++ b/src/java.base/share/classes/java/util/Spliterators.java @@ -28,7 +28,8 @@ import org.checkerframework.checker.nonempty.qual.NonEmpty; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.function.Consumer; import java.util.function.DoubleConsumer; import java.util.function.IntConsumer; @@ -696,7 +697,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public T next(@NonEmpty Adapter this) { if (!valueReady && !hasNext()) throw new NoSuchElementException(); @@ -758,7 +760,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int nextInt(@NonEmpty Adapter this) { if (!valueReady && !hasNext()) throw new NoSuchElementException(); @@ -816,7 +819,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public long nextLong(@NonEmpty Adapter this) { if (!valueReady && !hasNext()) throw new NoSuchElementException(); @@ -874,7 +878,8 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public double nextDouble(@NonEmpty Adapter this) { if (!valueReady && !hasNext()) throw new NoSuchElementException(); diff --git a/src/java.base/share/classes/java/util/Stack.java b/src/java.base/share/classes/java/util/Stack.java index 4a960c5b90d..5877afa458b 100644 --- a/src/java.base/share/classes/java/util/Stack.java +++ b/src/java.base/share/classes/java/util/Stack.java @@ -33,6 +33,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * The {@code Stack} class represents a last-in-first-out @@ -75,6 +76,8 @@ public Stack() { * @return the {@code item} argument. * @see java.util.Vector#addElement */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E push(@GuardSatisfied Stack this, E item) { addElement(item); @@ -89,6 +92,8 @@ public E push(@GuardSatisfied Stack this, E item) { * of the {@code Vector} object). * @throws EmptyStackException if this stack is empty. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized E pop(@GuardSatisfied @NonEmpty @CanShrink Stack this) { E obj; int len = size(); diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index eeb4c767672..e11638f9402 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -38,9 +38,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.Serializable; import java.util.function.BiConsumer; @@ -309,6 +310,9 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied * and this map uses natural ordering, or its comparator * does not permit null keys */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @Pure public @Nullable V get(@GuardSatisfied TreeMap this, @UnknownSignedness @GuardSatisfied Object key) { Entry p = getEntry(key); return (p==null ? null : p.value); @@ -341,6 +345,8 @@ public boolean containsValue(@GuardSatisfied TreeMap this, @GuardSatisfied * @throws UnsupportedOperationException always * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -353,6 +359,8 @@ public V putFirst(K k, V v) { * @throws UnsupportedOperationException always * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putLast(K k, V v) { throw new UnsupportedOperationException(); } @@ -369,6 +377,8 @@ public V putLast(K k, V v) { * the specified map contains a null key and this map does not * permit null keys */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putAll(@GuardSatisfied TreeMap this, Map map) { int mapSize = map.size(); if (size==0 && mapSize!=0 && map instanceof SortedMap) { @@ -590,11 +600,15 @@ final Entry getLowerEntry(K key) { * does not permit null keys */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(@GuardSatisfied TreeMap this, K key, V value) { return put(key, value, true); } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putIfAbsent(K key, V value) { return put(key, value, false); } @@ -610,6 +624,7 @@ public V putIfAbsent(K key, V value) { * mapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public V computeIfAbsent(K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); V newValue; @@ -680,6 +695,7 @@ else if (cmp > 0) * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public V computeIfPresent(K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Entry oldEntry = getEntry(key); @@ -701,6 +717,7 @@ public V computeIfPresent(K key, BiFunction r * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public V compute(K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); V newValue; @@ -763,6 +780,7 @@ else if (cmp > 0) * remapping function modified this map */ @Override + @DoesNotUnrefineReceiver("modifiability") public V merge(K key, V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); Objects.requireNonNull(value); @@ -937,6 +955,8 @@ private V mergeValue(Entry t, V value, BiFunction this, @GuardSatisfied @UnknownSignedness Object key) { Entry p = getEntry(key); if (p == null) @@ -951,6 +971,8 @@ private V mergeValue(Entry t, V value, BiFunction this) { modCount++; size = 0; @@ -963,6 +985,9 @@ public void clear(@GuardSatisfied TreeMap this) { * * @return a shallow copy of this map */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @SideEffectFree public Object clone(@GuardSatisfied TreeMap this) { TreeMap clone; try { @@ -1007,6 +1032,8 @@ public Object clone(@GuardSatisfied TreeMap this) { /** * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.@Nullable Entry pollFirstEntry(@GuardSatisfied TreeMap this) { Entry p = getFirstEntry(); Map.Entry result = exportEntry(p); @@ -1018,6 +1045,8 @@ public Object clone(@GuardSatisfied TreeMap this) { /** * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.@Nullable Entry pollLastEntry(@GuardSatisfied TreeMap this) { Entry p = getLastEntry(); Map.Entry result = exportEntry(p); @@ -1150,6 +1179,9 @@ public Object clone(@GuardSatisfied TreeMap this) { * operations. It does not support the {@code add} or {@code addAll} * operations. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @SideEffectFree public Set<@KeyFor({"this"}) K> keySet(@GuardSatisfied TreeMap this) { return navigableKeySet(); } @@ -1192,6 +1224,7 @@ public Object clone(@GuardSatisfied TreeMap this) { * {@code retainAll} and {@code clear} operations. It does not * support the {@code add} or {@code addAll} operations. */ + @SideEffectFree public Collection values(@GuardSatisfied TreeMap this) { Collection vs = values; if (vs == null) { @@ -1324,6 +1357,8 @@ public SortedMap tailMap(@GuardSatisfied TreeMap this, K fromKey) { } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { Entry p = getEntry(key); if (p!=null && Objects.equals(oldValue, p.value)) { @@ -1334,6 +1369,8 @@ public boolean replace(K key, V oldValue, V newValue) { } @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V replace(K key, V value) { Entry p = getEntry(key); if (p!=null) { @@ -1358,6 +1395,7 @@ public void forEach(BiConsumer action) { } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { Objects.requireNonNull(function); int expectedModCount = modCount; @@ -1390,6 +1428,8 @@ public boolean contains(@UnknownSignedness Object o) { return TreeMap.this.containsValue(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { for (Entry e = getFirstEntry(); e != null; e = successor(e)) { if (valEquals(e.getValue(), o)) { @@ -1400,6 +1440,8 @@ public boolean remove(@UnknownSignedness Object o) { return false; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { TreeMap.this.clear(); } @@ -1426,6 +1468,8 @@ public boolean contains(@UnknownSignedness Object o) { return p != null && valEquals(p.getValue(), value); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { if (!(o instanceof Map.Entry entry)) return false; @@ -1443,6 +1487,8 @@ public boolean remove(@UnknownSignedness Object o) { return TreeMap.this.size(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { TreeMap.this.clear(); } @@ -1496,13 +1542,18 @@ public Iterator descendingIterator() { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@UnknownSignedness Object o) { return m.containsKey(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } public E lower(E e) { return m.lowerKey(e); } public E floor(E e) { return m.floorKey(e); } public E ceiling(E e) { return m.ceilingKey(e); } public E higher(E e) { return m.higherKey(e); } + @SideEffectFree public E first() { return m.firstKey(); } + @SideEffectFree public E last() { return m.lastKey(); } + @Pure public Comparator comparator() { return m.comparator(); } public E pollFirst() { Map.Entry e = m.pollFirstEntry(); @@ -1512,6 +1563,8 @@ public E pollLast() { Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { int oldSize = size(); m.remove(o); @@ -1522,18 +1575,23 @@ public NavigableSet subSet(E fromElement, boolean fromInclusive, return new KeySet<>(m.subMap(fromElement, fromInclusive, toElement, toInclusive)); } + @SideEffectFree public NavigableSet headSet(E toElement, boolean inclusive) { return new KeySet<>(m.headMap(toElement, inclusive)); } + @SideEffectFree public NavigableSet tailSet(E fromElement, boolean inclusive) { return new KeySet<>(m.tailMap(fromElement, inclusive)); } + @SideEffectFree public SortedSet subSet(E fromElement, E toElement) { return subSet(fromElement, true, toElement, false); } + @SideEffectFree public SortedSet headSet(E toElement) { return headSet(toElement, false); } + @SideEffectFree public SortedSet tailSet(E fromElement) { return tailSet(fromElement, true); } @@ -1567,7 +1625,7 @@ public final boolean hasNext() { return next != null; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") final Entry nextEntry() { Entry e = next; if (e == null) @@ -1579,7 +1637,7 @@ final Entry nextEntry() { return e; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") final Entry prevEntry() { Entry e = next; if (e == null) @@ -1591,6 +1649,8 @@ final Entry prevEntry() { return e; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastReturned == null) throw new IllegalStateException(); @@ -1609,6 +1669,8 @@ final class EntryIterator extends PrivateEntryIterator> { EntryIterator(Entry first) { super(first); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry next(@NonEmpty EntryIterator this) { return nextEntry(); } @@ -1618,6 +1680,8 @@ final class ValueIterator extends PrivateEntryIterator { ValueIterator(Entry first) { super(first); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V next(@NonEmpty ValueIterator this) { return nextEntry().value; } @@ -1627,6 +1691,8 @@ final class KeyIterator extends PrivateEntryIterator { KeyIterator(Entry first) { super(first); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K next(@NonEmpty KeyIterator this) { return nextEntry().key; } @@ -1636,9 +1702,13 @@ final class DescendingKeyIterator extends PrivateEntryIterator { DescendingKeyIterator(Entry first) { super(first); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K next(@NonEmpty DescendingKeyIterator this) { return prevEntry().key; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastReturned == null) throw new IllegalStateException(); @@ -1887,24 +1957,30 @@ public final boolean containsKey(@UnknownSignedness Object key) { } @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final V put(K key, V value) { if (!inRange(key)) throw new IllegalArgumentException("key out of range"); return m.put(key, value); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putIfAbsent(K key, V value) { if (!inRange(key)) throw new IllegalArgumentException("key out of range"); return m.putIfAbsent(key, value); } + @DoesNotUnrefineReceiver("modifiability") public V merge(K key, V value, BiFunction remappingFunction) { if (!inRange(key)) throw new IllegalArgumentException("key out of range"); return m.merge(key, value, remappingFunction); } + @DoesNotUnrefineReceiver("modifiability") public V computeIfAbsent(K key, Function mappingFunction) { if (!inRange(key)) { // Do not throw if mapping function returns null @@ -1915,6 +1991,7 @@ public V computeIfAbsent(K key, Function mappingFunction return m.computeIfAbsent(key, mappingFunction); } + @DoesNotUnrefineReceiver("modifiability") public V compute(K key, BiFunction remappingFunction) { if (!inRange(key)) { // Do not throw if remapping function returns null @@ -1925,14 +2002,18 @@ public V compute(K key, BiFunction remappingF return m.compute(key, remappingFunction); } + @DoesNotUnrefineReceiver("modifiability") public V computeIfPresent(K key, BiFunction remappingFunction) { return !inRange(key) ? null : m.computeIfPresent(key, remappingFunction); } + @Pure public final V get(Object key) { return !inRange(key) ? null : m.get(key); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final V remove(Object key) { return !inRange(key) ? null : m.remove(key); } @@ -2013,6 +2094,7 @@ public final NavigableSet navigableKeySet() { (navigableKeySetView = new TreeMap.KeySet<>(this)); } + @SideEffectFree public final Set keySet() { return navigableKeySet(); } @@ -2078,6 +2160,8 @@ public boolean contains(@UnknownSignedness Object o) { valEquals(node.getValue(), entry.getValue()); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { if (!(o instanceof Entry entry)) return false; @@ -2117,7 +2201,7 @@ public final boolean hasNext() { return next != null && next.key != fenceKey; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") final TreeMap.Entry nextEntry() { TreeMap.Entry e = next; if (e == null || e.key == fenceKey) @@ -2129,7 +2213,7 @@ final TreeMap.Entry nextEntry() { return e; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") final TreeMap.Entry prevEntry() { TreeMap.Entry e = next; if (e == null || e.key == fenceKey) @@ -2171,9 +2255,13 @@ final class SubMapEntryIterator extends SubMapIterator> { TreeMap.Entry fence) { super(first, fence); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry next(@NonEmpty SubMapEntryIterator this) { return nextEntry(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { removeAscending(); } @@ -2185,9 +2273,13 @@ final class DescendingSubMapEntryIterator extends SubMapIterator> super(last, fence); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry next(@NonEmpty DescendingSubMapEntryIterator this) { return prevEntry(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { removeDescending(); } @@ -2200,9 +2292,13 @@ final class SubMapKeyIterator extends SubMapIterator TreeMap.Entry fence) { super(first, fence); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K next(@NonEmpty SubMapKeyIterator this) { return nextEntry().key; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { removeAscending(); } @@ -2238,9 +2334,13 @@ final class DescendingSubMapKeyIterator extends SubMapIterator TreeMap.Entry fence) { super(last, fence); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K next(@NonEmpty DescendingSubMapKeyIterator this) { return prevEntry().key; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { removeDescending(); } @@ -2280,6 +2380,7 @@ static final class AscendingSubMap extends NavigableSubMap { super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); } + @Pure public Comparator comparator() { return m.comparator(); } @@ -2337,6 +2438,7 @@ Iterator descendingKeyIterator() { } final class AscendingEntrySetView extends EntrySetView { + @SideEffectFree public Iterator> iterator() { return new SubMapEntryIterator(absLowest(), absHighFence()); } @@ -2372,6 +2474,7 @@ static final class DescendingSubMap extends NavigableSubMap { private final Comparator reverseComparator = Collections.reverseOrder(m.comparator); + @Pure public Comparator comparator() { return reverseComparator; } @@ -2429,6 +2532,7 @@ Iterator descendingKeyIterator() { } final class DescendingEntrySetView extends EntrySetView { + @SideEffectFree public Iterator> iterator() { return new DescendingSubMapEntryIterator(absHighest(), absLowFence()); } @@ -2482,6 +2586,7 @@ private Object readResolve() { public SortedMap headMap(K toKey) { throw new InternalError(); } @SideEffectFree public SortedMap tailMap(K fromKey) { throw new InternalError(); } + @Pure public Comparator comparator() { throw new InternalError(); } } @@ -2519,6 +2624,7 @@ static final class Entry implements Map.Entry { * * @return the key */ + @Pure public K getKey() { return key; } @@ -2528,6 +2634,7 @@ public K getKey() { * * @return the value associated with the key */ + @Pure public V getValue() { return value; } @@ -2545,18 +2652,21 @@ public V setValue(V value) { return oldValue; } + @Pure public boolean equals(Object o) { return o instanceof Map.Entry e && valEquals(key,e.getKey()) && valEquals(value,e.getValue()); } + @Pure public int hashCode() { int keyHash = (key==null ? 0 : key.hashCode()); int valueHash = (value==null ? 0 : value.hashCode()); return keyHash ^ valueHash; } + @SideEffectFree public String toString() { return key + "=" + value; } diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index b4770fab88f..a0450cf215b 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -39,6 +39,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; /** * A {@link NavigableSet} implementation based on a {@link TreeMap}. @@ -209,6 +210,8 @@ public TreeSet(@Nullable Comparator comparator) { * @return an iterator over the elements in this set in descending order * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @PolyGrowShrink @PolyNonEmpty Iterator descendingIterator(@PolyGrowShrink @PolyNonEmpty TreeSet this) { return m.descendingKeySet().iterator(); } @@ -216,6 +219,8 @@ public TreeSet(@Nullable Comparator comparator) { /** * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public NavigableSet descendingSet() { return new TreeSet<>(m.descendingMap()); } @@ -280,6 +285,8 @@ public boolean contains(@GuardSatisfied TreeSet this, @GuardSatisfied @Unknow * does not permit null elements */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(@GuardSatisfied TreeSet this, E e) { return m.put(e, PRESENT)==null; } @@ -301,6 +308,8 @@ public boolean add(@GuardSatisfied TreeSet this, E e) { * and this set uses natural ordering, or its comparator * does not permit null elements */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied TreeSet this, @GuardSatisfied @UnknownSignedness Object o) { return m.remove(o)==PRESENT; } @@ -309,6 +318,8 @@ public boolean remove(@GuardSatisfied TreeSet this, @GuardSatisfied @UnknownS * Removes all of the elements from this set. * The set will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied TreeSet this) { m.clear(); } @@ -324,6 +335,8 @@ public void clear(@GuardSatisfied TreeSet this) { * if any element is null and this set uses natural ordering, or * its comparator does not permit null elements */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@GuardSatisfied TreeSet this, Collection c) { // Use linear-time version if applicable if (m.size()==0 && c.size() > 0 && @@ -485,6 +498,8 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { /** * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@GuardSatisfied TreeSet this) { Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); @@ -493,6 +508,8 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { /** * @since 1.6 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@GuardSatisfied TreeSet this) { Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); @@ -506,6 +523,8 @@ public E last(@GuardSatisfied @NonEmpty TreeSet this) { * @throws UnsupportedOperationException always * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { throw new UnsupportedOperationException(); } @@ -518,6 +537,8 @@ public void addFirst(E e) { * @throws UnsupportedOperationException always * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { throw new UnsupportedOperationException(); } @@ -614,6 +635,9 @@ private void readObject(java.io.ObjectInputStream s) * @return a {@code Spliterator} over the elements in this set * @since 1.8 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") + @SideEffectFree public Spliterator spliterator() { return TreeMap.keySpliteratorFor(m); } diff --git a/src/java.base/share/classes/java/util/Vector.java b/src/java.base/share/classes/java/util/Vector.java index a8a3608bb7c..83d13368bd2 100644 --- a/src/java.base/share/classes/java/util/Vector.java +++ b/src/java.base/share/classes/java/util/Vector.java @@ -40,9 +40,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.IOException; import java.io.ObjectInputStream; @@ -351,10 +352,12 @@ public synchronized boolean isEmpty(@GuardSatisfied Vector this) { * @return an enumeration of the components of this vector * @see Iterator */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty Enumeration elements(@PolyGrowShrink @PolyNonEmpty Vector this) { return new Enumeration() { int count = 0; + @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean hasMoreElements() { return count < elementCount; @@ -492,6 +495,7 @@ public boolean contains(@GuardSatisfied Vector this, @GuardSatisfied @Nullabl * @throws ArrayIndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}) */ + @Pure public synchronized E elementAt(@NonNegative int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); @@ -548,6 +552,8 @@ public synchronized E lastElement(@NonEmpty Vector this) { * @throws ArrayIndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized void setElementAt(@GuardSatisfied Vector this, E obj, @NonNegative int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + @@ -575,6 +581,8 @@ public synchronized void setElementAt(@GuardSatisfied Vector this, E obj, @No * @throws ArrayIndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= size()}) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized void removeElementAt(@GuardSatisfied @CanShrink Vector this, @NonNegative int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + @@ -615,6 +623,8 @@ else if (index < 0) { * @throws ArrayIndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index > size()}) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized void insertElementAt(@GuardSatisfied Vector this, E obj, @NonNegative int index) { if (index > elementCount) { throw new ArrayIndexOutOfBoundsException(index @@ -643,6 +653,8 @@ public synchronized void insertElementAt(@GuardSatisfied Vector this, E obj, * * @param obj the component to be added */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized void addElement(@GuardSatisfied Vector this, E obj) { modCount++; add(obj, elementData, elementCount); @@ -663,6 +675,8 @@ public synchronized void addElement(@GuardSatisfied Vector this, E obj) { * @return {@code true} if the argument was a component of this * vector; {@code false} otherwise. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean removeElement(@GuardSatisfied @CanShrink Vector this, Object obj) { modCount++; int i = indexOf(obj); @@ -679,6 +693,8 @@ public synchronized boolean removeElement(@GuardSatisfied @CanShrink Vector t *

    This method is identical in functionality to the {@link #clear} * method (which is part of the {@link List} interface). */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized void removeAllElements(@GuardSatisfied @CanShrink Vector this) { final Object[] es = elementData; for (int to = elementCount, i = elementCount = 0; i < to; i++) @@ -766,6 +782,7 @@ E elementData(int index) { } @SuppressWarnings("unchecked") + @Pure static E elementAt(Object[] es, int index) { return (E) es[index]; } @@ -798,6 +815,8 @@ public synchronized E get(@GuardSatisfied Vector this, @NonNegative int index * ({@code index < 0 || index >= size()}) * @since 1.2 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized E set(@GuardSatisfied Vector this, @NonNegative int index, E element) { if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); @@ -826,8 +845,10 @@ private void add(E e, Object[] elementData, int s) { * @return {@code true} (as specified by {@link Collection#add}) * @since 1.2 */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean add(@GuardSatisfied Vector this, E e) { modCount++; add(e, elementData, elementCount); @@ -845,6 +866,8 @@ public synchronized boolean add(@GuardSatisfied Vector this, E e) { * @return true if the Vector contained the specified element * @since 1.2 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @CanShrink Vector this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeElement(o); } @@ -860,6 +883,8 @@ public boolean remove(@GuardSatisfied @CanShrink Vector this, @GuardSatisfied * ({@code index < 0 || index > size()}) * @since 1.2 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(@GuardSatisfied Vector this, @NonNegative int index, E element) { insertElementAt(element, index); } @@ -875,6 +900,8 @@ public void add(@GuardSatisfied Vector this, @NonNegative int index, E elemen * ({@code index < 0 || index >= size()}) * @since 1.2 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized E remove(@GuardSatisfied @CanShrink Vector this, @NonNegative int index) { modCount++; if (index >= elementCount) @@ -896,6 +923,8 @@ public synchronized E remove(@GuardSatisfied @CanShrink Vector this, @NonNega * * @since 1.2 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink Vector this) { removeAllElements(); } @@ -930,6 +959,8 @@ public synchronized boolean containsAll(@GuardSatisfied Vector this, @GuardSa * @throws NullPointerException if the specified collection is null * @since 1.2 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(@GuardSatisfied Vector this, Collection c) { Object[] a = c.toArray(); modCount++; @@ -964,6 +995,8 @@ public boolean addAll(@GuardSatisfied Vector this, Collection c) * or if the specified collection is null * @since 1.2 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@GuardSatisfied @CanShrink Vector this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -988,6 +1021,8 @@ public boolean removeAll(@GuardSatisfied @CanShrink Vector this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); @@ -998,6 +1033,8 @@ public boolean retainAll(@GuardSatisfied @CanShrink Vector this, Collection this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1067,6 +1104,8 @@ private synchronized boolean bulkRemove(Predicate filter) { * @throws NullPointerException if the specified collection is null * @since 1.2 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized boolean addAll(@GuardSatisfied Vector this, @NonNegative int index, Collection c) { if (index < 0 || index > elementCount) throw new ArrayIndexOutOfBoundsException(index); @@ -1172,6 +1211,8 @@ public synchronized String toString(@GuardSatisfied Vector this) { * This call shortens the list by {@code (toIndex - fromIndex)} elements. * (If {@code toIndex==fromIndex}, this operation has no effect.) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") protected synchronized void removeRange(@GuardSatisfied @CanShrink Vector this, int fromIndex, int toIndex) { modCount++; shiftTailOverGap(elementData, fromIndex, toIndex); @@ -1289,7 +1330,8 @@ public boolean hasNext() { return cursor != elementCount; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty Itr this) { synchronized (Vector.this) { checkForComodification(); @@ -1301,6 +1343,8 @@ public E next(@NonEmpty Itr this) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastRet == -1) throw new IllegalStateException(); @@ -1349,14 +1393,17 @@ final class ListItr extends Itr implements ListIterator { cursor = index; } + @Pure public boolean hasPrevious() { return cursor != 0; } + @Pure public int nextIndex() { return cursor; } + @Pure public int previousIndex() { return cursor - 1; } @@ -1372,6 +1419,8 @@ public E previous() { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { if (lastRet == -1) throw new IllegalStateException(); @@ -1381,6 +1430,8 @@ public void set(E e) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { int i = cursor; synchronized (Vector.this) { @@ -1397,6 +1448,7 @@ public void add(E e) { * @throws NullPointerException {@inheritDoc} */ @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void forEach(Consumer action) { Objects.requireNonNull(action); final int expectedModCount = modCount; @@ -1413,6 +1465,7 @@ public synchronized void forEach(Consumer action) { */ @SuppressWarnings({"unchecked"}) @Override + @DoesNotUnrefineReceiver("modifiability") public synchronized void replaceAll(UnaryOperator operator) { Objects.requireNonNull(operator); final int expectedModCount = modCount; @@ -1428,6 +1481,8 @@ public synchronized void replaceAll(UnaryOperator operator) { @SuppressWarnings("unchecked") @Override + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public synchronized void sort(Comparator c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, elementCount, c); diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index 0bf358ec1f6..85f6a9be058 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -38,9 +38,10 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.lang.ref.WeakReference; import java.lang.ref.ReferenceQueue; @@ -448,8 +449,8 @@ public boolean isEmpty(@GuardSatisfied WeakHashMap this) { * @return {@code true} if there is a mapping for {@code key}; * {@code false} otherwise */ - @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) @Pure + @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) public boolean containsKey(@GuardSatisfied WeakHashMap this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { return getEntry(key) != null; } @@ -482,6 +483,8 @@ Entry getEntry(Object key) { * previously associated {@code null} with {@code key}.) */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(@GuardSatisfied WeakHashMap this, K key, V value) { Object k = maskNull(key); int h = hash(k); @@ -574,6 +577,8 @@ private void transfer(Entry[] src, Entry[] dest) { * @param m mappings to be stored in this map. * @throws NullPointerException if the specified map is null. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putAll(@GuardSatisfied WeakHashMap this, Map m) { int numKeysToBeAdded = m.size(); if (numKeysToBeAdded == 0) @@ -623,6 +628,8 @@ public void putAll(@GuardSatisfied WeakHashMap this, Map this, @GuardSatisfied @Nullable @UnknownSignedness Object key) { Object k = maskNull(key); int h = hash(k); @@ -682,6 +689,8 @@ boolean removeMapping(Object o) { * Removes all of the mappings from this map. * The map will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied WeakHashMap this) { // clear out ref queue. We don't need to expunge entries // since table is getting cleared. @@ -754,20 +763,25 @@ private static class Entry extends WeakReference implements Map.Ent } @SuppressWarnings("unchecked") + @Pure public K getKey() { return (K) WeakHashMap.unmaskNull(get()); } + @Pure public V getValue() { return value; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V setValue(V newValue) { V oldValue = value; value = newValue; return oldValue; } + @Pure public boolean equals(Object o) { if (!(o instanceof Map.Entry e)) return false; @@ -782,12 +796,14 @@ public boolean equals(Object o) { return false; } + @Pure public int hashCode() { K k = getKey(); V v = getValue(); return Objects.hashCode(k) ^ Objects.hashCode(v); } + @SideEffectFree public String toString() { return getKey() + "=" + getValue(); } @@ -839,7 +855,7 @@ public boolean hasNext() { } /** The common parts of next() across different types of iterators */ - @SideEffectsOnly("this") + // @SideEffectsOnly("this") protected Entry nextEntry() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); @@ -853,6 +869,8 @@ protected Entry nextEntry() { return lastReturned; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastReturned == null) throw new IllegalStateException(); @@ -868,18 +886,24 @@ public void remove() { } private class ValueIterator extends HashIterator { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V next(@NonEmpty ValueIterator this) { return nextEntry().value; } } private class KeyIterator extends HashIterator { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K next(@NonEmpty KeyIterator this) { return nextEntry().getKey(); } } private class EntryIterator extends HashIterator> { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry next(@NonEmpty EntryIterator this) { return nextEntry(); } @@ -929,6 +953,8 @@ public boolean contains(@Nullable @UnknownSignedness Object o) { return containsKey(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { if (containsKey(o)) { WeakHashMap.this.remove(o); @@ -938,6 +964,8 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { return false; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { WeakHashMap.this.clear(); } @@ -988,6 +1016,8 @@ public boolean contains(@Nullable @UnknownSignedness Object o) { return containsValue(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { WeakHashMap.this.clear(); } @@ -1032,6 +1062,8 @@ && getEntry(e.getKey()) != null && getEntry(e.getKey()).equals(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { return removeMapping(o); } @@ -1041,6 +1073,8 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { return WeakHashMap.this.size(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { WeakHashMap.this.clear(); } @@ -1057,7 +1091,6 @@ public Object[] toArray() { return deepCopy().toArray(); } - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { return deepCopy().toArray(a); } @@ -1070,6 +1103,7 @@ public Spliterator> spliterator() { @SuppressWarnings("unchecked") @Override + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { Objects.requireNonNull(action); int expectedModCount = modCount; @@ -1092,6 +1126,7 @@ public void forEach(BiConsumer action) { @SuppressWarnings("unchecked") @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { Objects.requireNonNull(function); int expectedModCount = modCount; diff --git a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java index 44f6b775e89..3fe027bafbe 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -48,8 +48,10 @@ import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.dataflow.qual.SideEffectFree; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.lang.ref.WeakReference; import java.util.AbstractQueue; @@ -343,6 +345,8 @@ public ArrayBlockingQueue(int capacity, boolean fair, * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { return super.add(e); } @@ -356,6 +360,8 @@ public boolean add(E e) { * * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { Objects.requireNonNull(e); final ReentrantLock lock = this.lock; @@ -379,6 +385,8 @@ public boolean offer(E e) { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void put(E e) throws InterruptedException { Objects.requireNonNull(e); final ReentrantLock lock = this.lock; @@ -400,6 +408,8 @@ public void put(E e) throws InterruptedException { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { @@ -420,6 +430,8 @@ public boolean offer(E e, long timeout, TimeUnit unit) } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E poll(@GuardSatisfied @CanShrink ArrayBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -430,6 +442,8 @@ public E poll(@GuardSatisfied @CanShrink ArrayBlockingQueue this) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E take(@GuardSatisfied @CanShrink ArrayBlockingQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -442,6 +456,8 @@ public E take(@GuardSatisfied @CanShrink ArrayBlockingQueue this) throws Inte } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E poll(@GuardSatisfied @CanShrink ArrayBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; @@ -527,6 +543,8 @@ public int remainingCapacity() { * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@CanShrink ArrayBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; @@ -596,6 +614,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) * * @return an array containing all of the elements in this queue */ + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(ArrayBlockingQueue<@PolyNull @PolySigned E> this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -670,6 +689,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) } } + @SideEffectFree public String toString() { return Helpers.collectionToString(this); } @@ -678,6 +698,8 @@ public String toString() { * Atomically removes all of the elements from this queue. * The queue will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink ArrayBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -717,6 +739,8 @@ private static void circularClear(Object[] items, int i, int end) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink ArrayBlockingQueue this, Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -727,6 +751,8 @@ public int drainTo(@GuardSatisfied @CanShrink ArrayBlockingQueue this, Collec * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink ArrayBlockingQueue this, Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -779,6 +805,7 @@ else if (i > take) * * @return an iterator over the elements in this queue in proper sequence */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty ArrayBlockingQueue this) { return new Itr(); } @@ -1233,7 +1260,8 @@ private void noNext() { } } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty Itr this) { final E e = nextItem; if (e == null) @@ -1292,6 +1320,8 @@ public void forEachRemaining(Consumer action) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { final ReentrantLock lock = ArrayBlockingQueue.this.lock; lock.lock(); @@ -1460,6 +1490,7 @@ boolean takeIndexWrapped() { * @return a {@code Spliterator} over the elements in this queue * @since 1.8 */ + @SideEffectFree public Spliterator spliterator() { return Spliterators.spliterator (this, (Spliterator.ORDERED | @@ -1493,6 +1524,8 @@ public void forEach(Consumer action) { /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@CanShrink ArrayBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1501,6 +1534,8 @@ public boolean removeIf(@CanShrink ArrayBlockingQueue this, Predicate this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1509,6 +1544,8 @@ public boolean removeAll(@CanShrink ArrayBlockingQueue this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java b/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java index 81eecd57443..5f626cc338d 100644 --- a/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/BlockingDeque.java @@ -48,6 +48,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.Deque; import java.util.Iterator; @@ -231,6 +232,8 @@ public interface BlockingDeque extends BlockingQueue< * @throws NullPointerException if the specified element is null * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void addFirst(E e); /** @@ -246,6 +249,8 @@ public interface BlockingDeque extends BlockingQueue< * @throws NullPointerException if the specified element is null * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void addLast(E e); /** @@ -262,6 +267,8 @@ public interface BlockingDeque extends BlockingQueue< * @throws NullPointerException if the specified element is null * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offerFirst(E e); /** @@ -278,6 +285,8 @@ public interface BlockingDeque extends BlockingQueue< * @throws NullPointerException if the specified element is null * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offerLast(E e); /** @@ -292,6 +301,8 @@ public interface BlockingDeque extends BlockingQueue< * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void putFirst(E e) throws InterruptedException; /** @@ -306,6 +317,8 @@ public interface BlockingDeque extends BlockingQueue< * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void putLast(E e) throws InterruptedException; /** @@ -327,6 +340,8 @@ public interface BlockingDeque extends BlockingQueue< * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offerFirst(E e, long timeout, TimeUnit unit) throws InterruptedException; @@ -349,6 +364,8 @@ boolean offerFirst(E e, long timeout, TimeUnit unit) * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offerLast(E e, long timeout, TimeUnit unit) throws InterruptedException; @@ -359,6 +376,8 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @return the head of this deque * @throws InterruptedException if interrupted while waiting */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E takeFirst(@CanShrink BlockingDeque this) throws InterruptedException; /** @@ -368,6 +387,8 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @return the tail of this deque * @throws InterruptedException if interrupted while waiting */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E takeLast(@CanShrink BlockingDeque this) throws InterruptedException; /** @@ -383,6 +404,8 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * waiting time elapses before an element is available * @throws InterruptedException if interrupted while waiting */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable E pollFirst(@CanShrink BlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException; @@ -399,6 +422,8 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * waiting time elapses before an element is available * @throws InterruptedException if interrupted while waiting */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable E pollLast(@CanShrink BlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException; @@ -418,6 +443,8 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @throws NullPointerException if the specified element is null * (optional) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean removeFirstOccurrence(@CanShrink BlockingDeque this, Object o); /** @@ -436,6 +463,8 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @throws NullPointerException if the specified element is null * (optional) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean removeLastOccurrence(@CanShrink BlockingDeque this, Object o); // *** BlockingQueue methods *** @@ -459,6 +488,8 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @EnsuresNonEmpty("this") boolean add(E e); @@ -480,6 +511,8 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offer(E e); /** @@ -497,6 +530,8 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void put(E e) throws InterruptedException; /** @@ -517,6 +552,8 @@ boolean offerLast(E e, long timeout, TimeUnit unit) * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException; @@ -531,6 +568,8 @@ boolean offer(E e, long timeout, TimeUnit unit) * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E remove(@GuardSatisfied @NonEmpty @CanShrink BlockingDeque this); /** @@ -542,6 +581,8 @@ boolean offer(E e, long timeout, TimeUnit unit) * * @return the head of this deque, or {@code null} if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable E poll(@CanShrink BlockingDeque this); /** @@ -554,6 +595,8 @@ boolean offer(E e, long timeout, TimeUnit unit) * @return the head of this deque * @throws InterruptedException if interrupted while waiting */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E take(@CanShrink BlockingDeque this) throws InterruptedException; /** @@ -568,6 +611,8 @@ boolean offer(E e, long timeout, TimeUnit unit) * specified waiting time elapses before an element is available * @throws InterruptedException if interrupted while waiting */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable E poll(@CanShrink BlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException; @@ -582,6 +627,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * @return the head of this deque * @throws NoSuchElementException if this deque is empty */ + @Pure E element(@NonEmpty BlockingDeque this); /** @@ -593,6 +639,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * * @return the head of this deque, or {@code null} if this deque is empty */ + @Pure @Nullable E peek(); /** @@ -614,6 +661,8 @@ boolean offer(E e, long timeout, TimeUnit unit) * @throws NullPointerException if the specified element is null * (optional) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean remove(@CanShrink BlockingDeque this, @UnknownSignedness Object o); /** @@ -665,5 +714,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * @throws NullPointerException if the specified element is null * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void push(E e); } diff --git a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java index f33a527593e..dc9b4edda9e 100644 --- a/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/BlockingQueue.java @@ -45,6 +45,7 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.Collection; import java.util.Queue; @@ -208,6 +209,8 @@ public interface BlockingQueue extends Queue { * element prevents it from being added to this queue */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean add(E e); /** @@ -227,6 +230,8 @@ public interface BlockingQueue extends Queue { * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this queue */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offer(E e); /** @@ -241,6 +246,8 @@ public interface BlockingQueue extends Queue { * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this queue */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") void put(E e) throws InterruptedException; /** @@ -261,6 +268,8 @@ public interface BlockingQueue extends Queue { * @throws IllegalArgumentException if some property of the specified * element prevents it from being added to this queue */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException; @@ -271,6 +280,8 @@ boolean offer(E e, long timeout, TimeUnit unit) * @return the head of this queue * @throws InterruptedException if interrupted while waiting */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") E take() throws InterruptedException; /** @@ -285,6 +296,8 @@ boolean offer(E e, long timeout, TimeUnit unit) * specified waiting time elapses before an element is available * @throws InterruptedException if interrupted while waiting */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable E poll(long timeout, TimeUnit unit) throws InterruptedException; @@ -319,6 +332,8 @@ boolean offer(E e, long timeout, TimeUnit unit) * @throws NullPointerException if the specified element is null * (optional) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean remove(@CanShrink BlockingQueue this, @UnknownSignedness Object o); /** @@ -361,6 +376,8 @@ boolean offer(E e, long timeout, TimeUnit unit) * queue, or some property of an element of this queue prevents * it from being added to the specified collection */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") int drainTo(@GuardSatisfied @CanShrink BlockingQueue this, Collection c); /** @@ -386,5 +403,7 @@ boolean offer(E e, long timeout, TimeUnit unit) * queue, or some property of an element of this queue prevents * it from being added to the specified collection */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") int drainTo(@GuardSatisfied @CanShrink BlockingQueue this, Collection c, int maxElements); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index f5bfb81b94a..f9f090d33a2 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -50,8 +50,9 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.ObjectStreamField; import java.io.Serializable; @@ -658,16 +659,23 @@ static class Node implements Map.Entry { this.next = next; } + @Pure public final K getKey() { return key; } + @Pure public final V getValue() { return val; } + @Pure public final int hashCode() { return key.hashCode() ^ val.hashCode(); } + @SideEffectFree public final String toString() { return Helpers.mapEntryToString(key, val); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final V setValue(V value) { throw new UnsupportedOperationException(); } + @Pure public final boolean equals(Object o) { Object k, v, u; Map.Entry e; return ((o instanceof Map.Entry) && @@ -983,8 +991,8 @@ else if (eh < 0) * {@code equals} method; {@code false} otherwise * @throws NullPointerException if the specified key is null */ - @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) @Pure + @EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"}) public boolean containsKey(@GuardSatisfied @UnknownSignedness Object key) { return get(key) != null; } @@ -1029,6 +1037,8 @@ public boolean containsValue(@GuardSatisfied @UnknownSignedness Object value) { * @throws NullPointerException if the specified key or value is null */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V put(K key, V value) { return putVal(key, value, false); } @@ -1110,6 +1120,8 @@ else if (f instanceof ReservationNode) * * @param m mappings to be stored in this map */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putAll(Map m) { tryPresize(m.size()); for (Map.Entry e : m.entrySet()) @@ -1125,6 +1137,8 @@ public void putAll(Map m) { * {@code null} if there was no mapping for {@code key} * @throws NullPointerException if the specified key is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V remove(@GuardSatisfied @UnknownSignedness Object key) { return replaceNode(key, null, null); } @@ -1210,6 +1224,8 @@ else if (f instanceof ReservationNode) /** * Removes all of the mappings from this map. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { long delta = 0L; // negative number of deletions int i = 0; @@ -1323,6 +1339,7 @@ public Collection values() { * * @return the hash code value for this map */ + @Pure public int hashCode() { int h = 0; Node[] t; @@ -1345,6 +1362,7 @@ public int hashCode() { * * @return a string representation of this map */ + @SideEffectFree public String toString() { Node[] t; int f = (t = table) == null ? 0 : t.length; @@ -1570,6 +1588,8 @@ private void readObject(java.io.ObjectInputStream s) * @throws NullPointerException if the specified key or value is null */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V putIfAbsent(K key, V value) { return putVal(key, value, true); } @@ -1579,6 +1599,8 @@ private void readObject(java.io.ObjectInputStream s) * * @throws NullPointerException if the specified key is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { if (key == null) throw new NullPointerException(); @@ -1590,6 +1612,8 @@ public boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSatis * * @throws NullPointerException if any of the arguments are null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { if (key == null || oldValue == null || newValue == null) throw new NullPointerException(); @@ -1603,6 +1627,8 @@ public boolean replace(K key, V oldValue, V newValue) { * or {@code null} if there was no mapping for the key * @throws NullPointerException if the specified key or value is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable V replace(K key, V value) { if (key == null || value == null) throw new NullPointerException(); @@ -1628,6 +1654,7 @@ public V getOrDefault(@GuardSatisfied @UnknownSignedness Object key, V defaultVa return (v = get(key)) == null ? defaultValue : v; } + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { if (action == null) throw new NullPointerException(); Node[] t; @@ -1639,6 +1666,7 @@ public void forEach(BiConsumer action) { } } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { if (function == null) throw new NullPointerException(); Node[] t; @@ -1722,6 +1750,7 @@ boolean removeValueIf(Predicate function) { * @throws RuntimeException or Error if the mappingFunction does so, * in which case the mapping is left unestablished */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfAbsent(K key, Function mappingFunction) { if (key == null || mappingFunction == null) throw new NullPointerException(); @@ -1834,6 +1863,7 @@ else if (f instanceof ReservationNode) * @throws RuntimeException or Error if the remappingFunction does so, * in which case the mapping is unchanged */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) throw new NullPointerException(); @@ -1928,6 +1958,7 @@ else if (f instanceof ReservationNode) * @throws RuntimeException or Error if the remappingFunction does so, * in which case the mapping is unchanged */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V compute(K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) @@ -2057,6 +2088,7 @@ else if (f instanceof ReservationNode) * @throws RuntimeException or Error if the remappingFunction does so, * in which case the mapping is unchanged */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { if (key == null || value == null || remappingFunction == null) throw new NullPointerException(); @@ -2255,6 +2287,7 @@ public static KeySetView newKeySet(int initialCapacity) { * @return the set view * @throws NullPointerException if the mappedValue is null */ + @SideEffectFree public KeySetView keySet(V mappedValue) { if (mappedValue == null) throw new NullPointerException(); @@ -3478,6 +3511,8 @@ static class BaseIterator extends Traverser { @Pure public final boolean hasMoreElements() { return next != null; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void remove() { Node p; if ((p = lastReturned) == null) @@ -3494,6 +3529,8 @@ static final class KeyIterator extends BaseIterator super(tab, size, index, limit, map); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final K next(@NonEmpty KeyIterator this) { Node p; if ((p = next) == null) @@ -3504,6 +3541,8 @@ public final K next(@NonEmpty KeyIterator this) { return k; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final K nextElement(@NonEmpty KeyIterator this) { return next(); } } @@ -3514,6 +3553,8 @@ static final class ValueIterator extends BaseIterator super(tab, size, index, limit, map); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final V next(@NonEmpty ValueIterator this) { Node p; if ((p = next) == null) @@ -3524,6 +3565,8 @@ public final V next(@NonEmpty ValueIterator this) { return v; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final V nextElement(@NonEmpty ValueIterator this) { return next(); } } @@ -3534,6 +3577,8 @@ static final class EntryIterator extends BaseIterator super(tab, size, index, limit, map); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final Map.Entry next(@NonEmpty EntryIterator this) { Node p; if ((p = next) == null) @@ -3558,13 +3603,18 @@ static final class MapEntry implements Map.Entry { this.val = val; this.map = map; } + @Pure public K getKey() { return key; } + @Pure public V getValue() { return val; } + @Pure public int hashCode() { return key.hashCode() ^ val.hashCode(); } + @SideEffectFree public String toString() { return Helpers.mapEntryToString(key, val); } + @Pure public boolean equals(Object o) { Object k, v; Map.Entry e; return ((o instanceof Map.Entry) && @@ -3582,6 +3632,8 @@ public boolean equals(Object o) { * could even have been removed, in which case the put will * re-establish). We do not and cannot guarantee more. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V setValue(V value) { if (value == null) throw new NullPointerException(); V v = val; @@ -4473,6 +4525,8 @@ abstract static sealed class CollectionView * Removes all of the elements from this view, by removing all * the mappings from the map backing this view. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void clear() { map.clear(); } @Pure public final int size() { return map.size(); } @@ -4495,6 +4549,8 @@ abstract static sealed class CollectionView @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public abstract boolean contains(@UnknownSignedness Object o); + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public abstract boolean remove(@UnknownSignedness Object o); private static final String OOME_MSG = "Required array size too large"; @@ -4564,6 +4620,7 @@ abstract static sealed class CollectionView * * @return a string representation of this collection */ + @SideEffectFree public final String toString() { StringBuilder sb = new StringBuilder(); sb.append('['); @@ -4591,6 +4648,8 @@ public final boolean containsAll(Collection c) { if (c == null) throw new NullPointerException(); boolean modified = false; @@ -4613,6 +4672,8 @@ public boolean removeAll(Collection c) { if (c == null) throw new NullPointerException(); boolean modified = false; @@ -4677,6 +4738,8 @@ public static final class KeySetView extends CollectionView * @return {@code true} if the backing map contained the specified key * @throws NullPointerException if the specified key is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { return map.remove(o) != null; } /** @@ -4701,6 +4764,8 @@ public Iterator iterator() { * for additions was provided */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(K e) { V v; if ((v = value) == null) @@ -4719,6 +4784,8 @@ public boolean add(K e) { * @throws UnsupportedOperationException if no default mapped value * for additions was provided */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { boolean added = false; V v; @@ -4731,6 +4798,7 @@ public boolean addAll(Collection c) { return added; } + @Pure public int hashCode() { int h = 0; for (K e : this) @@ -4738,6 +4806,7 @@ public int hashCode() { return h; } + @Pure public boolean equals(Object o) { Set c; return ((o instanceof Set) && @@ -4780,6 +4849,8 @@ public final boolean contains(@UnknownSignedness Object o) { return map.containsValue(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final boolean remove(@UnknownSignedness Object o) { if (o != null) { for (Iterator it = iterator(); it.hasNext();) { @@ -4801,9 +4872,13 @@ public final Iterator iterator() { } @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final boolean add(V e) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final boolean addAll(Collection c) { throw new UnsupportedOperationException(); } @@ -4820,6 +4895,8 @@ public final boolean addAll(Collection c) { return modified; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { return map.removeValueIf(filter); } @@ -4865,6 +4942,8 @@ public boolean contains(@UnknownSignedness Object o) { (v == r || v.equals(r))); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { Object k, v; Map.Entry e; return ((o instanceof Map.Entry) && @@ -4885,10 +4964,14 @@ public Iterator> iterator() { } @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(Entry e) { return map.putVal(e.getKey(), e.getValue(), false) == null; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection> c) { boolean added = false; for (Entry e : c) { @@ -4898,10 +4981,13 @@ public boolean addAll(Collection> c) { return added; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate> filter) { return map.removeEntryIf(filter); } + @Pure public final int hashCode() { int h = 0; Node[] t; @@ -4914,6 +5000,7 @@ public final int hashCode() { return h; } + @Pure public final boolean equals(Object o) { Set c; return ((o instanceof Set) && @@ -5296,6 +5383,7 @@ static final class SearchKeysTask super(p, b, i, f, t); this.searchFunction = searchFunction; this.result = result; } + @Pure public final U getRawResult() { return result.get(); } public final void compute() { final Function searchFunction; @@ -5340,6 +5428,7 @@ static final class SearchValuesTask super(p, b, i, f, t); this.searchFunction = searchFunction; this.result = result; } + @Pure public final U getRawResult() { return result.get(); } public final void compute() { final Function searchFunction; @@ -5384,6 +5473,7 @@ static final class SearchEntriesTask super(p, b, i, f, t); this.searchFunction = searchFunction; this.result = result; } + @Pure public final U getRawResult() { return result.get(); } public final void compute() { final Function, ? extends U> searchFunction; @@ -5428,6 +5518,7 @@ static final class SearchMappingsTask super(p, b, i, f, t); this.searchFunction = searchFunction; this.result = result; } + @Pure public final U getRawResult() { return result.get(); } public final void compute() { final BiFunction searchFunction; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index b3a9cf89266..ce2d2a01ebd 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -50,8 +50,9 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -842,6 +843,8 @@ private void initHeadTail(Node h, Node t) { * * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { linkFirst(e); } @@ -855,6 +858,8 @@ public void addFirst(E e) { * * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { linkLast(e); } @@ -866,6 +871,8 @@ public void addLast(E e) { * @return {@code true} (as specified by {@link Deque#offerFirst}) * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(E e) { linkFirst(e); return true; @@ -880,6 +887,8 @@ public boolean offerFirst(E e) { * @return {@code true} (as specified by {@link Deque#offerLast}) * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(E e) { linkLast(e); return true; @@ -920,6 +929,7 @@ public boolean offerLast(E e) { /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E getFirst(@NonEmpty ConcurrentLinkedDeque this) { return screenNullResult(peekFirst()); } @@ -927,10 +937,13 @@ public E getFirst(@NonEmpty ConcurrentLinkedDeque this) { /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E getLast(@NonEmpty ConcurrentLinkedDeque this) { return screenNullResult(peekLast()); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { restart: for (;;) { for (Node first = first(), p = first;;) { @@ -952,6 +965,8 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { restart: for (;;) { for (Node last = last(), p = last;;) { @@ -976,6 +991,8 @@ public E getLast(@NonEmpty ConcurrentLinkedDeque this) { /** * @throws NoSuchElementException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return screenNullResult(pollFirst()); } @@ -983,6 +1000,8 @@ public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque< /** * @throws NoSuchElementException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeLast(@GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return screenNullResult(pollLast()); } @@ -996,6 +1015,8 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return pollFirst(); } @Pure public @Nullable E peek() { return peekFirst(); } @@ -1020,21 +1045,28 @@ public boolean add(E e) { /** * @throws NoSuchElementException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(@NonEmpty @CanShrink ConcurrentLinkedDeque this) { return removeFirst(); } /** * @throws NoSuchElementException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E pop(@GuardSatisfied @NonEmpty @CanShrink ConcurrentLinkedDeque this) { return removeFirst(); } /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E element(@NonEmpty ConcurrentLinkedDeque this) { return getFirst(); } /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void push(E e) { addFirst(e); } /** @@ -1049,6 +1081,8 @@ public boolean add(E e) { * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeFirstOccurrence(@CanShrink ConcurrentLinkedDeque this, Object o) { Objects.requireNonNull(o); for (Node p = first(); p != null; p = succ(p)) { @@ -1075,6 +1109,8 @@ public boolean removeFirstOccurrence(@CanShrink ConcurrentLinkedDeque this, O * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeLastOccurrence(@CanShrink ConcurrentLinkedDeque this, Object o) { Objects.requireNonNull(o); for (Node p = last(); p != null; p = pred(p)) { @@ -1167,6 +1203,8 @@ public int size() { * @return {@code true} if the deque contained the specified element * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@CanShrink ConcurrentLinkedDeque this, @GuardSatisfied @UnknownSignedness Object o) { return removeFirstOccurrence(o); } @@ -1183,6 +1221,8 @@ public boolean remove(@CanShrink ConcurrentLinkedDeque this, @GuardSatisfied * of its elements are null * @throws IllegalArgumentException if the collection is this deque */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { if (c == this) // As historically specified in AbstractQueue#addAll @@ -1237,11 +1277,14 @@ else if (p.prev == p) // NEXT_TERMINATOR /** * Removes all of the elements from this deque. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink ConcurrentLinkedDeque this) { while (pollFirst() != null) ; } + @SideEffectFree public String toString() { String[] a = null; restart: for (;;) { @@ -1353,7 +1396,6 @@ else if (a != null && size <= a.length) { * this deque * @throws NullPointerException if the specified array is null */ - @SideEffectFree @SuppressWarnings("unchecked") public @Nullable T[] toArray(@PolyNull T[] a) { if (a == null) throw new NullPointerException(); @@ -1445,7 +1487,8 @@ public boolean hasNext() { return nextItem != null; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty AbstractItr this) { E item = nextItem; if (item == null) throw new NoSuchElementException(); @@ -1453,6 +1496,8 @@ public E next(@NonEmpty AbstractItr this) { return item; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { Node l = lastRet; if (l == null) throw new IllegalStateException(); @@ -1465,6 +1510,7 @@ public void remove() { /** Forward iterator */ private class Itr extends AbstractItr { Itr() {} // prevent access constructor creation + @SideEffectFree Node startNode() { return first(); } Node nextNode(Node p) { return succ(p); } } @@ -1472,6 +1518,7 @@ private class Itr extends AbstractItr { /** Descending iterator */ private class DescendingItr extends AbstractItr { DescendingItr() {} // prevent access constructor creation + @SideEffectFree Node startNode() { return last(); } Node nextNode(Node p) { return pred(p); } } @@ -1638,6 +1685,8 @@ private void readObject(java.io.ObjectInputStream s) /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@CanShrink ConcurrentLinkedDeque this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1646,6 +1695,8 @@ public boolean removeIf(@CanShrink ConcurrentLinkedDeque this, Predicate this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1654,6 +1705,8 @@ public boolean removeAll(@CanShrink ConcurrentLinkedDeque this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 18ee6f6aebc..20956d9251c 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -49,8 +49,9 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -298,6 +299,8 @@ public ConcurrentLinkedQueue(Collection c) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { return offer(e); } @@ -370,6 +373,8 @@ private Node skipDeadNodes(Node pred, Node c, Node p, Node q) { * @return {@code true} (as specified by {@link Queue#offer}) * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { final Node newNode = new Node(Objects.requireNonNull(e)); @@ -399,6 +404,8 @@ else if (p == q) } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { restartFromHead: for (;;) { for (Node h = head, p = h, q;; p = q) { @@ -543,6 +550,8 @@ public boolean contains(@GuardSatisfied @UnknownSignedness Object o) { * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@CanShrink ConcurrentLinkedQueue this, @GuardSatisfied @UnknownSignedness Object o) { if (o == null) return false; restartFromHead: for (;;) { @@ -579,6 +588,8 @@ public boolean remove(@CanShrink ConcurrentLinkedQueue this, @GuardSatisfied * of its elements are null * @throws IllegalArgumentException if the collection is this queue */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { if (c == this) // As historically specified in AbstractQueue#addAll @@ -627,6 +638,7 @@ else if (p == q) } } + @SideEffectFree public String toString() { String[] a = null; restartFromHead: for (;;) { @@ -736,7 +748,6 @@ else if (a != null && size <= a.length) { * this queue * @throws NullPointerException if the specified array is null */ - @SideEffectFree @SuppressWarnings("unchecked") public @Nullable T[] toArray(@PolyNull T[] a) { Objects.requireNonNull(a); @@ -802,7 +813,8 @@ public boolean hasNext() { return nextItem != null; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty Itr this) { final Node pred = nextNode; if (pred == null) throw new NoSuchElementException(); @@ -825,6 +837,8 @@ public E next(@NonEmpty Itr this) { // Default implementation of forEachRemaining is "good enough". + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { Node l = lastRet; if (l == null) throw new IllegalStateException(); @@ -991,6 +1005,8 @@ public Spliterator spliterator() { /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@CanShrink ConcurrentLinkedQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -999,6 +1015,8 @@ public boolean removeIf(@CanShrink ConcurrentLinkedQueue this, Predicate this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1007,11 +1025,15 @@ public boolean removeAll(@CanShrink ConcurrentLinkedQueue this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink ConcurrentLinkedQueue this) { bulkRemove(e -> true); } diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java index 018492522c1..c19b3b58ff0 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentMap.java @@ -35,13 +35,14 @@ package java.util.concurrent; -import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.checker.nullness.qual.EnsuresKeyFor; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; +import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.Map; import java.util.Objects; @@ -117,6 +118,7 @@ default V getOrDefault(Object key, V defaultValue) { * @since 1.8 */ @Override + @DoesNotUnrefineReceiver("modifiability") default void forEach(BiConsumer action) { Objects.requireNonNull(action); for (Map.Entry entry : entrySet()) { @@ -165,6 +167,8 @@ default void forEach(BiConsumer action) { * or value prevents it from being stored in this map */ @EnsuresKeyFor(value={"#1"}, map={"this"}) + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable V putIfAbsent(K key, V value); /** @@ -196,6 +200,8 @@ default void forEach(BiConsumer action) { * and this map does not permit null keys or values * (optional) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean remove(@UnknownSignedness Object key, @UnknownSignedness Object value); /** @@ -228,6 +234,8 @@ default void forEach(BiConsumer action) { * @throws IllegalArgumentException if some property of a specified key * or value prevents it from being stored in this map */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") boolean replace(K key, V oldValue, V newValue); /** @@ -260,6 +268,8 @@ default void forEach(BiConsumer action) { * @throws IllegalArgumentException if some property of the specified key * or value prevents it from being stored in this map */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") @Nullable V replace(K key, V value); /** @@ -293,6 +303,7 @@ default void forEach(BiConsumer action) { * @since 1.8 */ @Override + @DoesNotUnrefineReceiver("modifiability") default void replaceAll(BiFunction function) { Objects.requireNonNull(function); forEach((k,v) -> { @@ -333,6 +344,7 @@ default void replaceAll(BiFunction function) * @since 1.8 */ @Override + @DoesNotUnrefineReceiver("modifiability") default @PolyNull V computeIfAbsent(K key, Function mappingFunction) { Objects.requireNonNull(mappingFunction); @@ -375,6 +387,7 @@ default void replaceAll(BiFunction function) * @since 1.8 */ @Override + @DoesNotUnrefineReceiver("modifiability") default @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); @@ -423,6 +436,7 @@ default void replaceAll(BiFunction function) * @since 1.8 */ @Override + @DoesNotUnrefineReceiver("modifiability") default @PolyNull V compute(K key, BiFunction remappingFunction) { retry: for (;;) { @@ -483,6 +497,7 @@ else if ((oldValue = putIfAbsent(key, newValue)) == null) * @since 1.8 */ @Override + @DoesNotUnrefineReceiver("modifiability") default @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { Objects.requireNonNull(remappingFunction); diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index f201d63bcb8..1ff2b80f208 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -157,6 +157,7 @@ ConcurrentNavigableMap subMap(K fromKey, boolean fromInclusive, * * @return a navigable set view of the keys in this map */ + @SideEffectFree NavigableSet keySet(); /** diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index bda48d78230..5da0d611337 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -46,7 +46,8 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -1134,6 +1135,7 @@ public ConcurrentSkipListMap(SortedMap m) { * * @return a shallow copy of this map */ + @SideEffectFree public ConcurrentSkipListMap clone() { try { @SuppressWarnings("unchecked") @@ -1322,6 +1324,7 @@ public boolean containsKey(@GuardSatisfied @UnknownSignedness Object key) { * with the keys currently in the map * @throws NullPointerException if the specified key is null */ + @Pure public V get(Object key) { return doGet(key); } @@ -1356,6 +1359,8 @@ public V getOrDefault(@GuardSatisfied @UnknownSignedness Object key, V defaultVa * with the keys currently in the map * @throws NullPointerException if the specified key or value is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V put(K key, V value) { if (value == null) throw new NullPointerException(); @@ -1372,6 +1377,8 @@ public V put(K key, V value) { * with the keys currently in the map * @throws NullPointerException if the specified key is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V remove(@GuardSatisfied @UnknownSignedness Object key) { return doRemove(key, null); } @@ -1427,6 +1434,8 @@ public boolean isEmpty() { /** * Removes all of the mappings from this map. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { Index h, r, d; Node b; VarHandle.acquireFence(); @@ -1472,6 +1481,7 @@ else if ((d = h.down) != null) // remove levels * or the mappingFunction is null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfAbsent(K key, Function mappingFunction) { if (key == null || mappingFunction == null) @@ -1496,6 +1506,7 @@ else if ((d = h.down) != null) // remove levels * or the remappingFunction is null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V computeIfPresent(K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) @@ -1528,6 +1539,7 @@ else if (doRemove(key, v) != null) * or the remappingFunction is null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V compute(K key, BiFunction remappingFunction) { if (key == null || remappingFunction == null) @@ -1567,6 +1579,7 @@ else if (doRemove(key, v) != null) * or the remappingFunction is null * @since 1.8 */ + @DoesNotUnrefineReceiver("modifiability") public @PolyNull V merge(K key, @NonNull V value, BiFunction remappingFunction) { if (key == null || value == null || remappingFunction == null) @@ -1629,6 +1642,7 @@ else if (doRemove(key, v) != null) * * @return a navigable set view of the keys in this map */ + @SideEffectFree public NavigableSet keySet() { KeySet ks; if ((ks = keySet) != null) return ks; @@ -1661,6 +1675,7 @@ public NavigableSet navigableKeySet() { *

    The view's iterators and spliterators are * weakly consistent. */ + @SideEffectFree public Collection values() { Values vs; if ((vs = values) != null) return vs; @@ -1806,6 +1821,8 @@ public boolean equals(@Nullable Object o) { * with the keys currently in the map * @throws NullPointerException if the specified key or value is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putIfAbsent(K key, V value) { if (value == null) throw new NullPointerException(); @@ -1819,6 +1836,8 @@ public V putIfAbsent(K key, V value) { * with the keys currently in the map * @throws NullPointerException if the specified key is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSatisfied @UnknownSignedness Object value) { if (key == null) throw new NullPointerException(); @@ -1832,6 +1851,8 @@ public boolean remove(@GuardSatisfied @UnknownSignedness Object key, @GuardSatis * with the keys currently in the map * @throws NullPointerException if any of the arguments are null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { if (key == null || oldValue == null || newValue == null) throw new NullPointerException(); @@ -1857,6 +1878,8 @@ public boolean replace(K key, V oldValue, V newValue) { * with the keys currently in the map * @throws NullPointerException if the specified key or value is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V replace(K key, V value) { if (key == null || value == null) throw new NullPointerException(); @@ -1871,6 +1894,7 @@ public V replace(K key, V value) { /* ------ SortedMap API methods ------ */ + @Pure public Comparator comparator() { return comparator; } @@ -1903,6 +1927,8 @@ public K lastKey(@NonEmpty ConcurrentSkipListMap this) { * @throws UnsupportedOperationException always * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putFirst(K k, V v) { throw new UnsupportedOperationException(); } @@ -1915,6 +1941,8 @@ public V putFirst(K k, V v) { * @throws UnsupportedOperationException always * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putLast(K k, V v) { throw new UnsupportedOperationException(); } @@ -2113,6 +2141,8 @@ public Map.Entry lastEntry() { * The returned entry does not support * the {@code Entry.setValue} method. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry pollFirstEntry() { return doRemoveFirstEntry(); } @@ -2123,6 +2153,8 @@ public Map.Entry pollFirstEntry() { * The returned entry does not support * the {@code Entry.setValue} method. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry pollLastEntry() { return doRemoveLastEntry(); } @@ -2163,6 +2195,8 @@ final void advance(Node b) { next = n; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void remove() { Node n; K k; if ((n = lastReturned) == null || (k = n.key) == null) @@ -2175,6 +2209,8 @@ public final void remove() { } final class ValueIterator extends Iter { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V next(@NonEmpty ValueIterator this) { V v; if ((v = nextValue) == null) @@ -2185,6 +2221,8 @@ public V next(@NonEmpty ValueIterator this) { } final class KeyIterator extends Iter { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K next(@NonEmpty KeyIterator this) { Node n; if ((n = next) == null) @@ -2196,6 +2234,8 @@ public K next(@NonEmpty KeyIterator this) { } final class EntryIterator extends Iter> { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry next(@NonEmpty EntryIterator this) { Node n; if ((n = next) == null) @@ -2235,28 +2275,41 @@ static final class KeySet @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@UnknownSignedness Object o) { return m.containsKey(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { return m.remove(o) != null; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } public K lower(K e) { return m.lowerKey(e); } public K floor(K e) { return m.floorKey(e); } public K ceiling(K e) { return m.ceilingKey(e); } public K higher(K e) { return m.higherKey(e); } + @Pure public Comparator comparator() { return m.comparator(); } + @SideEffectFree public K first() { return m.firstKey(); } + @SideEffectFree public K last() { return m.lastKey(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K pollFirst() { Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K pollLast() { Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); } + @SideEffectFree public Iterator iterator() { return (m instanceof ConcurrentSkipListMap) ? ((ConcurrentSkipListMap)m).new KeyIterator() : ((SubMap)m).new SubMapKeyIterator(); } + @Pure public boolean equals(Object o) { if (o == this) return true; @@ -2269,6 +2322,7 @@ public boolean equals(Object o) { return false; } } + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(KeySet<@PolyNull @PolySigned K,V> this) { return toList(this).toArray(); } public @Nullable T[] toArray(@PolyNull T[] a) { return toList(this).toArray(a); } public Iterator descendingIterator() { @@ -2281,18 +2335,23 @@ public NavigableSet subSet(K fromElement, return new KeySet<>(m.subMap(fromElement, fromInclusive, toElement, toInclusive)); } + @SideEffectFree public NavigableSet headSet(K toElement, boolean inclusive) { return new KeySet<>(m.headMap(toElement, inclusive)); } + @SideEffectFree public NavigableSet tailSet(K fromElement, boolean inclusive) { return new KeySet<>(m.tailMap(fromElement, inclusive)); } + @SideEffectFree public NavigableSet subSet(K fromElement, K toElement) { return subSet(fromElement, true, toElement, false); } + @SideEffectFree public NavigableSet headSet(K toElement) { return headSet(toElement, false); } + @SideEffectFree public NavigableSet tailSet(K fromElement) { return tailSet(fromElement, true); } @@ -2300,6 +2359,7 @@ public NavigableSet descendingSet() { return new KeySet<>(m.descendingMap()); } + @SideEffectFree public Spliterator spliterator() { return (m instanceof ConcurrentSkipListMap) ? ((ConcurrentSkipListMap)m).keySpliterator() @@ -2312,6 +2372,7 @@ static final class Values extends AbstractCollection { Values(ConcurrentNavigableMap map) { m = map; } + @SideEffectFree public Iterator iterator() { return (m instanceof ConcurrentSkipListMap) ? ((ConcurrentSkipListMap)m).new ValueIterator() @@ -2325,16 +2386,22 @@ public Iterator iterator() { @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean contains(@UnknownSignedness Object o) { return m.containsValue(o); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } + @SideEffectFree public Object[] toArray() { return toList(this).toArray(); } public @Nullable T[] toArray(@PolyNull T[] a) { return toList(this).toArray(a); } + @SideEffectFree public Spliterator spliterator() { return (m instanceof ConcurrentSkipListMap) ? ((ConcurrentSkipListMap)m).valueSpliterator() : ((SubMap)m).new SubMapValueIterator(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { if (filter == null) throw new NullPointerException(); if (m instanceof ConcurrentSkipListMap) @@ -2358,6 +2425,7 @@ static final class EntrySet extends AbstractSet> { EntrySet(ConcurrentNavigableMap map) { m = map; } + @SideEffectFree public Iterator> iterator() { return (m instanceof ConcurrentSkipListMap) ? ((ConcurrentSkipListMap)m).new EntryIterator() @@ -2373,6 +2441,8 @@ public boolean contains(@UnknownSignedness Object o) { V v = m.get(e.getKey()); return v != null && v.equals(e.getValue()); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object o) { if (!(o instanceof Map.Entry)) return false; @@ -2389,9 +2459,12 @@ public boolean isEmpty() { public int size() { return m.size(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } + @Pure public boolean equals(Object o) { if (o == this) return true; @@ -2404,14 +2477,18 @@ public boolean equals(Object o) { return false; } } + @SideEffectFree public Object[] toArray() { return toList(this).toArray(); } public @Nullable T[] toArray(@PolyNull T[] a) { return toList(this).toArray(a); } + @SideEffectFree public Spliterator> spliterator() { return (m instanceof ConcurrentSkipListMap) ? ((ConcurrentSkipListMap)m).entrySpliterator() : ((SubMap)m).new SubMapEntryIterator(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate> filter) { if (filter == null) throw new NullPointerException(); if (m instanceof ConcurrentSkipListMap) @@ -2693,16 +2770,21 @@ public boolean containsKey(@UnknownSignedness Object key) { return inBounds(key, m.comparator) && m.containsKey(key); } + @Pure public V get(Object key) { if (key == null) throw new NullPointerException(); return (!inBounds(key, m.comparator)) ? null : m.get(key); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V put(K key, V value) { checkKeyBounds(key, m.comparator); return m.put(key, value); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V remove(Object key) { return (!inBounds(key, m.comparator)) ? null : m.remove(key); } @@ -2742,6 +2824,8 @@ public boolean containsValue(@UnknownSignedness Object value) { return false; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { Comparator cmp = m.comparator; for (ConcurrentSkipListMap.Node n = loNode(cmp); @@ -2754,20 +2838,28 @@ public void clear() { /* ---------------- ConcurrentMap API methods -------------- */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V putIfAbsent(K key, V value) { checkKeyBounds(key, m.comparator); return m.putIfAbsent(key, value); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@UnknownSignedness Object key, @UnknownSignedness Object value) { return inBounds(key, m.comparator) && m.remove(key, value); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean replace(K key, V oldValue, V newValue) { checkKeyBounds(key, m.comparator); return m.replace(key, oldValue, newValue); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V replace(K key, V value) { checkKeyBounds(key, m.comparator); return m.replace(key, value); @@ -2775,6 +2867,7 @@ public V replace(K key, V value) { /* ---------------- SortedMap API methods -------------- */ + @Pure public Comparator comparator() { Comparator cmp = m.comparator(); if (isDescending) @@ -2917,16 +3010,21 @@ public Map.Entry lastEntry() { return isDescending ? lowestEntry() : highestEntry(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry pollFirstEntry() { return isDescending ? removeHighest() : removeLowest(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry pollLastEntry() { return isDescending ? removeLowest() : removeHighest(); } /* ---------------- Submap Views -------------- */ + @SideEffectFree public NavigableSet keySet() { KeySet ks; if ((ks = keySetView) != null) return ks; @@ -2940,6 +3038,7 @@ public NavigableSet navigableKeySet() { return keySetView = new KeySet<>(this); } + @SideEffectFree public Collection values() { Values vs; if ((vs = valuesView) != null) return vs; @@ -3038,6 +3137,8 @@ private void descend() { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { Node l = lastReturned; if (l == null) @@ -3070,6 +3171,8 @@ public long estimateSize() { } final class SubMapValueIterator extends SubMapIter { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public V next(@NonEmpty SubMapValueIterator this) { V v = nextValue; advance(); @@ -3081,6 +3184,8 @@ public int characteristics() { } final class SubMapKeyIterator extends SubMapIter { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public K next(@NonEmpty SubMapKeyIterator this) { Node n = next; advance(); @@ -3096,6 +3201,8 @@ public final Comparator getComparator() { } final class SubMapEntryIterator extends SubMapIter> { + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Map.Entry next(@NonEmpty SubMapEntryIterator this) { Node n = next; V v = nextValue; @@ -3110,6 +3217,7 @@ public int characteristics() { // default Map method overrides + @DoesNotUnrefineReceiver("modifiability") public void forEach(BiConsumer action) { if (action == null) throw new NullPointerException(); Node b, n; V v; @@ -3122,6 +3230,7 @@ public void forEach(BiConsumer action) { } } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction function) { if (function == null) throw new NullPointerException(); Node b, n; V v; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 1e02531ced6..b9bd22662de 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -48,6 +48,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.lang.reflect.Field; import java.util.AbstractSet; @@ -261,6 +262,8 @@ public boolean contains(@GuardSatisfied @UnknownSignedness Object o) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { return m.putIfAbsent(e, Boolean.TRUE) == null; } @@ -279,6 +282,8 @@ public boolean add(E e) { * with the elements currently in this set * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @UnknownSignedness Object o) { return m.remove(o, Boolean.TRUE); } @@ -286,6 +291,8 @@ public boolean remove(@GuardSatisfied @UnknownSignedness Object o) { /** * Removes all of the elements from this set. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { m.clear(); } @@ -354,6 +361,8 @@ public boolean equals(@Nullable Object o) { * @throws NullPointerException if the specified collection or any * of its elements are null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { // Override AbstractSet version to avoid unnecessary call to size() boolean modified = false; @@ -397,11 +406,15 @@ public E higher(E e) { return m.higherKey(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst() { Map.Entry e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast() { Map.Entry e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); @@ -418,6 +431,7 @@ public E higher(E e) { /** * @throws java.util.NoSuchElementException {@inheritDoc} */ + @SideEffectFree public E first(@NonEmpty ConcurrentSkipListSet this) { return m.firstKey(); } @@ -425,6 +439,7 @@ public E first(@NonEmpty ConcurrentSkipListSet this) { /** * @throws java.util.NoSuchElementException {@inheritDoc} */ + @SideEffectFree public E last(@NonEmpty ConcurrentSkipListSet this) { return m.lastKey(); } @@ -473,6 +488,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code toElement} is null * @throws IllegalArgumentException {@inheritDoc} */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty NavigableSet headSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E toElement, boolean inclusive) { return new ConcurrentSkipListSet(m.headMap(toElement, inclusive)); } @@ -482,6 +498,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code fromElement} is null * @throws IllegalArgumentException {@inheritDoc} */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty NavigableSet tailSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, boolean inclusive) { return new ConcurrentSkipListSet(m.tailMap(fromElement, inclusive)); } @@ -492,6 +509,7 @@ public void addLast(E e) { * {@code toElement} is null * @throws IllegalArgumentException {@inheritDoc} */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty NavigableSet subSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement, E toElement) { return subSet(fromElement, true, toElement, false); } @@ -501,6 +519,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code toElement} is null * @throws IllegalArgumentException {@inheritDoc} */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty NavigableSet headSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E toElement) { return headSet(toElement, false); } @@ -510,6 +529,7 @@ public void addLast(E e) { * @throws NullPointerException if {@code fromElement} is null * @throws IllegalArgumentException {@inheritDoc} */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty NavigableSet tailSet(@PolyGrowShrink @PolyNonEmpty ConcurrentSkipListSet this, E fromElement) { return tailSet(fromElement, true); } diff --git a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java index e7566d9e5cf..01701d98047 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -49,7 +49,8 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.lang.invoke.VarHandle; import java.lang.reflect.Field; @@ -260,6 +261,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { /** * {@inheritDoc} */ + @Pure public int indexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { Object[] es = getArray(); return indexOfRange(o, es, 0, es.length); @@ -280,6 +282,7 @@ public int indexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * {@code -1} if the element is not found. * @throws IndexOutOfBoundsException if the specified index is negative */ + @Pure public int indexOf(E e, int index) { Object[] es = getArray(); return indexOfRange(e, es, index, es.length); @@ -288,6 +291,7 @@ public int indexOf(E e, int index) { /** * {@inheritDoc} */ + @Pure public int lastIndexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { Object[] es = getArray(); return lastIndexOfRange(o, es, 0, es.length); @@ -309,6 +313,7 @@ public int lastIndexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * @throws IndexOutOfBoundsException if the specified index is greater * than or equal to the current size of this list */ + @Pure public int lastIndexOf(E e, int index) { Object[] es = getArray(); return lastIndexOfRange(e, es, 0, index + 1); @@ -320,6 +325,7 @@ public int lastIndexOf(E e, int index) { * * @return a clone of this list */ + @SideEffectFree public Object clone() { try { @SuppressWarnings("unchecked") @@ -349,6 +355,7 @@ public Object clone() { * * @return an array containing all the elements in this list */ + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(CopyOnWriteArrayList<@PolyNull @PolySigned E> this) { return getArray().clone(); } @@ -408,6 +415,7 @@ public Object clone() { // Positional Access Operations @SuppressWarnings("unchecked") + @Pure static E elementAt(Object[] a, int index) { return (E) a[index]; } @@ -421,6 +429,7 @@ static String outOfBounds(int index, int size) { * * @throws IndexOutOfBoundsException {@inheritDoc} */ + @Pure public E get(int index) { return elementAt(getArray(), index); } @@ -431,6 +440,7 @@ public E get(int index) { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getFirst() { Object[] es = getArray(); if (es.length == 0) @@ -445,6 +455,7 @@ public E getFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + @Pure public E getLast() { Object[] es = getArray(); if (es.length == 0) @@ -459,6 +470,8 @@ public E getLast() { * * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(int index, E element) { synchronized (lock) { Object[] es = getArray(); @@ -481,6 +494,8 @@ public E set(int index, E element) { * @return {@code true} (as specified by {@link Collection#add}) */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { synchronized (lock) { Object[] es = getArray(); @@ -499,6 +514,8 @@ public boolean add(E e) { * * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(int index, E element) { synchronized (lock) { Object[] es = getArray(); @@ -525,6 +542,8 @@ public void add(int index, E element) { * * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { add(0, e); } @@ -534,6 +553,8 @@ public void addFirst(E e) { * * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { synchronized (lock) { add(getArray().length, e); @@ -547,6 +568,8 @@ public void addLast(E e) { * * @throws IndexOutOfBoundsException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(@GuardSatisfied @CanShrink CopyOnWriteArrayList this, int index) { synchronized (lock) { Object[] es = getArray(); @@ -573,6 +596,8 @@ public E remove(@GuardSatisfied @CanShrink CopyOnWriteArrayList this, int ind * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeFirst() { synchronized (lock) { if (getArray().length == 0) @@ -588,6 +613,8 @@ public E removeFirst() { * @throws NoSuchElementException {@inheritDoc} * @since 21 */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeLast() { synchronized (lock) { int size = getArray().length; @@ -610,6 +637,8 @@ public E removeLast() { * @param o element to be removed from this list, if present * @return {@code true} if this list contained the specified element */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@CanShrink CopyOnWriteArrayList this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { Object[] snapshot = getArray(); int index = indexOfRange(o, snapshot, 0, snapshot.length); @@ -690,6 +719,8 @@ void removeRange(@GuardSatisfied @CanShrink CopyOnWriteArrayList this, int fr * @param e element to be added to this list, if absent * @return {@code true} if the element was added */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addIfAbsent(E e) { Object[] snapshot = getArray(); return indexOfRange(e, snapshot, 0, snapshot.length) < 0 @@ -758,6 +789,8 @@ public boolean containsAll(Collection c) { * or if the specified collection is null * @see #remove(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@CanShrink CopyOnWriteArrayList this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -779,6 +812,8 @@ public boolean removeAll(@CanShrink CopyOnWriteArrayList this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); @@ -795,6 +830,8 @@ public boolean retainAll(@GuardSatisfied @CanShrink CopyOnWriteArrayList this * @throws NullPointerException if the specified collection is null * @see #addIfAbsent(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int addAllAbsent(Collection c) { Object[] cs = c.toArray(); if (c.getClass() != ArrayList.class) { @@ -826,6 +863,8 @@ public int addAllAbsent(Collection c) { * Removes all of the elements from this list. * The list will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink CopyOnWriteArrayList this) { synchronized (lock) { setArray(new Object[0]); @@ -842,6 +881,8 @@ public void clear(@GuardSatisfied @CanShrink CopyOnWriteArrayList this) { * @throws NullPointerException if the specified collection is null * @see #add(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ? ((CopyOnWriteArrayList)c).getArray() : c.toArray(); @@ -879,6 +920,8 @@ public boolean addAll(Collection c) { * @throws NullPointerException if the specified collection is null * @see #add(int,Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { Object[] cs = c.toArray(); synchronized (lock) { @@ -919,6 +962,8 @@ public void forEach(Consumer action) { /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@CanShrink CopyOnWriteArrayList this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -976,6 +1021,7 @@ boolean bulkRemove(Predicate filter, int i, int end) { } } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { synchronized (lock) { replaceAllRange(operator, 0, getArray().length); @@ -991,6 +1037,8 @@ void replaceAllRange(UnaryOperator operator, int i, int end) { setArray(es); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { synchronized (lock) { sortRange(c, 0, getArray().length); @@ -1064,6 +1112,7 @@ private void readObject(java.io.ObjectInputStream s) * * @return a string representation of this list */ + @SideEffectFree public String toString() { return Arrays.toString(getArray()); } @@ -1115,6 +1164,7 @@ private static int hashCodeOfRange(Object[] es, int from, int to) { * * @return the hash code value for this list */ + @Pure public int hashCode() { Object[] es = getArray(); return hashCodeOfRange(es, 0, es.length); @@ -1130,6 +1180,7 @@ public int hashCode() { * * @return an iterator over the elements in this list in proper sequence */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty CopyOnWriteArrayList this) { return new COWIterator(getArray(), 0); } @@ -1179,6 +1230,7 @@ public int hashCode() { * @return a {@code Spliterator} over the elements in this list * @since 1.8 */ + @SideEffectFree public Spliterator spliterator() { return Spliterators.spliterator (getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED); @@ -1207,7 +1259,8 @@ public boolean hasPrevious() { } @SuppressWarnings("unchecked") - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty COWIterator this) { if (! hasNext()) throw new NoSuchElementException(); @@ -1215,7 +1268,7 @@ public E next(@NonEmpty COWIterator this) { } @SuppressWarnings("unchecked") - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public E previous() { if (! hasPrevious()) throw new NoSuchElementException(); @@ -1237,6 +1290,8 @@ public int previousIndex() { * @throws UnsupportedOperationException always; {@code remove} * is not supported by this iterator. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { throw new UnsupportedOperationException(); } @@ -1246,6 +1301,8 @@ public void remove() { * @throws UnsupportedOperationException always; {@code set} * is not supported by this iterator. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { throw new UnsupportedOperationException(); } @@ -1255,6 +1312,8 @@ public void set(E e) { * @throws UnsupportedOperationException always; {@code add} * is not supported by this iterator. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { throw new UnsupportedOperationException(); } @@ -1285,6 +1344,7 @@ public void forEachRemaining(Consumer action) { * @return a view of the specified range within this list * @throws IndexOutOfBoundsException {@inheritDoc} */ + @SideEffectFree public @PolyGrowShrink List subList(@PolyGrowShrink CopyOnWriteArrayList this, int fromIndex, int toIndex) { synchronized (lock) { Object[] es = getArray(); @@ -1337,6 +1397,7 @@ private void rangeCheckForAdd(int index) { throw new IndexOutOfBoundsException(outOfBounds(index, size)); } + @SideEffectFree public Object[] toArray() { final Object[] es; final int offset; @@ -1370,6 +1431,7 @@ public Object[] toArray() { } } + @Pure public int indexOf(Object o) { final Object[] es; final int offset; @@ -1383,6 +1445,7 @@ public int indexOf(Object o) { return (i == -1) ? -1 : i - offset; } + @Pure public int lastIndexOf(Object o) { final Object[] es; final int offset; @@ -1424,10 +1487,12 @@ public boolean isEmpty() { return size() == 0; } + @SideEffectFree public String toString() { return Arrays.toString(toArray()); } + @Pure public int hashCode() { final Object[] es; final int offset; @@ -1440,6 +1505,7 @@ public int hashCode() { return hashCodeOfRange(es, offset, offset + size); } + @Pure public boolean equals(Object o) { if (o == this) return true; @@ -1462,6 +1528,8 @@ public boolean equals(Object o) { return !it.hasNext(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(int index, E element) { synchronized (lock) { rangeCheck(index); @@ -1472,6 +1540,7 @@ public E set(int index, E element) { } } + @Pure public E get(int index) { synchronized (lock) { rangeCheck(index); @@ -1490,6 +1559,7 @@ public E getFirst() { } } + @Pure public E getLast() { synchronized (lock) { if (size == 0) @@ -1499,6 +1569,7 @@ public E getLast() { } } + @Pure public int size() { synchronized (lock) { checkForComodification(); @@ -1507,6 +1578,8 @@ public int size() { } @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E element) { synchronized (lock) { checkForComodification(); @@ -1517,6 +1590,8 @@ public boolean add(E element) { return true; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(int index, E element) { synchronized (lock) { checkForComodification(); @@ -1527,16 +1602,22 @@ public void add(int index, E element) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { add(0, e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { synchronized (lock) { add(size, e); } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { synchronized (lock) { final Object[] oldArray = getArrayChecked(); @@ -1547,6 +1628,8 @@ public boolean addAll(Collection c) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { synchronized (lock) { rangeCheckForAdd(index); @@ -1558,6 +1641,8 @@ public boolean addAll(int index, Collection c) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { synchronized (lock) { checkForComodification(); @@ -1567,6 +1652,8 @@ public void clear() { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(int index) { synchronized (lock) { rangeCheck(index); @@ -1578,6 +1665,8 @@ public E remove(int index) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeFirst() { synchronized (lock) { if (size == 0) @@ -1587,6 +1676,8 @@ public E removeFirst() { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeLast() { synchronized (lock) { if (size == 0) @@ -1596,6 +1687,8 @@ public E removeLast() { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@Nullable @UnknownSignedness Object o) { synchronized (lock) { checkForComodification(); @@ -1607,6 +1700,7 @@ public boolean remove(@Nullable @UnknownSignedness Object o) { } } + @SideEffectFree public Iterator iterator() { return listIterator(0); } @@ -1624,6 +1718,7 @@ public ListIterator listIterator(int index) { } } + @SideEffectFree public List subList(int fromIndex, int toIndex) { synchronized (lock) { checkForComodification(); @@ -1645,6 +1740,7 @@ public void forEach(Consumer action) { action.accept(elementAt(es, i)); } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { synchronized (lock) { checkForComodification(); @@ -1653,6 +1749,8 @@ public void replaceAll(UnaryOperator operator) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { synchronized (lock) { checkForComodification(); @@ -1661,16 +1759,22 @@ public void sort(Comparator c) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1686,6 +1790,7 @@ private boolean bulkRemove(Predicate filter) { } } + @SideEffectFree public Spliterator spliterator() { synchronized (lock) { return Spliterators.spliterator( @@ -1716,7 +1821,8 @@ public boolean hasNext() { return nextIndex() < size; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty COWSubListIterator this) { if (hasNext()) return it.next(); @@ -1724,6 +1830,7 @@ public E next(@NonEmpty COWSubListIterator this) { throw new NoSuchElementException(); } + @Pure public boolean hasPrevious() { return previousIndex() >= 0; } @@ -1735,10 +1842,12 @@ public E previous() { throw new NoSuchElementException(); } + @Pure public int nextIndex() { return it.nextIndex() - offset; } + @Pure public int previousIndex() { return it.previousIndex() - offset; } @@ -1798,8 +1907,13 @@ class DescendingIterator implements Iterator { it = base.listIterator(base.size()); } } + @Pure public boolean hasNext() { return it.hasPrevious(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next() { return it.previous(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { it.remove(); } } @@ -1816,14 +1930,18 @@ class DescendingListIterator implements ListIterator { } } + @Pure public boolean hasNext() { return it.hasPrevious(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next() { return it.previous(); } + @Pure public boolean hasPrevious() { return it.hasNext(); } @@ -1832,22 +1950,30 @@ public E previous() { return it.next(); } + @Pure public int nextIndex() { return size - it.nextIndex(); } + @Pure public int previousIndex() { return nextIndex() - 1; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void set(E e) { throw new UnsupportedOperationException(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(E e) { throw new UnsupportedOperationException(); } @@ -1860,21 +1986,27 @@ public void forEach(Consumer action) { action.accept(e); } + @SideEffectFree public Iterator iterator() { return new DescendingIterator(); } + @SideEffectFree public Spliterator spliterator() { return Spliterators.spliterator(this, Spliterator.ORDERED); } // ========== Collection ========== + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { base.add(0, e); return true; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { @SuppressWarnings("unchecked") E[] es = (E[]) c.toArray(); @@ -1887,19 +2019,24 @@ public boolean addAll(Collection c) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { base.clear(); } + @Pure public boolean contains(Object o) { return base.contains(o); } + @Pure public boolean containsAll(Collection c) { return base.containsAll(c); } // copied from AbstractList + @Pure public boolean equals(Object o) { if (o == this) return true; @@ -1918,6 +2055,7 @@ public boolean equals(Object o) { } // copied from AbstractList + @Pure public int hashCode() { int hashCode = 1; for (E e : this) @@ -1925,6 +2063,7 @@ public int hashCode() { return hashCode; } + @Pure public boolean isEmpty() { return base.isEmpty(); } @@ -1933,6 +2072,8 @@ public Stream parallelStream() { return StreamSupport.stream(spliterator(), true); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(Object o) { synchronized (lock) { int index = indexOf(o); @@ -1943,14 +2084,19 @@ public boolean remove(Object o) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return base.removeAll(c); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean retainAll(Collection c) { return base.retainAll(c); } + @Pure public int size() { return base.size(); } @@ -1959,6 +2105,7 @@ public Stream stream() { return StreamSupport.stream(spliterator(), false); } + @SideEffectFree public Object[] toArray() { return ArraysSupport.reverse(base.toArray()); } @@ -1974,6 +2121,7 @@ public T[] toArray(IntFunction generator) { } // copied from AbstractCollection + @SideEffectFree public String toString() { Iterator it = iterator(); if (! it.hasNext()) @@ -1992,20 +2140,28 @@ public String toString() { // ========== List ========== + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void add(int index, E element) { synchronized (lock) { base.add(base.size() - index, element); } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { base.add(e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { base.add(0, e); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(int index, Collection c) { @SuppressWarnings("unchecked") E[] es = (E[]) c.toArray(); @@ -2020,12 +2176,14 @@ public boolean addAll(int index, Collection c) { } } + @Pure public E get(int i) { synchronized (lock) { return base.get(base.size() - i - 1); } } + @Pure public E getFirst() { synchronized (lock) { int size = base.size(); @@ -2036,6 +2194,7 @@ public E getFirst() { } } + @Pure public E getLast() { synchronized (lock) { if (base.size() == 0) @@ -2045,6 +2204,7 @@ public E getLast() { } } + @Pure public int indexOf(Object o) { synchronized (lock) { int i = base.lastIndexOf(o); @@ -2052,6 +2212,7 @@ public int indexOf(Object o) { } } + @Pure public int lastIndexOf(Object o) { synchronized (lock) { int i = base.indexOf(o); @@ -2067,12 +2228,16 @@ public ListIterator listIterator(int index) { return new DescendingListIterator(index); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(int index) { synchronized (lock) { return base.remove(base.size() - index - 1); } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeFirst() { synchronized (lock) { int size = base.size(); @@ -2083,6 +2248,8 @@ public E removeFirst() { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeLast() { synchronized (lock) { if (base.size() == 0) @@ -2092,24 +2259,32 @@ public E removeLast() { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { return base.removeIf(filter); } + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(UnaryOperator operator) { base.replaceAll(operator); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void sort(Comparator c) { base.sort(Collections.reverseOrder(c)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E set(int index, E element) { synchronized (lock) { return base.set(base.size() - index - 1, element); } } + @SideEffectFree public List subList(int fromIndex, int toIndex) { synchronized (lock) { int size = base.size(); diff --git a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java index 94d82680c8c..da70f7bf664 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -49,6 +49,7 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import jdk.internal.misc.Unsafe; @@ -200,6 +201,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * * @return an array containing all the elements in this set */ + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(CopyOnWriteArraySet<@PolyNull @PolySigned E> this) { return al.toArray(); } @@ -253,6 +255,8 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * Removes all of the elements from this set. * The set will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { al.clear(); } @@ -268,6 +272,8 @@ public void clear() { * @param o object to be removed from this set, if present * @return {@code true} if this set contained the specified element */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object o) { return al.remove(o); } @@ -285,6 +291,8 @@ public boolean remove(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * element */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { return al.addIfAbsent(e); } @@ -355,6 +363,8 @@ private static int compareSets(Object[] snapshot, Set set) { * @throws NullPointerException if the specified collection is null * @see #add(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { return al.addAllAbsent(c) > 0; } @@ -376,6 +386,8 @@ public boolean addAll(Collection c) { * or if the specified collection is null * @see #remove(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(Collection c) { return al.removeAll(c); } @@ -399,6 +411,8 @@ public boolean removeAll(Collection c) { return al.retainAll(c); } @@ -414,6 +428,7 @@ public boolean retainAll(Collection iterator(@PolyGrowShrink @PolyNonEmpty CopyOnWriteArraySet this) { return al.iterator(); } @@ -445,6 +460,8 @@ public boolean equals(@Nullable Object o) { /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(Predicate filter) { return al.removeIf(filter); } @@ -471,6 +488,7 @@ public void forEach(Consumer action) { * @return a {@code Spliterator} over the elements in this set * @since 1.8 */ + @SideEffectFree public Spliterator spliterator() { return Spliterators.spliterator (al.getArray(), Spliterator.IMMUTABLE | Spliterator.DISTINCT); diff --git a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java index 368384198af..4463a14ba3b 100644 --- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java @@ -45,8 +45,9 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import static java.util.concurrent.TimeUnit.NANOSECONDS; import org.checkerframework.checker.nonempty.qual.PolyNonEmpty; @@ -170,6 +171,8 @@ public DelayQueue(Collection c) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { return offer(e); } @@ -181,6 +184,8 @@ public boolean add(E e) { * @return {@code true} * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { final ReentrantLock lock = this.lock; lock.lock(); @@ -203,6 +208,8 @@ public boolean offer(E e) { * @param e the element to add * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void put(E e) { offer(e); } @@ -217,6 +224,8 @@ public void put(E e) { * @return {@code true} * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e, long timeout, TimeUnit unit) { return offer(e); } @@ -229,6 +238,8 @@ public boolean offer(E e, long timeout, TimeUnit unit) { * @return the expired head of this queue, or {@code null} if this * queue has no elements with an expired delay */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink DelayQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -250,6 +261,8 @@ public boolean offer(E e, long timeout, TimeUnit unit) { * @return the expired head of this queue * @throws InterruptedException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E take(@GuardSatisfied @CanShrink DelayQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -295,6 +308,8 @@ public E take(@GuardSatisfied @CanShrink DelayQueue this) throws InterruptedE * an expired delay becomes available * @throws InterruptedException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink DelayQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; @@ -345,6 +360,8 @@ public E take(@GuardSatisfied @CanShrink DelayQueue this) throws InterruptedE * @throws NoSuchElementException if this queue has no elements with an * expired delay */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove() { return super.remove(); } @@ -386,6 +403,8 @@ public int size() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -396,6 +415,8 @@ public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, Collection this, Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -426,6 +447,8 @@ public int drainTo(@GuardSatisfied @CanShrink DelayQueue this, Collection this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -505,7 +528,6 @@ public int remainingCapacity() { * this queue * @throws NullPointerException if the specified array is null */ - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { final ReentrantLock lock = this.lock; lock.lock(); @@ -520,6 +542,8 @@ public int remainingCapacity() { * Removes a single instance of the specified element from this * queue, if it is present, whether or not it has expired. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@CanShrink DelayQueue this, @UnknownSignedness Object o) { final ReentrantLock lock = this.lock; lock.lock(); @@ -583,13 +607,16 @@ public boolean hasNext() { } @SuppressWarnings("unchecked") - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty Itr this) { if (cursor >= array.length) throw new NoSuchElementException(); return (E)array[lastRet = cursor++]; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastRet < 0) throw new IllegalStateException(); diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java index a77ccefcce8..f928042e2d1 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -48,8 +48,10 @@ import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.dataflow.qual.SideEffectFree; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.AbstractQueue; import java.util.Collection; @@ -331,6 +333,8 @@ void unlink(@CanShrink LinkedBlockingDeque this, Node x) { * @throws IllegalStateException if this deque is full * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addFirst(E e) { if (!offerFirst(e)) throw new IllegalStateException("Deque full"); @@ -340,6 +344,8 @@ public void addFirst(E e) { * @throws IllegalStateException if this deque is full * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void addLast(E e) { if (!offerLast(e)) throw new IllegalStateException("Deque full"); @@ -348,6 +354,8 @@ public void addLast(E e) { /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(E e) { if (e == null) throw new NullPointerException(); Node node = new Node(e); @@ -363,6 +371,8 @@ public boolean offerFirst(E e) { /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(E e) { if (e == null) throw new NullPointerException(); Node node = new Node(e); @@ -379,6 +389,8 @@ public boolean offerLast(E e) { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putFirst(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); @@ -396,6 +408,8 @@ public void putFirst(E e) throws InterruptedException { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putLast(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); Node node = new Node(e); @@ -413,6 +427,8 @@ public void putLast(E e) throws InterruptedException { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerFirst(E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); @@ -436,6 +452,8 @@ public boolean offerFirst(E e, long timeout, TimeUnit unit) * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offerLast(E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); @@ -458,6 +476,8 @@ public boolean offerLast(E e, long timeout, TimeUnit unit) /** * @throws NoSuchElementException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { E x = pollFirst(); if (x == null) throw new NoSuchElementException(); @@ -467,12 +487,16 @@ public E removeFirst(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque /** * @throws NoSuchElementException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E removeLast(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { E x = pollLast(); if (x == null) throw new NoSuchElementException(); return x; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -483,6 +507,8 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -493,6 +519,8 @@ public E removeLast(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E takeFirst(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lock(); @@ -506,6 +534,8 @@ public E takeFirst(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throw } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E takeLast(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lock(); @@ -519,6 +549,8 @@ public E takeLast(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollFirst(@GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); @@ -537,6 +569,8 @@ public E takeLast(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E pollLast(@GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); @@ -558,6 +592,7 @@ public E takeLast(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E getFirst(@NonEmpty LinkedBlockingDeque this) { E x = peekFirst(); if (x == null) throw new NoSuchElementException(); @@ -567,6 +602,7 @@ public E getFirst(@NonEmpty LinkedBlockingDeque this) { /** * @throws NoSuchElementException {@inheritDoc} */ + @Pure public E getLast(@NonEmpty LinkedBlockingDeque this) { E x = peekLast(); if (x == null) throw new NoSuchElementException(); @@ -595,6 +631,8 @@ public E getLast(@NonEmpty LinkedBlockingDeque this) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeFirstOccurrence(@CanShrink LinkedBlockingDeque this, Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; @@ -612,6 +650,8 @@ public boolean removeFirstOccurrence(@CanShrink LinkedBlockingDeque this, Obj } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeLastOccurrence(@CanShrink LinkedBlockingDeque this, Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; @@ -642,6 +682,8 @@ public boolean removeLastOccurrence(@CanShrink LinkedBlockingDeque this, Obje * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { addLast(e); return true; @@ -650,6 +692,8 @@ public boolean add(E e) { /** * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { return offerLast(e); } @@ -658,6 +702,8 @@ public boolean offer(E e) { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void put(E e) throws InterruptedException { putLast(e); } @@ -666,6 +712,8 @@ public void put(E e) throws InterruptedException { * @throws NullPointerException {@inheritDoc} * @throws InterruptedException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { return offerLast(e, timeout, unit); @@ -681,18 +729,26 @@ public boolean offer(E e, long timeout, TimeUnit unit) * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E remove(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { return removeFirst(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink LinkedBlockingDeque this) { return pollFirst(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E take(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws InterruptedException { return takeFirst(); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink LinkedBlockingDeque this, long timeout, TimeUnit unit) throws InterruptedException { return pollFirst(timeout, unit); } @@ -707,6 +763,7 @@ public E take(@GuardSatisfied @CanShrink LinkedBlockingDeque this) throws Int * @return the head of the queue represented by this deque * @throws NoSuchElementException if this deque is empty */ + @Pure public E element(@NonEmpty LinkedBlockingDeque this) { return getFirst(); } @@ -743,6 +800,8 @@ public int remainingCapacity() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -753,6 +812,8 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, Colle * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -779,6 +840,8 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingDeque this, Colle * @throws IllegalStateException if this deque is full * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void push(E e) { addFirst(e); } @@ -786,6 +849,8 @@ public void push(E e) { /** * @throws NoSuchElementException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E pop(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { return removeFirst(); } @@ -806,6 +871,8 @@ public E pop(@GuardSatisfied @NonEmpty @CanShrink LinkedBlockingDeque this) { * @param o element to be removed from this deque, if present * @return {@code true} if this deque changed as a result of the call */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@CanShrink LinkedBlockingDeque this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return removeFirstOccurrence(o); } @@ -864,6 +931,8 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * @throws IllegalStateException if this deque is full * @see #add(Object) */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean addAll(Collection c) { if (c == this) // As historically specified in AbstractQueue#addAll @@ -924,6 +993,7 @@ public boolean addAll(Collection c) { * @return an array containing all of the elements in this deque */ @SuppressWarnings("unchecked") + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(LinkedBlockingDeque<@PolyNull @PolySigned E> this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -993,6 +1063,7 @@ public boolean addAll(Collection c) { } } + @SideEffectFree public String toString() { return Helpers.collectionToString(this); } @@ -1001,6 +1072,8 @@ public String toString() { * Atomically removes all of the elements from this deque. * The deque will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink LinkedBlockingDeque this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -1041,6 +1114,7 @@ Node succ(Node p) { * * @return an iterator over the elements in this deque in proper sequence */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty LinkedBlockingDeque this) { return new Itr(); } @@ -1109,7 +1183,8 @@ public boolean hasNext() { return next != null; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty AbstractItr this) { Node p; if ((p = next) == null) @@ -1170,6 +1245,8 @@ public void forEachRemaining(Consumer action) { } while (n > 0 && p != null); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { Node n = lastRet; if (n == null) @@ -1308,6 +1385,7 @@ public int characteristics() { * @return a {@code Spliterator} over the elements in this deque * @since 1.8 */ + @SideEffectFree public Spliterator spliterator() { return new LBDSpliterator(); } @@ -1357,6 +1435,8 @@ void forEachFrom(Consumer action, Node p) { /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@CanShrink LinkedBlockingDeque this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1365,6 +1445,8 @@ public boolean removeIf(@CanShrink LinkedBlockingDeque this, Predicate this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1373,6 +1455,8 @@ public boolean removeAll(@CanShrink LinkedBlockingDeque this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java index b8bb0e7c107..5faa7a4ad1e 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -47,8 +47,10 @@ import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.dataflow.qual.SideEffectFree; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.AbstractQueue; import java.util.Collection; @@ -340,6 +342,8 @@ public int remainingCapacity() { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void put(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); final int c; @@ -379,6 +383,8 @@ public void put(E e) throws InterruptedException { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { @@ -417,6 +423,8 @@ public boolean offer(E e, long timeout, TimeUnit unit) * * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { if (e == null) throw new NullPointerException(); final AtomicInteger count = this.count; @@ -441,6 +449,8 @@ public boolean offer(E e) { return true; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E take(@GuardSatisfied @CanShrink LinkedBlockingQueue this) throws InterruptedException { final E x; final int c; @@ -463,6 +473,8 @@ public E take(@GuardSatisfied @CanShrink LinkedBlockingQueue this) throws Int return x; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink LinkedBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { final E x; final int c; @@ -488,6 +500,8 @@ public E take(@GuardSatisfied @CanShrink LinkedBlockingQueue this) throws Int return x; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink LinkedBlockingQueue this) { final AtomicInteger count = this.count; if (count.get() == 0) @@ -552,6 +566,8 @@ void unlink(Node p, Node pred) { * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@CanShrink LinkedBlockingQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; fullyLock(); @@ -606,6 +622,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * * @return an array containing all of the elements in this queue */ + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(LinkedBlockingQueue<@PolyNull @PolySigned E> this) { fullyLock(); try { @@ -675,6 +692,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { } } + @SideEffectFree public String toString() { return Helpers.collectionToString(this); } @@ -683,6 +701,8 @@ public String toString() { * Atomically removes all of the elements from this queue. * The queue will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink LinkedBlockingQueue this) { fullyLock(); try { @@ -705,6 +725,8 @@ public void clear(@GuardSatisfied @CanShrink LinkedBlockingQueue this) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingQueue this, Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -715,6 +737,8 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingQueue this, Colle * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink LinkedBlockingQueue this, Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -775,6 +799,7 @@ Node succ(Node p) { * * @return an iterator over the elements in this queue in proper sequence */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty LinkedBlockingQueue this) { return new Itr(); } @@ -808,7 +833,8 @@ public boolean hasNext() { return next != null; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E next(@NonEmpty Itr this) { Node p; if ((p = next) == null) @@ -867,6 +893,8 @@ public void forEachRemaining(Consumer action) { } while (n > 0 && p != null); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { Node p = lastRet; if (p == null) @@ -992,6 +1020,7 @@ public int characteristics() { * @return a {@code Spliterator} over the elements in this queue * @since 1.8 */ + @SideEffectFree public Spliterator spliterator() { return new LBQSpliterator(); } @@ -1040,6 +1069,8 @@ void forEachFrom(Consumer action, Node p) { /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@CanShrink LinkedBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1048,6 +1079,8 @@ public boolean removeIf(@CanShrink LinkedBlockingQueue this, Predicate this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1056,6 +1089,8 @@ public boolean removeAll(@CanShrink LinkedBlockingQueue this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index 1a8f179dd33..f54a3abf03b 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -48,7 +48,9 @@ import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.dataflow.qual.SideEffectFree; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -777,6 +779,7 @@ final int countOfMode(boolean data) { } } + @SideEffectFree public String toString() { String[] a = null; restartFromHead: for (;;) { @@ -852,6 +855,7 @@ else if (a != null && size <= a.length) { * * @return an array containing all of the elements in this queue */ + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(LinkedTransferQueue<@PolyNull @PolySigned E> this) { return toArrayInternal(null); } @@ -950,7 +954,8 @@ public final boolean hasNext() { return nextNode != null; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final E next(@NonEmpty Itr this) { DualNode p; if ((p = nextNode) == null) throw new NoSuchElementException(); @@ -968,6 +973,8 @@ public void forEachRemaining(Consumer action) { lastRet = q; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public final void remove() { final DualNode lastRet = this.lastRet; if (lastRet == null) @@ -1121,6 +1128,7 @@ public int characteristics() { * @return a {@code Spliterator} over the elements in this queue * @since 1.8 */ + @SideEffectFree public Spliterator spliterator() { return new LTQSpliterator(); } @@ -1160,6 +1168,8 @@ public LinkedTransferQueue(Collection c) { * * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void put(E e) { Objects.requireNonNull(e); xfer(e, -1L); @@ -1174,6 +1184,8 @@ public void put(E e) { * {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer}) * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e, long timeout, TimeUnit unit) { Objects.requireNonNull(e); xfer(e, -1L); @@ -1187,6 +1199,8 @@ public boolean offer(E e, long timeout, TimeUnit unit) { * @return {@code true} (as specified by {@link Queue#offer}) * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { Objects.requireNonNull(e); xfer(e, -1L); @@ -1202,6 +1216,8 @@ public boolean offer(E e) { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { Objects.requireNonNull(e); xfer(e, -1L); @@ -1218,6 +1234,8 @@ public boolean add(E e) { * * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean tryTransfer(@GuardSatisfied @CanShrink LinkedTransferQueue this, E e) { Objects.requireNonNull(e); return xfer(e, 0L) == null; @@ -1234,6 +1252,8 @@ public boolean tryTransfer(@GuardSatisfied @CanShrink LinkedTransferQueue thi * * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void transfer(@GuardSatisfied @CanShrink LinkedTransferQueue this, E e) throws InterruptedException { Objects.requireNonNull(e); if (!Thread.interrupted()) { @@ -1258,6 +1278,8 @@ public void transfer(@GuardSatisfied @CanShrink LinkedTransferQueue this, E e * * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean tryTransfer(@GuardSatisfied @CanShrink LinkedTransferQueue this, E e, long timeout, TimeUnit unit) throws InterruptedException { Objects.requireNonNull(e); @@ -1270,6 +1292,8 @@ public boolean tryTransfer(@GuardSatisfied @CanShrink LinkedTransferQueue thi } @SuppressWarnings("unchecked") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E take(@GuardSatisfied @CanShrink LinkedTransferQueue this) throws InterruptedException { Object e; if (!Thread.interrupted()) { @@ -1281,6 +1305,8 @@ public E take(@GuardSatisfied @CanShrink LinkedTransferQueue this) throws Int } @SuppressWarnings("unchecked") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E poll(@GuardSatisfied @CanShrink LinkedTransferQueue this, long timeout, TimeUnit unit) throws InterruptedException { Object e; long nanos = Math.max(unit.toNanos(timeout), 0L); @@ -1290,6 +1316,8 @@ public E poll(@GuardSatisfied @CanShrink LinkedTransferQueue this, long timeo } @SuppressWarnings("unchecked") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E poll(@GuardSatisfied @CanShrink LinkedTransferQueue this) { return (E) xfer(null, 0L); } @@ -1298,6 +1326,8 @@ public E poll(@GuardSatisfied @CanShrink LinkedTransferQueue this) { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, Collection c) { Objects.requireNonNull(c); if (c == this) @@ -1312,6 +1342,8 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, Colle * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -1331,6 +1363,7 @@ public int drainTo(@GuardSatisfied @CanShrink LinkedTransferQueue this, Colle * * @return an iterator over the elements in this queue in proper sequence */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty LinkedTransferQueue this) { return new Itr(); } @@ -1415,6 +1448,8 @@ public int getWaitingConsumerCount() { * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@CanShrink LinkedTransferQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o == null) return false; restartFromHead: for (;;) { @@ -1536,6 +1571,8 @@ private void readObject(java.io.ObjectInputStream s) /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@CanShrink LinkedTransferQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1544,6 +1581,8 @@ public boolean removeIf(@CanShrink LinkedTransferQueue this, Predicate this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1552,11 +1591,15 @@ public boolean removeAll(@CanShrink LinkedTransferQueue this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink LinkedTransferQueue this) { bulkRemove(e -> true); } diff --git a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java index 44da54e18ea..fe1a1cef947 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -48,8 +48,10 @@ import org.checkerframework.checker.signedness.qual.PolySigned; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.dataflow.qual.SideEffectFree; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -463,6 +465,8 @@ private void heapify() { * @throws NullPointerException if the specified element is null */ @EnsuresNonEmpty("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean add(E e) { return offer(e); } @@ -478,6 +482,8 @@ public boolean add(E e) { * priority queue's ordering * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { if (e == null) throw new NullPointerException(); @@ -511,6 +517,8 @@ public boolean offer(E e) { * priority queue's ordering * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void put(E e) { offer(e); // never need to block } @@ -530,10 +538,14 @@ public void put(E e) { * priority queue's ordering * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e, long timeout, TimeUnit unit) { return offer(e); // never need to block } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink PriorityBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -544,6 +556,8 @@ public boolean offer(E e, long timeout, TimeUnit unit) { } } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E take(@GuardSatisfied @CanShrink PriorityBlockingQueue this) throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -557,6 +571,8 @@ public E take(@GuardSatisfied @CanShrink PriorityBlockingQueue this) throws I return result; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public @Nullable E poll(@GuardSatisfied @CanShrink PriorityBlockingQueue this, long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; @@ -591,6 +607,7 @@ public E take(@GuardSatisfied @CanShrink PriorityBlockingQueue this) throws I * or {@code null} if this queue uses the natural * ordering of its elements */ + @Pure public Comparator comparator() { return comparator; } @@ -615,6 +632,7 @@ public int remainingCapacity() { return Integer.MAX_VALUE; } + @Pure private int indexOf(@GuardSatisfied @Nullable @UnknownSignedness Object o) { if (o != null) { final Object[] es = queue; @@ -662,6 +680,8 @@ private void removeAt(int i) { * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@CanShrink PriorityBlockingQueue this, @Nullable @UnknownSignedness Object o) { final ReentrantLock lock = this.lock; lock.lock(); @@ -717,6 +737,7 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { } } + @SideEffectFree public String toString() { return Helpers.collectionToString(this); } @@ -727,6 +748,8 @@ public String toString() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, Collection c) { return drainTo(c, Integer.MAX_VALUE); } @@ -737,6 +760,8 @@ public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, Col * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) @@ -761,6 +786,8 @@ public int drainTo(@GuardSatisfied @CanShrink PriorityBlockingQueue this, Col * Atomically removes all of the elements from this queue. * The queue will be empty after this call returns. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink PriorityBlockingQueue this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -787,6 +814,7 @@ public void clear(@GuardSatisfied @CanShrink PriorityBlockingQueue this) { * * @return an array containing all of the elements in this queue */ + @SideEffectFree public @PolyNull @PolySigned Object[] toArray(PriorityBlockingQueue<@PolyNull @PolySigned E> this) { final ReentrantLock lock = this.lock; lock.lock(); @@ -859,6 +887,7 @@ public void clear(@GuardSatisfied @CanShrink PriorityBlockingQueue this) { * * @return an iterator over the elements in this queue */ + @SideEffectFree public @PolyGrowShrink @PolyNonEmpty Iterator iterator(@PolyGrowShrink @PolyNonEmpty PriorityBlockingQueue this) { return new Itr(toArray()); } @@ -881,13 +910,15 @@ public boolean hasNext() { return cursor < array.length; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public E next(@NonEmpty Itr this) { if (cursor >= array.length) throw new NoSuchElementException(); return (E)array[lastRet = cursor++]; } + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (lastRet < 0) throw new IllegalStateException(); @@ -1026,6 +1057,7 @@ public int characteristics() { * @return a {@code Spliterator} over the elements in this queue * @since 1.8 */ + @SideEffectFree public Spliterator spliterator() { return new PBQSpliterator(); } @@ -1033,6 +1065,8 @@ public Spliterator spliterator() { /** * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeIf(@CanShrink PriorityBlockingQueue this, Predicate filter) { Objects.requireNonNull(filter); return bulkRemove(filter); @@ -1041,6 +1075,8 @@ public boolean removeIf(@CanShrink PriorityBlockingQueue this, Predicate this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); @@ -1049,6 +1085,8 @@ public boolean removeAll(@CanShrink PriorityBlockingQueue this, Collection this, Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); diff --git a/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java b/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java index 3861899a7f2..6015ffd22f0 100644 --- a/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java +++ b/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java @@ -42,7 +42,8 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; @@ -1023,6 +1024,7 @@ private void grow() { /** * Finds index of given object, or -1 if absent. */ + @Pure private int indexOf(Object x) { if (x != null) { if (x instanceof ScheduledFutureTask) { @@ -1351,7 +1353,8 @@ public boolean hasNext() { return cursor < array.length; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Runnable next(@NonEmpty Itr this) { if (cursor >= array.length) throw new NoSuchElementException(); diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index fd8fa0a5cc0..d4c0765e327 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -49,6 +49,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -275,6 +276,8 @@ public SynchronousQueue(boolean fair) { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void put(E e) throws InterruptedException { Objects.requireNonNull(e); if (!Thread.interrupted()) { @@ -294,6 +297,8 @@ public void put(E e) throws InterruptedException { * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { Objects.requireNonNull(e); @@ -314,6 +319,8 @@ public boolean offer(E e, long timeout, TimeUnit unit) * {@code false} * @throws NullPointerException if the specified element is null */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean offer(E e) { Objects.requireNonNull(e); return xfer(e, 0L) == null; @@ -326,6 +333,8 @@ public boolean offer(E e) { * @return the head of this queue * @throws InterruptedException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E take(@GuardSatisfied @CanShrink SynchronousQueue this) throws InterruptedException { Object e; if (!Thread.interrupted()) { @@ -345,6 +354,8 @@ public E take(@GuardSatisfied @CanShrink SynchronousQueue this) throws Interr * specified waiting time elapses before an element is present * @throws InterruptedException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E poll(@GuardSatisfied @CanShrink SynchronousQueue this, long timeout, TimeUnit unit) throws InterruptedException { Object e; long nanos = Math.max(unit.toNanos(timeout), 0L); @@ -360,6 +371,8 @@ public E poll(@GuardSatisfied @CanShrink SynchronousQueue this, long timeout, * @return the head of this queue, or {@code null} if no * element is available */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public E poll(@GuardSatisfied @CanShrink SynchronousQueue this) { return (E) xfer(null, 0L); } @@ -401,6 +414,8 @@ public int remainingCapacity() { * Does nothing. * A {@code SynchronousQueue} has no internal capacity. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear(@GuardSatisfied @CanShrink SynchronousQueue this) { } @@ -424,6 +439,8 @@ public boolean contains(@GuardSatisfied @Nullable @UnknownSignedness Object o) { * @param o the element to remove * @return {@code false} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean remove(@CanShrink SynchronousQueue this, @GuardSatisfied @Nullable @UnknownSignedness Object o) { return false; } @@ -447,6 +464,8 @@ public boolean containsAll(Collection c) { * @param c the collection * @return {@code false} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public boolean removeAll(@CanShrink SynchronousQueue this, Collection c) { return false; } @@ -458,6 +477,8 @@ public boolean removeAll(@CanShrink SynchronousQueue this, Collection this, Collection c) { return false; } @@ -514,7 +535,6 @@ public Spliterator spliterator() { * @return the specified array * @throws NullPointerException if the specified array is null */ - @SideEffectFree public @Nullable T[] toArray(@PolyNull T[] a) { if (a.length > 0) a[0] = null; @@ -525,6 +545,7 @@ public Spliterator spliterator() { * Always returns {@code "[]"}. * @return {@code "[]"} */ + @SideEffectFree public String toString() { return "[]"; } @@ -535,6 +556,8 @@ public String toString() { * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink SynchronousQueue this, Collection c) { Objects.requireNonNull(c); if (c == this) @@ -551,6 +574,8 @@ public int drainTo(@GuardSatisfied @CanShrink SynchronousQueue this, Collecti * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public int drainTo(@GuardSatisfied @CanShrink SynchronousQueue this, Collection c, int maxElements) { Objects.requireNonNull(c); if (c == this) diff --git a/src/java.base/share/classes/java/util/jar/Attributes.java b/src/java.base/share/classes/java/util/jar/Attributes.java index bf564385c01..ec2d5880bf2 100644 --- a/src/java.base/share/classes/java/util/jar/Attributes.java +++ b/src/java.base/share/classes/java/util/jar/Attributes.java @@ -34,6 +34,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; @@ -123,6 +124,7 @@ public Attributes(Attributes attr) { * @return the value of the specified attribute name, or null if * not found. */ + @Pure public Object get(Object name) { return map.get(name); } @@ -142,6 +144,7 @@ public Object get(Object name) { * not found. * @throws IllegalArgumentException if the attribute name is invalid */ + @Pure public String getValue(String name) { return (String)get(Name.of(name)); } @@ -159,6 +162,7 @@ public String getValue(String name) { * @return the String value of the specified Attribute.Name, or null if * not found. */ + @Pure public String getValue(Name name) { return (String)get(name); } @@ -174,6 +178,8 @@ public String getValue(Name name) { * @throws ClassCastException if the name is not a Attributes.Name * or the value is not a String */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Object put(Object name, Object value) { return map.put((Attributes.Name)name, (String)value); } @@ -205,6 +211,8 @@ public String putValue(String name, String value) { * @param name attribute name * @return the previous value of the attribute, or null if none */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public Object remove(@GuardSatisfied @Nullable @UnknownSignedness Object name) { return map.remove(name); } @@ -240,6 +248,8 @@ public boolean containsKey(@GuardSatisfied @Nullable @UnknownSignedness Object n * @param attr the Attributes to be stored in this map * @throws ClassCastException if attr is not an Attributes */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void putAll(Map attr) { // ## javac bug? if (!Attributes.class.isInstance(attr)) @@ -251,6 +261,8 @@ public void putAll(Map attr) { /** * Removes all attributes from this Map. */ + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public void clear() { map.clear(); } @@ -275,6 +287,7 @@ public boolean isEmpty() { /** * Returns a Set view of the attribute names (keys) contained in this Map. */ + @SideEffectFree public Set keySet() { return map.keySet(); } @@ -282,6 +295,7 @@ public Set keySet() { /** * Returns a Collection view of the attribute values contained in this Map. */ + @SideEffectFree public Collection values() { return map.values(); } @@ -313,6 +327,7 @@ public boolean equals(@Nullable Object o) { /** * Returns the hash code value for this Map. */ + @Pure public int hashCode() { return map.hashCode(); } @@ -326,6 +341,7 @@ public int hashCode() { * the Attributes returned can be safely modified without affecting * the original. */ + @SideEffectFree public Object clone() { return new Attributes(this); } @@ -488,6 +504,7 @@ public static class Name { */ private static @Stable Map KNOWN_NAMES; + @SideEffectFree static final Name of(String name) { Name n = KNOWN_NAMES.get(name); if (n != null) { @@ -540,6 +557,7 @@ private final int hash(String name) { * @return true if this attribute name is equal to the * specified attribute object */ + @Pure public boolean equals(Object o) { if (this == o) { return true; @@ -551,6 +569,7 @@ public boolean equals(Object o) { /** * Computes the hash value for this attribute name. */ + @Pure public int hashCode() { return hashCode; } @@ -558,6 +577,7 @@ public int hashCode() { /** * Returns the attribute name as a String. */ + @SideEffectFree public String toString() { return name; } diff --git a/src/java.base/share/classes/java/util/regex/Matcher.java b/src/java.base/share/classes/java/util/regex/Matcher.java index 26da409010d..e4e9b1eb853 100644 --- a/src/java.base/share/classes/java/util/regex/Matcher.java +++ b/src/java.base/share/classes/java/util/regex/Matcher.java @@ -35,8 +35,9 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.IOException; import java.util.ConcurrentModificationException; @@ -1384,7 +1385,8 @@ class MatchResultIterator implements Iterator { int expectedCount = -1; @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public MatchResult next(@NonEmpty MatchResultIterator this) { if (expectedCount >= 0 && expectedCount != modCount) throw new ConcurrentModificationException(); diff --git a/src/java.base/share/classes/java/util/regex/Pattern.java b/src/java.base/share/classes/java/util/regex/Pattern.java index 51eac7d9a8b..1bf0f99641c 100644 --- a/src/java.base/share/classes/java/util/regex/Pattern.java +++ b/src/java.base/share/classes/java/util/regex/Pattern.java @@ -35,9 +35,10 @@ import org.checkerframework.common.value.qual.MinLen; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.text.Normalizer; import java.text.Normalizer.Form; @@ -6085,7 +6086,8 @@ class MatcherIterator implements Iterator { // > 0 if there are N next empty elements private int emptyElementCount; - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public String next(@NonEmpty MatcherIterator this) { if (!hasNext()) throw new NoSuchElementException(); diff --git a/src/java.base/share/classes/java/util/stream/SpinedBuffer.java b/src/java.base/share/classes/java/util/stream/SpinedBuffer.java index 98bbc040a7b..5ea5f3a3246 100644 --- a/src/java.base/share/classes/java/util/stream/SpinedBuffer.java +++ b/src/java.base/share/classes/java/util/stream/SpinedBuffer.java @@ -24,6 +24,8 @@ */ package java.util.stream; +import org.checkerframework.dataflow.qual.SideEffectFree; + import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -37,6 +39,7 @@ import java.util.function.IntConsumer; import java.util.function.IntFunction; import java.util.function.LongConsumer; +import org.checkerframework.dataflow.qual.Pure; /** * An ordered collection of elements. Elements can be added, but not removed. @@ -157,6 +160,7 @@ protected void increaseCapacity() { /** * Retrieve the element at the specified index. */ + @Pure public E get(long index) { // @@@ can further optimize by caching last seen spineIndex, // which is going to be right most of the time @@ -234,6 +238,7 @@ public void clear() { } @Override + @SideEffectFree public Iterator iterator() { return Spliterators.iterator(spliterator()); } @@ -264,6 +269,7 @@ public void accept(E e) { } @Override + @SideEffectFree public String toString() { List list = new ArrayList<>(); forEach(list::add); @@ -276,6 +282,7 @@ public String toString() { /** * Return a {@link Spliterator} describing the contents of the buffer. */ + @SideEffectFree public Spliterator spliterator() { class Splitr implements Spliterator { // The current spine index @@ -462,6 +469,7 @@ abstract static class OfPrimitive } @Override + @SideEffectFree public abstract Iterator iterator(); @Override @@ -770,6 +778,7 @@ public void accept(int i) { curChunk[elementIndex++] = i; } + @Pure public int get(long index) { // Casts to int are safe since the spine array index is the index minus // the prior element count from the current spine @@ -781,10 +790,12 @@ public int get(long index) { } @Override + @SideEffectFree public PrimitiveIterator.OfInt iterator() { return Spliterators.iterator(spliterator()); } + @SideEffectFree public Spliterator.OfInt spliterator() { @SuppressWarnings("overloads") class Splitr extends BaseSpliterator @@ -816,6 +827,7 @@ Spliterator.OfInt arraySpliterator(int[] array, int offset, int len) { } @Override + @SideEffectFree public String toString() { int[] array = asPrimitiveArray(); if (array.length < 200) { @@ -885,6 +897,7 @@ public void accept(long i) { curChunk[elementIndex++] = i; } + @Pure public long get(long index) { // Casts to int are safe since the spine array index is the index minus // the prior element count from the current spine @@ -896,11 +909,12 @@ public long get(long index) { } @Override + @SideEffectFree public PrimitiveIterator.OfLong iterator() { return Spliterators.iterator(spliterator()); } - + @SideEffectFree public Spliterator.OfLong spliterator() { @SuppressWarnings("overloads") class Splitr extends BaseSpliterator @@ -932,6 +946,7 @@ Spliterator.OfLong arraySpliterator(long[] array, int offset, int len) { } @Override + @SideEffectFree public String toString() { long[] array = asPrimitiveArray(); if (array.length < 200) { @@ -1002,6 +1017,7 @@ public void accept(double i) { curChunk[elementIndex++] = i; } + @Pure public double get(long index) { // Casts to int are safe since the spine array index is the index minus // the prior element count from the current spine @@ -1013,10 +1029,12 @@ public double get(long index) { } @Override + @SideEffectFree public PrimitiveIterator.OfDouble iterator() { return Spliterators.iterator(spliterator()); } + @SideEffectFree public Spliterator.OfDouble spliterator() { @SuppressWarnings("overloads") class Splitr extends BaseSpliterator @@ -1048,6 +1066,7 @@ Spliterator.OfDouble arraySpliterator(double[] array, int offset, int len) { } @Override + @SideEffectFree public String toString() { double[] array = asPrimitiveArray(); if (array.length < 200) { diff --git a/src/java.base/share/classes/java/util/stream/Stream.java b/src/java.base/share/classes/java/util/stream/Stream.java index 7193a7d7e86..4e592f28346 100644 --- a/src/java.base/share/classes/java/util/stream/Stream.java +++ b/src/java.base/share/classes/java/util/stream/Stream.java @@ -922,7 +922,6 @@ default Stream dropWhile(Predicate predicate) { * stream is not assignable to the {@linkplain Class#getComponentType * runtime component type} of the generated array */ - @SideEffectFree A[] toArray(IntFunction generator); /** diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index 05b336d8c8d..ac4fd2f57b2 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -36,9 +36,10 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.SignedPositive; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.io.Closeable; import java.io.InputStream; @@ -517,6 +518,7 @@ public ZipEntryIterator(int entryCount) { } @Override + @Pure @EnsuresNonEmptyIf(result = true, expression = "this") public boolean hasMoreElements() { return hasNext(); @@ -530,14 +532,16 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public T nextElement(@NonEmpty ZipEntryIterator this) { return next(); } @Override @SuppressWarnings("unchecked") - @SideEffectsOnly("this") + // @SideEffectsOnly("this") + @DoesNotUnrefineReceiver("modifiability") public T next(@NonEmpty ZipEntryIterator this) { synchronized (ZipFile.this) { ensureOpen(); @@ -1030,6 +1034,7 @@ public int available() { return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem; } + @Pure public long size() { return size; } @@ -1432,12 +1437,14 @@ public Key(File file, BasicFileAttributes attrs, ZipCoder zc) { this.utf8 = zc.isUTF8(); } + @Pure public int hashCode() { long t = utf8 ? 0 : Long.MAX_VALUE; t += attrs.lastModifiedTime().toMillis(); return ((int)(t ^ (t >>> 32))) + file.hashCode(); } + @Pure public boolean equals(Object obj) { if (obj instanceof Key key) { if (key.utf8 != utf8) { diff --git a/src/java.base/share/classes/javax/security/auth/Subject.java b/src/java.base/share/classes/javax/security/auth/Subject.java index 54a8c778242..0c5c919bf02 100644 --- a/src/java.base/share/classes/javax/security/auth/Subject.java +++ b/src/java.base/share/classes/javax/security/auth/Subject.java @@ -34,7 +34,7 @@ import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import java.io.IOException; import java.io.ObjectInputStream; @@ -1207,7 +1207,7 @@ public boolean hasNext() { return i.hasNext(); } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public E next(/*@NonEmpty Iterator this*/) { if (which != Subject.PRIV_CREDENTIAL_SET) { return i.next(); diff --git a/src/java.base/share/classes/jdk/internal/icu/text/Replaceable.java b/src/java.base/share/classes/jdk/internal/icu/text/Replaceable.java index ebbf633f01a..399f28b33a5 100644 --- a/src/java.base/share/classes/jdk/internal/icu/text/Replaceable.java +++ b/src/java.base/share/classes/jdk/internal/icu/text/Replaceable.java @@ -38,7 +38,7 @@ package jdk.internal.icu.text; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; /** * Replaceable is an interface representing a @@ -120,6 +120,6 @@ public interface Replaceable { * @param dstStart the start offset in the destination array. * @stable ICU 2.0 */ - @SideEffectsOnly("#3") + // @SideEffectsOnly("#3") void getChars(int srcStart, int srcLimit, char dst[], int dstStart); } diff --git a/src/java.base/share/classes/jdk/internal/icu/text/ReplaceableString.java b/src/java.base/share/classes/jdk/internal/icu/text/ReplaceableString.java index dfdfafb0cbf..2bed00848bb 100644 --- a/src/java.base/share/classes/jdk/internal/icu/text/ReplaceableString.java +++ b/src/java.base/share/classes/jdk/internal/icu/text/ReplaceableString.java @@ -33,7 +33,7 @@ package jdk.internal.icu.text; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; /** * ReplaceableString is an adapter class that implements the @@ -113,7 +113,7 @@ public char charAt(int offset) { * @param dstStart the start offset in the destination array. * @stable ICU 2.0 */ - @SideEffectsOnly("#3") + // @SideEffectsOnly("#3") public void getChars(int srcStart, int srcLimit, char dst[], int dstStart) { if (srcStart != srcLimit) { buf.getChars(srcStart, srcLimit, dst, dstStart); diff --git a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java index c81d8775f67..a6038701a72 100644 --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java @@ -60,6 +60,7 @@ package jdk.internal.org.objectweb.asm.tree; import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.ListIterator; import java.util.NoSuchElementException; import jdk.internal.org.objectweb.asm.MethodVisitor; @@ -543,6 +544,7 @@ public boolean hasNext() { } @Override + @DoesNotUnrefineReceiver("modifiability") public Object next() { if (nextInsn == null) { throw new NoSuchElementException(); @@ -555,6 +557,7 @@ public Object next() { } @Override + @DoesNotUnrefineReceiver("modifiability") public void remove() { if (remove != null) { if (remove == nextInsn) { @@ -609,6 +612,7 @@ public int previousIndex() { } @Override + @DoesNotUnrefineReceiver("modifiability") public void add(final Object o) { if (nextInsn != null) { InsnList.this.insertBefore(nextInsn, (AbstractInsnNode) o); @@ -622,6 +626,7 @@ public void add(final Object o) { } @Override + @DoesNotUnrefineReceiver("modifiability") public void set(final Object o) { if (remove != null) { InsnList.this.set(remove, (AbstractInsnNode) o); diff --git a/src/java.base/share/classes/sun/net/www/HeaderParser.java b/src/java.base/share/classes/sun/net/www/HeaderParser.java index ec69c47f035..6e6fff53188 100644 --- a/src/java.base/share/classes/sun/net/www/HeaderParser.java +++ b/src/java.base/share/classes/sun/net/www/HeaderParser.java @@ -26,7 +26,8 @@ package sun.net.www; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.Iterator; import java.util.Locale; @@ -208,10 +209,12 @@ class ParserIterator implements Iterator { public boolean hasNext () { return index next() { return new Map.Entry() { String k = i.next(); diff --git a/src/java.base/share/classes/sun/util/locale/StringTokenIterator.java b/src/java.base/share/classes/sun/util/locale/StringTokenIterator.java index 7d0ab209641..5d1d4aa12c2 100644 --- a/src/java.base/share/classes/sun/util/locale/StringTokenIterator.java +++ b/src/java.base/share/classes/sun/util/locale/StringTokenIterator.java @@ -31,7 +31,7 @@ package sun.util.locale; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; public class StringTokenIterator { private String text; @@ -74,7 +74,7 @@ public boolean isDone() { return done; } - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public String next() { if (hasNext()) { start = end + 1; diff --git a/src/java.base/share/classes/sun/util/resources/ParallelListResourceBundle.java b/src/java.base/share/classes/sun/util/resources/ParallelListResourceBundle.java index e372d57d222..0de7491fc9c 100644 --- a/src/java.base/share/classes/sun/util/resources/ParallelListResourceBundle.java +++ b/src/java.base/share/classes/sun/util/resources/ParallelListResourceBundle.java @@ -28,7 +28,7 @@ import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import java.util.AbstractSet; import java.util.Collections; @@ -240,7 +240,7 @@ public boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public String next() { if (hasNext()) { return itr.next(); diff --git a/src/java.base/unix/classes/java/lang/ProcessEnvironment.java b/src/java.base/unix/classes/java/lang/ProcessEnvironment.java index c91fca356b5..24575254fdb 100644 --- a/src/java.base/unix/classes/java/lang/ProcessEnvironment.java +++ b/src/java.base/unix/classes/java/lang/ProcessEnvironment.java @@ -55,7 +55,7 @@ package java.lang; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import java.util.*; @@ -338,7 +338,7 @@ public Iterator> iterator() { Iterator> i = s.iterator(); @Pure public boolean hasNext() {return i.hasNext();} - @SideEffectsOnly("this") + // // @SideEffectsOnly("this") public Map.Entry next() { return new StringEntry(i.next()); } @@ -385,7 +385,7 @@ public Iterator iterator() { Iterator i = c.iterator(); @Pure public boolean hasNext() {return i.hasNext();} - @SideEffectsOnly("this") + // // @SideEffectsOnly("this") public String next() {return i.next().toString();} public void remove() {i.remove();} }; @@ -416,7 +416,7 @@ public Iterator iterator() { Iterator i = s.iterator(); @Pure public boolean hasNext() {return i.hasNext();} - @SideEffectsOnly("this") + // // @SideEffectsOnly("this") public String next() {return i.next().toString();} public void remove() { i.remove();} }; diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixDirectoryStream.java b/src/java.base/unix/classes/sun/nio/fs/UnixDirectoryStream.java index 4ef0d19fc3c..bad17d050f4 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixDirectoryStream.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixDirectoryStream.java @@ -26,7 +26,7 @@ package sun.nio.fs; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import java.nio.file.*; import java.util.Iterator; @@ -204,7 +204,7 @@ public synchronized boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public synchronized Path next() { Path result; if (nextEntry == null && !atEof) { diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java index 1b663f0c137..f6728ae700c 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java @@ -26,7 +26,7 @@ package sun.nio.fs; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import java.nio.ByteBuffer; import java.nio.file.AtomicMoveNotSupportedException; @@ -260,7 +260,7 @@ public synchronized boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public synchronized FileStore next() { if (next == null) next = readNext(); diff --git a/src/java.base/windows/classes/java/lang/ProcessEnvironment.java b/src/java.base/windows/classes/java/lang/ProcessEnvironment.java index 8f0feb7519a..c621cf5e612 100644 --- a/src/java.base/windows/classes/java/lang/ProcessEnvironment.java +++ b/src/java.base/windows/classes/java/lang/ProcessEnvironment.java @@ -64,7 +64,7 @@ package java.lang; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import java.util.*; @@ -145,7 +145,7 @@ public Iterator> iterator() { Iterator> i = s.iterator(); @Pure public boolean hasNext() { return i.hasNext();} - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public Map.Entry next() { return new CheckedEntry(i.next()); } diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsDirectoryStream.java b/src/java.base/windows/classes/sun/nio/fs/WindowsDirectoryStream.java index 0916f458799..f9c17db80cb 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsDirectoryStream.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsDirectoryStream.java @@ -26,7 +26,7 @@ package sun.nio.fs; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; @@ -215,7 +215,7 @@ public synchronized boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public synchronized Path next() { Path result = null; if (nextEntry == null && !atEof) { diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java index faf07b454b9..30018a9e05b 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java @@ -26,7 +26,7 @@ package sun.nio.fs; import org.checkerframework.dataflow.qual.Pure; -import org.checkerframework.dataflow.qual.SideEffectsOnly; +// import org.checkerframework.dataflow.qual.SideEffectsOnly; import java.nio.file.*; import java.nio.file.attribute.*; @@ -170,7 +170,7 @@ public synchronized boolean hasNext() { } @Override - @SideEffectsOnly("this") + // @SideEffectsOnly("this") public synchronized FileStore next() { if (next == null) next = readNext(); diff --git a/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java b/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java index 633cd76d4b3..3c81b2cdcb7 100644 --- a/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java +++ b/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; +import java.awt.Color; import java.awt.Graphics; import java.awt.HeadlessException; import java.awt.Point; @@ -700,7 +701,25 @@ public void paint(Graphics g) { // semantics of damage we can't really get around this. damage(r); } - g.setColor(component.getCaretColor()); + if (component.isEditable()) { + g.setColor(component.getCaretColor()); + } else { + Color caretColor = component.getCaretColor(); + if (caretColor == null) { + caretColor = g.getColor(); + } + Color bg = component.getBackground(); + if (bg == null) { + g.setColor(caretColor); + } else { + int red = (caretColor.getRed() + bg.getRed()) / 2; + int green = (caretColor.getGreen() + bg.getGreen()) / 2; + int blue = (caretColor.getBlue() + bg.getBlue()) / 2; + int alpha = 127; + Color newCaretColor = new Color(red, green, blue, alpha); + g.setColor(newCaretColor); + } + } int paintWidth = getCaretWidth(r.height); r.x -= paintWidth >> 1; g.fillRect(r.x, r.y, paintWidth, r.height); diff --git a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/Headers.java b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/Headers.java index 9efb3d687ff..9e49d6e94e2 100644 --- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/Headers.java +++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/Headers.java @@ -26,6 +26,7 @@ package com.sun.net.httpserver; import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.framework.qual.DoesNotUnrefineReceiver; import java.util.Arrays; import java.util.Collection; @@ -246,6 +247,7 @@ public Set>> entrySet() { } @Override + @DoesNotUnrefineReceiver("modifiability") public void replaceAll(BiFunction, ? extends List> function) { var f = function.andThen(values -> { Objects.requireNonNull(values); diff --git a/test/hotspot/jtreg/containers/docker/EventGeneratorLoop.java b/test/hotspot/jtreg/containers/docker/EventGeneratorLoop.java index de7605b4457..efb1690ea75 100644 --- a/test/hotspot/jtreg/containers/docker/EventGeneratorLoop.java +++ b/test/hotspot/jtreg/containers/docker/EventGeneratorLoop.java @@ -24,6 +24,8 @@ import jdk.jfr.Description; import jdk.jfr.Label; +import java.util.concurrent.TimeUnit; + // This class generates simple event in a loop for a specified time. public class EventGeneratorLoop { @@ -44,16 +46,21 @@ public static void main(String[] args) throws Exception { throw new IllegalArgumentException("Expecting one argument: time to run (seconds)"); } int howLong = Integer.parseInt(args[0]); + long endTime = System.nanoTime() + TimeUnit.SECONDS.toNanos(howLong); System.out.println(MAIN_METHOD_STARTED + ", argument is " + howLong); - for (int i=0; i < howLong; i++) { + int count = 0; + while (System.nanoTime() < endTime) { SimpleEvent ev = new SimpleEvent(); ev.msg = "Hello"; - ev.count = i; + ev.count = count++; ev.commit(); - try { Thread.sleep(1000); } catch (InterruptedException e) {} + try { + Thread.sleep(1000); + } catch (InterruptedException ignore) { + } System.out.print("."); } diff --git a/test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java b/test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java index 3640f0ac587..91a07012f00 100644 --- a/test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java +++ b/test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java @@ -49,10 +49,10 @@ import java.util.EnumSet; import java.util.List; import java.util.Optional; +import java.util.Random; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.regex.Pattern; -import java.util.stream.Collectors; import jdk.test.lib.Container; import jdk.test.lib.Platform; @@ -68,7 +68,6 @@ public class TestJcmdWithSideCar { private static final String IMAGE_NAME = Common.imageName("jfr-jcmd"); private static final int TIME_TO_RUN_MAIN_PROCESS = (int) (30 * Utils.TIMEOUT_FACTOR); // seconds private static final long TIME_TO_WAIT_FOR_MAIN_METHOD_START = 50 * 1000; // milliseconds - private static final String MAIN_CONTAINER_NAME = "test-container-main"; private static final String UID = "uid"; private static final String GID = "gid"; @@ -116,19 +115,19 @@ public static void main(String[] args) throws Exception { // Elevated attach via proc/root not yet supported. continue; } - long mainProcPid = testCase01(attachStrategy, elevated); + long mainProcPid = testCase01(mainContainer, attachStrategy, elevated); // Excluding the test case below until JDK-8228850 is fixed // JDK-8228850: jhsdb jinfo fails with ClassCastException: // s.j.h.oops.TypeArray cannot be cast to s.j.h.oops.Instance // mainContainer.assertIsAlive(); - // testCase02(mainProcPid, attachStrategy, elevated); + // testCase02(mainContainer, mainProcPid, attachStrategy, elevated); mainContainer.assertIsAlive(); - testCase03(mainProcPid, attachStrategy, elevated); + testCase03(mainContainer, mainProcPid, attachStrategy, elevated); } - mainContainer.waitForAndCheck(TIME_TO_RUN_MAIN_PROCESS * 1000); + mainContainer.stop(); } } finally { DockerTestUtils.removeDockerImage(IMAGE_NAME); @@ -137,8 +136,8 @@ public static void main(String[] args) throws Exception { // Run "jcmd -l" in a sidecar container, find a target process. - private static long testCase01(AttachStrategy attachStrategy, boolean elevated) throws Exception { - OutputAnalyzer out = runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jcmd", "-l") + private static long testCase01(MainContainer mainContainer, AttachStrategy attachStrategy, boolean elevated) throws Exception { + OutputAnalyzer out = runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jcmd", "-l") .shouldHaveExitValue(0) .shouldContain("sun.tools.jcmd.JCmd"); long pid = findProcess(out, "EventGeneratorLoop"); @@ -150,8 +149,8 @@ private static long testCase01(AttachStrategy attachStrategy, boolean elevated) } // run jhsdb jinfo (jhsdb uses PTRACE) - private static void testCase02(long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception { - runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jhsdb", "jinfo", "--pid", "" + pid) + private static void testCase02(MainContainer mainContainer, long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception { + runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jhsdb", "jinfo", "--pid", "" + pid) .shouldHaveExitValue(0) .shouldContain("Java System Properties") .shouldContain("VM Flags"); @@ -159,11 +158,11 @@ private static void testCase02(long pid, AttachStrategy attachStrategy, boolean // test jcmd with some commands (help, start JFR recording) // JCMD will use signal mechanism and Unix Socket - private static void testCase03(long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception { - runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "help") + private static void testCase03(MainContainer mainContainer, long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception { + runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "help") .shouldHaveExitValue(0) .shouldContain("VM.version"); - runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "JFR.start") + runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "JFR.start") .shouldHaveExitValue(0) .shouldContain("Started recording"); } @@ -175,18 +174,18 @@ private static void testCase03(long pid, AttachStrategy attachStrategy, boolean // we have two options: // 1. mount /tmp from the main container using --volumes-from. // 2. access /tmp from the main container via /proc//root/tmp. - private static OutputAnalyzer runSideCar(String mainContainerName, AttachStrategy attachStrategy, boolean elevated, String whatToRun, String... args) throws Exception { + private static OutputAnalyzer runSideCar(MainContainer mainContainer, AttachStrategy attachStrategy, boolean elevated, String whatToRun, String... args) throws Exception { System.out.println("Attach strategy " + attachStrategy); List initialCommands = List.of( Container.ENGINE_COMMAND, "run", "--tty=true", "--rm", "--cap-add=SYS_PTRACE", "--sig-proxy=true", - "--pid=container:" + mainContainerName + "--pid=container:" + mainContainer.name() ); List attachStrategyCommands = switch (attachStrategy) { - case TMP_MOUNTED_INTO_SIDECAR -> List.of("--volumes-from", mainContainerName); + case TMP_MOUNTED_INTO_SIDECAR -> List.of("--volumes-from", mainContainer.name()); case ACCESS_TMP_VIA_PROC_ROOT -> List.of(); }; @@ -210,11 +209,11 @@ private static long findProcess(OutputAnalyzer out, String name) throws Exceptio List l = out.asLines() .stream() .filter(s -> s.contains(name)) - .collect(Collectors.toList()); + .toList(); if (l.isEmpty()) { return -1; } - String psInfo = l.get(0); + String psInfo = l.getFirst(); System.out.println("findProcess(): psInfo: " + psInfo); String pid = psInfo.substring(0, psInfo.indexOf(' ')); System.out.println("findProcess(): pid: " + pid); @@ -237,6 +236,10 @@ private static void sleep(long delay) { static class MainContainer { + private static final String MAIN_CONTAINER_NAME_PREFIX = "test-container-main"; + private static final Random RANDOM = Utils.getRandomInstance(); + + String name; boolean mainMethodStarted; Process p; @@ -256,8 +259,11 @@ public Process start(final boolean elevated) throws Exception { opts.addDockerOpts(NET_BIND_SERVICE); } + name = MAIN_CONTAINER_NAME_PREFIX + "-elevated-" + elevated + "-" + RANDOM.nextInt(); + opts.addDockerOpts("--cap-add=SYS_PTRACE") - .addDockerOpts("--name", MAIN_CONTAINER_NAME) + .addDockerOpts("--init") + .addDockerOpts("--name", name) .addDockerOpts("--volume", "/tmp") .addDockerOpts("--volume", Paths.get(".").toAbsolutePath() + ":/workdir/") .addJavaOpts("-XX:+UsePerfData") @@ -297,25 +303,18 @@ public void waitFor(long timeout) throws Exception { p.waitFor(timeout, TimeUnit.MILLISECONDS); } - public void waitForAndCheck(long timeout) throws Exception { - int exitValue = -1; - int retryCount = 3; - - do { - waitFor(timeout); - try { - exitValue = p.exitValue(); - } catch(IllegalThreadStateException ex) { - System.out.println("IllegalThreadStateException occurred when calling exitValue()"); - retryCount--; - } - } while (exitValue == -1 && retryCount > 0); - - if (exitValue != 0) { - throw new RuntimeException("DockerThread stopped unexpectedly, non-zero exit value is " + exitValue); + public void stop() throws Exception { + OutputAnalyzer out = DockerTestUtils.execute(Container.ENGINE_COMMAND, "ps") + .shouldHaveExitValue(0); + if (out.contains(name)) { + DockerTestUtils.execute(Container.ENGINE_COMMAND, "stop", name) + .shouldHaveExitValue(0); } } + public String name() { + return name; + } } private enum AttachStrategy { diff --git a/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java b/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java index 282c4fcfc14..4e7f2ca32ac 100644 --- a/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java +++ b/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,111 +28,68 @@ * @bug 8051973 * @summary Test to make sure that eager reclaim of humongous objects correctly clears * mark bitmaps at reclaim. - * @key randomness * @requires vm.gc.G1 * @requires vm.debug - * @library /test/lib + * @library /test/lib /testlibrary / * @modules java.base/jdk.internal.misc * java.management + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run driver gc.g1.TestEagerReclaimHumongousRegionsClearMarkBits */ -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; -import jdk.test.lib.Utils; - -// An object that has a few references to other instances to slow down marking. -class ObjectWithSomeRefs { - public ObjectWithSomeRefs other1; - public ObjectWithSomeRefs other2; - public ObjectWithSomeRefs other3; - public ObjectWithSomeRefs other4; -} - -class TestEagerReclaimHumongousRegionsClearMarkBitsReclaimRegionFast { - public static final long MAX_MILLIS_FOR_RUN = 50 * 1000; // The maximum runtime for the actual test. +import jdk.test.whitebox.WhiteBox; - public static final int M = 1024*1024; +public class TestEagerReclaimHumongousRegionsClearMarkBits { + public static void main(String[] args) throws Exception { + OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC", + "-Xmx20M", + "-Xms20m", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+VerifyAfterGC", + "-Xbootclasspath/a:.", + "-Xlog:gc=debug,gc+humongous=debug", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + TestEagerReclaimHumongousRegionsClearMarkBitsRunner.class.getName()); + + String log = output.getStdout(); + System.out.println(log); + output.shouldHaveExitValue(0); - public static LinkedList garbageList = new LinkedList(); + // Find the log output indicating that the humongous object has been reclaimed, and marked. + Pattern pattern = Pattern.compile("Humongous region .* marked 1 reclaim candidate 1 type array 1"); + Asserts.assertTrue(pattern.matcher(log).find(), "Could not find log output matching marked humongous region."); - public static void genGarbage(Object large) { - for (int i = 0; i < 64*1024; i++) { - Object[] garbage = new Object[50]; - garbage[0] = large; - garbageList.add(garbage); - } - garbageList.clear(); + pattern = Pattern.compile("Reclaimed humongous region .*"); + Asserts.assertTrue(pattern.matcher(log).find(), "Could not find log output reclaiming humongous region"); } +} - public static ArrayList longList = new ArrayList(); +class TestEagerReclaimHumongousRegionsClearMarkBitsRunner { + private static final WhiteBox WB = WhiteBox.getWhiteBox(); + private static final int M = 1024 * 1024; public static void main(String[] args) { + WB.fullGC(); - for (int i = 0; i < 16*1024; i++) { - longList.add(new ObjectWithSomeRefs()); - } - - Random rnd = Utils.getRandomInstance(); - for (int i = 0; i < longList.size(); i++) { - int len = longList.size(); - longList.get(i).other1 = longList.get(rnd.nextInt(len)); - longList.get(i).other2 = longList.get(rnd.nextInt(len)); - longList.get(i).other3 = longList.get(rnd.nextInt(len)); - longList.get(i).other4 = longList.get(rnd.nextInt(len)); - } - - int[] large1 = new int[M]; - int[] large2 = null; - int[] large3 = null; - int[] large4 = null; - - Object ref_from_stack = large1; - - long start_millis = System.currentTimeMillis(); - - for (int i = 0; i < 20; i++) { - long current_millis = System.currentTimeMillis(); - if ((current_millis - start_millis) > MAX_MILLIS_FOR_RUN) { - System.out.println("Finishing test because maximum runtime exceeded"); - break; - } - // A set of large objects that will be reclaimed eagerly - and hopefully marked. - large1 = new int[M - 20]; - large2 = new int[M - 20]; - large3 = new int[M - 20]; - large4 = new int[M - 20]; - genGarbage(large1); - // Make sure that the compiler cannot completely remove - // the allocation of the large object until here. - System.out.println(large1 + " " + large2 + " " + large3 + " " + large4); - } - - // Keep the reference to the first object alive. - System.out.println(ref_from_stack); - } -} + Object largeObj = new int[M]; // Humongous object. -public class TestEagerReclaimHumongousRegionsClearMarkBits { - public static void main(String[] args) throws Exception { - OutputAnalyzer output = ProcessTools.executeLimitedTestJava( - "-XX:+UseG1GC", - "-Xms128M", - "-Xmx128M", - "-Xmn2M", - "-XX:G1HeapRegionSize=1M", - "-XX:InitiatingHeapOccupancyPercent=0", // Want to have as much as possible mark cycles. - "-Xlog:gc", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+VerifyAfterGC", - "-XX:ConcGCThreads=1", // Want to make marking as slow as possible. - "-XX:+G1VerifyBitmaps", - TestEagerReclaimHumongousRegionsClearMarkBitsReclaimRegionFast.class.getName()); - output.shouldHaveExitValue(0); + WB.concurrentGCAcquireControl(); + WB.concurrentGCRunTo(WB.BEFORE_MARKING_COMPLETED); + + System.out.println("Large object at " + largeObj); + + largeObj = null; + WB.youngGC(); // Should reclaim marked humongous object. + + WB.concurrentGCRunToIdle(); } } diff --git a/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java b/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java index 302bf7cdc73..9c7d1b5532a 100644 --- a/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java +++ b/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java @@ -193,7 +193,7 @@ private static int getStringIndex(String needle, byte[] buf) { private static int getStringIndex(String needle, byte[] buf, int offset) { outer: - for (int i = offset; i < buf.length - offset - needle.length(); i++) { + for (int i = offset; i <= buf.length - needle.length(); i++) { for (int j = 0; j < needle.length(); j++) { if (buf[i + j] != (byte)needle.charAt(j)) continue outer; } diff --git a/test/hotspot/jtreg/runtime/vthread/RedefineClass.java b/test/hotspot/jtreg/runtime/vthread/RedefineClass.java index 33a9d52a523..b17bb55701b 100644 --- a/test/hotspot/jtreg/runtime/vthread/RedefineClass.java +++ b/test/hotspot/jtreg/runtime/vthread/RedefineClass.java @@ -120,7 +120,7 @@ private static int getStringIndex(String needle, byte[] buf) { private static int getStringIndex(String needle, byte[] buf, int offset) { outer: - for (int i = offset; i < buf.length - offset - needle.length(); i++) { + for (int i = offset; i <= buf.length - needle.length(); i++) { for (int j = 0; j < needle.length(); j++) { if (buf[i + j] != (byte)needle.charAt(j)) continue outer; } diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/ClassVersionAfterRedefine.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/ClassVersionAfterRedefine.java index cc601147714..5eb885e9ac6 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/ClassVersionAfterRedefine.java +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/ClassVersionAfterRedefine.java @@ -54,7 +54,7 @@ private static int getStringIndex(String needle, byte[] buf) { private static int getStringIndex(String needle, byte[] buf, int offset) { outer: - for (int i = offset; i < buf.length - offset - needle.length(); i++) { + for (int i = offset; i <= buf.length - needle.length(); i++) { for (int j = 0; j < needle.length(); j++) { if (buf[i + j] != (byte)needle.charAt(j)) continue outer; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC05/tc05t001/tc05t001.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC05/tc05t001/tc05t001.cpp index 9680d01847a..df67828d28b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC05/tc05t001/tc05t001.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC05/tc05t001/tc05t001.cpp @@ -42,7 +42,7 @@ static const jlong EXPECTED_TIMEOUT_ACCURACY_NS = 300000; #if (defined(WIN32) || defined(_WIN32)) static const jlong EXPECTED_ACCURACY = 16; // 16ms is longest clock update interval #else -static const jlong EXPECTED_ACCURACY = 10; // high frequency clock updates expected +static const jlong EXPECTED_ACCURACY = 32; // high frequency clock updates expected #endif /* scaffold objects */ diff --git a/test/jdk/java/net/httpclient/EmptyAuthenticate.java b/test/jdk/java/net/httpclient/EmptyAuthenticate.java index 2e80e1bdc81..ca5c41594e8 100644 --- a/test/jdk/java/net/httpclient/EmptyAuthenticate.java +++ b/test/jdk/java/net/httpclient/EmptyAuthenticate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,55 +24,120 @@ /* * @test * @bug 8263899 - * @summary HttpClient throws NPE in AuthenticationFilter when parsing www-authenticate head - * - * @run main/othervm EmptyAuthenticate + * @summary Verifies that empty `WWW-Authenticate` header is correctly parsed + * @library /test/jdk/java/net/httpclient/lib + * /test/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.test.lib.net.SimpleSSLContext + * @run junit EmptyAuthenticate */ -import com.sun.net.httpserver.HttpServer; + +import jdk.httpclient.test.lib.common.HttpServerAdapters; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestHandler; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer; +import jdk.test.lib.net.SimpleSSLContext; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import javax.net.ssl.SSLContext; import java.io.IOException; -import java.io.OutputStream; -import java.net.InetSocketAddress; import java.net.URI; -import java.net.URISyntaxException; import java.net.http.HttpClient; +import java.net.http.HttpClient.Version; +import java.net.http.HttpHeaders; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.util.stream.Stream; -public class EmptyAuthenticate { - - public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException { - int port = 0; - - //start server: - HttpServer server = HttpServer.create(new InetSocketAddress(port), 0); - port = server.getAddress().getPort(); - server.createContext("/", exchange -> { - String response = "test body"; - //this empty header will make the HttpClient throw NPE - exchange.getResponseHeaders().add("www-authenticate", ""); - exchange.sendResponseHeaders(401, response.length()); - OutputStream os = exchange.getResponseBody(); - os.write(response.getBytes()); - os.close(); - }); - server.start(); +import static java.net.http.HttpClient.Builder.NO_PROXY; +import static org.junit.jupiter.api.Assertions.assertEquals; - HttpResponse response = null; - //run client: +class EmptyAuthenticate { + + private static final SSLContext SSL_CONTEXT = createSslContext(); + + private static final String WWW_AUTH_HEADER_NAME = "WWW-Authenticate"; + + private static SSLContext createSslContext() { try { - HttpClient httpClient = HttpClient.newHttpClient(); - HttpRequest request = HttpRequest.newBuilder(new URI("http://localhost:" + port + "/")).GET().build(); - //this line will throw NPE (wrapped by IOException) when parsing empty www-authenticate response header in AuthenticationFilter: - response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - boolean ok = !response.headers().firstValue("WWW-Authenticate").isEmpty(); - if (!ok) { - throw new RuntimeException("WWW-Authenicate missing"); - } - } catch (IOException e) { - e.printStackTrace(); - throw new RuntimeException("Test failed"); + return new SimpleSSLContext().get(); + } catch (IOException exception) { + throw new RuntimeException(exception); + } + } + + @ParameterizedTest + @MethodSource("args") + void test(Version version, boolean secure) throws Exception { + String handlerPath = "/%s/%s/".formatted(EmptyAuthenticate.class.getSimpleName(), version); + String uriPath = handlerPath + (secure ? 's' : 'c'); + HttpTestServer server = createServer(version, secure, handlerPath); + try (HttpClient client = createClient(version, secure)) { + HttpRequest request = createRequest(server, secure, uriPath); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.discarding()); + HttpHeaders responseHeaders = response.headers(); + assertEquals( + "", + responseHeaders.firstValue(WWW_AUTH_HEADER_NAME).orElse(null), + () -> "was expecting empty `%s` header in: %s".formatted( + WWW_AUTH_HEADER_NAME, responseHeaders.map())); } finally { - server.stop(0); + server.stop(); } } + + static Stream args() { + return Stream + .of(Version.HTTP_1_1, Version.HTTP_2) + .flatMap(version -> Stream + .of(true, false) + .map(secure -> Arguments.of(version, secure))); + } + + private static HttpTestServer createServer(Version version, boolean secure, String uriPath) + throws IOException { + HttpTestServer server = secure + ? HttpTestServer.create(version, SSL_CONTEXT) + : HttpTestServer.create(version); + HttpTestHandler handler = new ServerHandlerRespondingWithEmptyWwwAuthHeader(); + server.addHandler(handler, uriPath); + server.start(); + return server; + } + + private static final class ServerHandlerRespondingWithEmptyWwwAuthHeader implements HttpTestHandler { + + private int responseIndex = 0; + + @Override + public synchronized void handle(HttpServerAdapters.HttpTestExchange exchange) throws IOException { + try (exchange) { + exchange.getResponseHeaders().addHeader(WWW_AUTH_HEADER_NAME, ""); + byte[] responseBodyBytes = "test body %d" + .formatted(responseIndex) + .getBytes(StandardCharsets.US_ASCII); + exchange.sendResponseHeaders(401, responseBodyBytes.length); + exchange.getResponseBody().write(responseBodyBytes); + } finally { + responseIndex++; + } + } + + } + + private static HttpClient createClient(Version version, boolean secure) { + HttpClient.Builder clientBuilder = HttpClient.newBuilder().version(version).proxy(NO_PROXY); + if (secure) { + clientBuilder.sslContext(SSL_CONTEXT); + } + return clientBuilder.build(); + } + + private static HttpRequest createRequest(HttpTestServer server, boolean secure, String uriPath) { + URI uri = URI.create("%s://%s%s".formatted(secure ? "https" : "http", server.serverAuthority(), uriPath)); + return HttpRequest.newBuilder(uri).version(server.getVersion()).GET().build(); + } + } diff --git a/test/jdk/javax/imageio/ReadAbortTest.java b/test/jdk/javax/imageio/ReadAbortTest.java index 7476dbe0de8..bda17aa4204 100644 --- a/test/jdk/javax/imageio/ReadAbortTest.java +++ b/test/jdk/javax/imageio/ReadAbortTest.java @@ -30,16 +30,17 @@ * calling IIOReadProgressListener.readAborted() for all readers. * @run main ReadAbortTest */ +import java.awt.Color; +import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; +import java.nio.file.Files; import java.util.Iterator; + import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.event.IIOReadProgressListener; import javax.imageio.stream.ImageInputStream; -import java.awt.Color; -import java.awt.Graphics2D; -import java.nio.file.Files; public class ReadAbortTest implements IIOReadProgressListener { @@ -103,7 +104,9 @@ public ReadAbortTest(String format) throws Exception { } catch (Exception e) { throw e; } finally { - Files.delete(file.toPath()); + if (file != null && file.exists()) { + Files.delete(file.toPath()); + } } } diff --git a/test/jdk/javax/imageio/WriteAbortTest.java b/test/jdk/javax/imageio/WriteAbortTest.java index 624ce16c94e..43abd703d7d 100644 --- a/test/jdk/javax/imageio/WriteAbortTest.java +++ b/test/jdk/javax/imageio/WriteAbortTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,15 +30,16 @@ * calling IIOWriteProgressListener.readAborted() for all readers. * @run main WriteAbortTest */ -import java.awt.image.BufferedImage; -import java.io.File; -import javax.imageio.ImageIO; -import javax.imageio.stream.ImageInputStream; import java.awt.Color; import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.File; import java.nio.file.Files; + +import javax.imageio.ImageIO; import javax.imageio.ImageWriter; import javax.imageio.event.IIOWriteProgressListener; +import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageOutputStream; public class WriteAbortTest implements IIOWriteProgressListener { @@ -98,7 +99,9 @@ public WriteAbortTest(String format) throws Exception { + format); } } finally { - Files.delete(file.toPath()); + if (file != null && file.exists()) { + Files.delete(file.toPath()); + } } } diff --git a/test/jdk/javax/swing/AbstractButton/bug4133768.java b/test/jdk/javax/swing/AbstractButton/bug4133768.java index ad5f56c0149..4ccec98c6ec 100644 --- a/test/jdk/javax/swing/AbstractButton/bug4133768.java +++ b/test/jdk/javax/swing/AbstractButton/bug4133768.java @@ -34,8 +34,11 @@ import java.awt.GridLayout; import java.awt.Point; import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; import java.awt.image.BufferedImage; -import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import javax.swing.AbstractButton; import javax.swing.Icon; import javax.swing.ImageIcon; @@ -47,20 +50,28 @@ import javax.swing.SwingUtilities; public class bug4133768 { - private static Icon RED, GREEN; + private static Icon RED; + private static Icon GREEN; private static JFrame f; private static AbstractButton[] buttons; private static volatile Point buttonLocation; private static volatile int buttonWidth; private static volatile int buttonHeight; private static Robot robot; + private static int ROLLOVER_Y_OFFSET = 4; + private static CountDownLatch frameGainedFocusLatch = + new CountDownLatch(1); public static void main(String[] args) throws Exception { try { createTestImages(); createUI(); + f.requestFocus(); + if (!frameGainedFocusLatch.await(5, TimeUnit.SECONDS)) { + throw new RuntimeException("Waited too long, but can't gain" + + " focus for frame"); + } robot = new Robot(); - robot.delay(1000); for (AbstractButton b : buttons) { testEnabledButton(b); } @@ -78,9 +89,9 @@ public static void main(String[] args) throws Exception { } } - private static void createTestImages() throws IOException { - int imageWidth = 32; - int imageHeight = 32; + private static void createTestImages() { + int imageWidth = 100; + int imageHeight = 100; BufferedImage redImg = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g = redImg.createGraphics(); @@ -114,6 +125,12 @@ private static void createUI() throws Exception { b.setRolloverSelectedIcon(GREEN); buttonPanel.add(b); } + f.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + frameGainedFocusLatch.countDown(); + } + }); f.setLayout(new GridLayout(2, 1)); f.add(buttonPanel); f.pack(); @@ -123,7 +140,8 @@ private static void createUI() throws Exception { }); } - private static void testEnabledButton(AbstractButton button) throws Exception { + private static void testEnabledButton(AbstractButton button) + throws Exception { robot.waitForIdle(); SwingUtilities.invokeAndWait(() -> { buttonLocation = button.getLocationOnScreen(); @@ -131,7 +149,7 @@ private static void testEnabledButton(AbstractButton button) throws Exception { buttonHeight = button.getHeight(); }); robot.mouseMove(buttonLocation.x + buttonWidth / 2, - buttonLocation.y + buttonHeight / 2 ); + buttonLocation.y + ROLLOVER_Y_OFFSET); robot.delay(1000); Color buttonColor = robot.getPixelColor(buttonLocation.x + buttonWidth / 2, buttonLocation.y + buttonHeight / 2); @@ -141,16 +159,15 @@ private static void testEnabledButton(AbstractButton button) throws Exception { } } - private static void testDisabledButton(AbstractButton button) throws Exception { + private static void testDisabledButton(AbstractButton button) + throws Exception { robot.waitForIdle(); SwingUtilities.invokeAndWait(() -> { buttonLocation = button.getLocationOnScreen(); buttonWidth = button.getWidth(); buttonHeight = button.getHeight(); }); - robot.mouseMove(buttonLocation.x + buttonWidth / 2, - buttonLocation.y + buttonHeight / 2 ); - robot.delay(1000); + robot.delay(200); Color buttonColor = robot.getPixelColor(buttonLocation.x + buttonWidth / 2, buttonLocation.y + buttonHeight / 2); if (buttonColor.equals(Color.GREEN) || diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java index 3222559554e..2e4ed916770 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,8 @@ * @requires vm.hasJFR & vm.gc.ZSinglegen * @key jfr * @library /test/lib /test/jdk /test/hotspot/jtreg - * @run main/othervm -XX:+UseZGC -XX:-ZGenerational -Xmx32M jdk.jfr.event.gc.detailed.TestZAllocationStallEvent + * @run main/othervm -XX:+UseZGC -XX:-ZGenerational -Xmx32M + * jdk.jfr.event.gc.detailed.TestZAllocationStallEvent */ /** @@ -44,7 +45,8 @@ * @requires vm.hasJFR & vm.gc.ZGenerational * @key jfr * @library /test/lib /test/jdk /test/hotspot/jtreg - * @run main/othervm -XX:+UseZGC -XX:+ZGenerational -Xmx32M jdk.jfr.event.gc.detailed.TestZAllocationStallEvent + * @run main/othervm -XX:+UseZGC -XX:+ZGenerational -Xmx32M + * jdk.jfr.event.gc.detailed.TestZAllocationStallEvent */ public class TestZAllocationStallEvent { @@ -55,7 +57,7 @@ public static void main(String[] args) throws Exception { recording.start(); // Allocate many large objects quickly, to outrun the GC - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 1000; i++) { blackHole(new byte[16 * 1024 * 1024]); } diff --git a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java index eb8b630e408..88641219067 100644 --- a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java +++ b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java @@ -322,7 +322,7 @@ public static OutputAnalyzer execute(String... command) throws Exception { System.out.println("[ELAPSED: " + (System.currentTimeMillis() - started) + " ms]"); System.out.println("[STDERR]\n" + output.getStderr()); System.out.println("[STDOUT]\n" + stdoutLimited); - if (stdout != stdoutLimited) { + if (!stdout.equals(stdoutLimited)) { System.out.printf("Child process STDOUT is limited to %d lines\n", max); } diff --git a/test/micro/org/openjdk/bench/java/security/HSS.java b/test/micro/org/openjdk/bench/java/security/HSS.java index c2f746d2449..6d0cf694f4a 100644 --- a/test/micro/org/openjdk/bench/java/security/HSS.java +++ b/test/micro/org/openjdk/bench/java/security/HSS.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,11 +57,6 @@ @Measurement(iterations = 5, time = 1) @Fork(value = 3, jvmArgs = {"--add-exports", "java.base/sun.security.util=ALL-UNNAMED"}) -// Tests 1-2 are from RFC 8554, Appendix F. - -// Tests 3-10 were generated with parameter sets mentioned in -// RFC 8554 section 6.4; two with W=8 and six with W=4. - public class HSS { static byte[] decode(String s) { @@ -87,14 +82,13 @@ public static void verify(Signature v, byte[] pk, byte[] msg, byte[] sig) } } - // RFC 8554 Test Case 1 @State(Scope.Benchmark) public static class test01 { byte[] pk; byte[] msg; byte[] sig; - @Param({"RFC 8554 1"}) + @Param({"Test 1"}) private String test; @Setup @@ -103,119 +97,117 @@ public void setup() throws Exception { 00000002 00000005 00000004 - 61a5d57d37f5e46bfb7520806b07a1b850650e3b31fe4a773ea29a07f09cf2ea - 30e579f0df58ef8e298da0434cb2b878"""); + 0e975b10a6b33473d01baa138c155e81d7b7156b389b2a6a09d49f42c1ac4984 + 2d977e65fceb6bc80e06eace38ce0116 + """); msg = decode(""" - 54686520706f77657273206e6f742064656c65676174656420746f2074686520 - 556e69746564205374617465732062792074686520436f6e737469747574696f - 6e2c206e6f722070726f6869626974656420627920697420746f207468652053 - 74617465732c2061726520726573657276656420746f20746865205374617465 - 7320726573706563746976656c792c206f7220746f207468652070656f706c65 - 2e0a"""); + 312e20546869732069732061207465737420666f72204853532f4c4d53207768 + 6963682069732076657279206c6f6e6720616e64206e6f74206d65616e742074 + 6f207265616420627920612068756d616e206265696e672e + """); sig = decode(""" 00000001 00000005 00000004 - d32b56671d7eb98833c49b433c272586bc4a1c8a8970528ffa04b966f9426eb9 - 965a25bfd37f196b9073f3d4a232feb69128ec45146f86292f9dff9610a7bf95 - a64c7f60f6261a62043f86c70324b7707f5b4a8a6e19c114c7be866d488778a0 - e05fd5c6509a6e61d559cf1a77a970de927d60c70d3de31a7fa0100994e162a2 - 582e8ff1b10cd99d4e8e413ef469559f7d7ed12c838342f9b9c96b83a4943d16 - 81d84b15357ff48ca579f19f5e71f18466f2bbef4bf660c2518eb20de2f66e3b - 14784269d7d876f5d35d3fbfc7039a462c716bb9f6891a7f41ad133e9e1f6d95 - 60b960e7777c52f060492f2d7c660e1471e07e72655562035abc9a701b473ecb - c3943c6b9c4f2405a3cb8bf8a691ca51d3f6ad2f428bab6f3a30f55dd9625563 - f0a75ee390e385e3ae0b906961ecf41ae073a0590c2eb6204f44831c26dd768c - 35b167b28ce8dc988a3748255230cef99ebf14e730632f27414489808afab1d1 - e783ed04516de012498682212b07810579b250365941bcc98142da13609e9768 - aaf65de7620dabec29eb82a17fde35af15ad238c73f81bdb8dec2fc0e7f93270 - 1099762b37f43c4a3c20010a3d72e2f606be108d310e639f09ce7286800d9ef8 - a1a40281cc5a7ea98d2adc7c7400c2fe5a101552df4e3cccfd0cbf2ddf5dc677 - 9cbbc68fee0c3efe4ec22b83a2caa3e48e0809a0a750b73ccdcf3c79e6580c15 - 4f8a58f7f24335eec5c5eb5e0cf01dcf4439424095fceb077f66ded5bec73b27 - c5b9f64a2a9af2f07c05e99e5cf80f00252e39db32f6c19674f190c9fbc506d8 - 26857713afd2ca6bb85cd8c107347552f30575a5417816ab4db3f603f2df56fb - c413e7d0acd8bdd81352b2471fc1bc4f1ef296fea1220403466b1afe78b94f7e - cf7cc62fb92be14f18c2192384ebceaf8801afdf947f698ce9c6ceb696ed70e9 - e87b0144417e8d7baf25eb5f70f09f016fc925b4db048ab8d8cb2a661ce3b57a - da67571f5dd546fc22cb1f97e0ebd1a65926b1234fd04f171cf469c76b884cf3 - 115cce6f792cc84e36da58960c5f1d760f32c12faef477e94c92eb75625b6a37 - 1efc72d60ca5e908b3a7dd69fef0249150e3eebdfed39cbdc3ce9704882a2072 - c75e13527b7a581a556168783dc1e97545e31865ddc46b3c957835da252bb732 - 8d3ee2062445dfb85ef8c35f8e1f3371af34023cef626e0af1e0bc017351aae2 - ab8f5c612ead0b729a1d059d02bfe18efa971b7300e882360a93b025ff97e9e0 - eec0f3f3f13039a17f88b0cf808f488431606cb13f9241f40f44e537d302c64a - 4f1f4ab949b9feefadcb71ab50ef27d6d6ca8510f150c85fb525bf25703df720 - 9b6066f09c37280d59128d2f0f637c7d7d7fad4ed1c1ea04e628d221e3d8db77 - b7c878c9411cafc5071a34a00f4cf07738912753dfce48f07576f0d4f94f42c6 - d76f7ce973e9367095ba7e9a3649b7f461d9f9ac1332a4d1044c96aefee67676 - 401b64457c54d65fef6500c59cdfb69af7b6dddfcb0f086278dd8ad0686078df - b0f3f79cd893d314168648499898fbc0ced5f95b74e8ff14d735cdea968bee74 + a63c20fdbd752910d2a87d25c4ba6bb233d5dd363e5f44a25f766a477f13aa79 + 1474acc5f205d27f1f89234282a2f27205bb914efa34ea8bdd8d7eab6e748614 + 79b5e6088451c07b079196d0d897edc8974e3d2fa244e38242c6831b9124a298 + ed74872b0c6c5cd1c25fcc5279fb1bc30d4b1ee122b9292aedbcfd7e49d4d54b + a1a330d88774e6de909a81624c3440b687495758c83b0439fb104d9e7a695a9e + 62247b52162121c1a80999d11e4211cd23c374a1a23e57dfc49792427806276f + c03cc2d0958990c030e2f8c85e2922547e4ae4918833357ed8ff16ae189fbc76 + 1da5a2e02f824d4ebd8ff731f9c3a8268d3056c1917129a918981bb35079a73b + bac9cba7a99a4536ed4420def0d1ca3b9702be27c6d638fb3a8449edf699d349 + fbd44a8c80985d85946d31221942541143ede3b557929c7f2de6840b0910b6ab + c0dac975200be5f36fbcb5d0ebe0c79d7c8b1218e6afa1fb487399f53ac2a10e + e70113fdc20ab4e1689122568eeeacd0da903cb56ddfe54d386e6f7ab7971878 + e3dddcf7f78e31ce95c9aa6dfa26501027e42f7066ee5a94c4ccf6647d85776f + b244ffa85794e873a12634a5468967f05a9a5efc4276944ec9664aaf9b684db4 + bd417669f2e151f174ae1eed01565b563eabf8177fbbeb2ab61667dcb7423a86 + 2dbea29581cada5c0ebab53c0811ec8ebab234b7dbb30456837e82bd5e23e8a8 + a75f4331a4da821abc63d50b1bdc4bd861a0ba1ebfad6db2fd5d44e587ce9bf3 + 095f314be58411b4b2ea5f0fd10bf091c5038bb8290b5964d6f24edb2aecccf2 + eb81cbcecaf1e1320853e326a8af9bb1f456105ea58b42ae9d994e35c505a74b + 50e04e406b247ff34e3ba27ddb4d7d2a6ade1e2652c25da88a8c6a76024c7c7d + 7e879597438e608741ac8bd3f35c9212db9978d7d54fda331df3e302e3b59201 + 4be842a48a0abc58f5421c8f9d32e191aad082ac04bde2e3695e346d2af5e20a + 00c232def87a5a3dfca8809b1260a43403242b303197a5329b951632aab0738c + b45a51c76f1c97a6c836f40c5165e0c68c16a8ab50b078c2b8fe09f280838648 + c6c74d59fc2c1a46ce424e28bdc7c44a683902b06e9995c67e4efd3981f5424a + 3930100b11bf7ef17c99c5d27a661e8d366ee49441278959c59e7af1ae25bd93 + a504291b3e834c5b68c1e84ee885c6e0152c7cf015aac2065ec19ba3b16166b9 + 02621389a60efea12d8b4a5b5d59ab8145c804bb45694d443b09d4111faa2ba6 + e7e48d3bfa3d1c48b427f383b393c7d0e422fd1e958e14e5866cf6dfd06764c0 + fe384c6ae8e1650860dbc12b0e2731ece7ea40e11fdeba8ae7dff74375d7d717 + 2ab0fb15d6c40b1677a2079b5a4af563fc4c08363176ce4da74b1ef34b0b8627 + 1d405a442b60a554fa88d0320363e7b818bf532d3fbc52764479886d3f4d3d7b + b35d0402b17025abad9cc1525e722cca4c961497f784e55f46d8f8067e4705c3 + 6b62c260391575cfaa949ad99a98e9ca2a55d4e2241c33b3dd8b2505a804c6f7 + 67617d02ebaefaa6cd02cc93041395d1c47be820abc647bd531549aee307cbca 00000005 - d8b8112f9200a5e50c4a262165bd342cd800b8496810bc716277435ac376728d - 129ac6eda839a6f357b5a04387c5ce97382a78f2a4372917eefcbf93f63bb591 - 12f5dbe400bd49e4501e859f885bf0736e90a509b30a26bfac8c17b5991c157e - b5971115aa39efd8d564a6b90282c3168af2d30ef89d51bf14654510a12b8a14 - 4cca1848cf7da59cc2b3d9d0692dd2a20ba3863480e25b1b85ee860c62bf5136 + d443111b4f3c3e02ea3043a3db682e8720e10e67852a4331f55deaf62ff8673b + fc8e3fed9740f6cd4a276556c40de3ce8c7c0e60d7b2744f2a481a0d7854b703 + cc47a30d27ed823933e6d87c5573c135c0ced4c944f766de92f216756824c4a4 + d80b9d5337dee0498becbd5b248920283dac655346a847f93555d9a469c66858 + 51891eb06cdfa25179c9054ee8795477c4806df8790becc8eb9ea458656f82a1 00000005 00000004 - d2f14ff6346af964569f7d6cb880a1b66c5004917da6eafe4d9ef6c6407b3db0 - e5485b122d9ebe15cda93cfec582d7ab + bb8df6a42d2b9f29644c2c99967d2cc569b3a8470a960d6fa954aafe5e15660a + 9fa56cc9a583d7b1dab98da3e6c121c1 0000000a 00000004 - 0703c491e7558b35011ece3592eaa5da4d918786771233e8353bc4f62323185c - 95cae05b899e35dffd717054706209988ebfdf6e37960bb5c38d7657e8bffeef - 9bc042da4b4525650485c66d0ce19b317587c6ba4bffcc428e25d08931e72dfb - 6a120c5612344258b85efdb7db1db9e1865a73caf96557eb39ed3e3f426933ac - 9eeddb03a1d2374af7bf77185577456237f9de2d60113c23f846df26fa942008 - a698994c0827d90e86d43e0df7f4bfcdb09b86a373b98288b7094ad81a0185ac - 100e4f2c5fc38c003c1ab6fea479eb2f5ebe48f584d7159b8ada03586e65ad9c - 969f6aecbfe44cf356888a7b15a3ff074f771760b26f9c04884ee1faa329fbf4 - e61af23aee7fa5d4d9a5dfcf43c4c26ce8aea2ce8a2990d7ba7b57108b47dabf - beadb2b25b3cacc1ac0cef346cbb90fb044beee4fac2603a442bdf7e507243b7 - 319c9944b1586e899d431c7f91bcccc8690dbf59b28386b2315f3d36ef2eaa3c - f30b2b51f48b71b003dfb08249484201043f65f5a3ef6bbd61ddfee81aca9ce6 - 0081262a00000480dcbc9a3da6fbef5c1c0a55e48a0e729f9184fcb1407c3152 - 9db268f6fe50032a363c9801306837fafabdf957fd97eafc80dbd165e435d0e2 - dfd836a28b354023924b6fb7e48bc0b3ed95eea64c2d402f4d734c8dc26f3ac5 - 91825daef01eae3c38e3328d00a77dc657034f287ccb0f0e1c9a7cbdc828f627 - 205e4737b84b58376551d44c12c3c215c812a0970789c83de51d6ad787271963 - 327f0a5fbb6b5907dec02c9a90934af5a1c63b72c82653605d1dcce51596b3c2 - b45696689f2eb382007497557692caac4d57b5de9f5569bc2ad0137fd47fb47e - 664fcb6db4971f5b3e07aceda9ac130e9f38182de994cff192ec0e82fd6d4cb7 - f3fe00812589b7a7ce515440456433016b84a59bec6619a1c6c0b37dd1450ed4 - f2d8b584410ceda8025f5d2d8dd0d2176fc1cf2cc06fa8c82bed4d944e71339e - ce780fd025bd41ec34ebff9d4270a3224e019fcb444474d482fd2dbe75efb203 - 89cc10cd600abb54c47ede93e08c114edb04117d714dc1d525e11bed8756192f - 929d15462b939ff3f52f2252da2ed64d8fae88818b1efa2c7b08c8794fb1b214 - aa233db3162833141ea4383f1a6f120be1db82ce3630b3429114463157a64e91 - 234d475e2f79cbf05e4db6a9407d72c6bff7d1198b5c4d6aad2831db61274993 - 715a0182c7dc8089e32c8531deed4f7431c07c02195eba2ef91efb5613c37af7 - ae0c066babc69369700e1dd26eddc0d216c781d56e4ce47e3303fa73007ff7b9 - 49ef23be2aa4dbf25206fe45c20dd888395b2526391a724996a44156beac8082 - 12858792bf8e74cba49dee5e8812e019da87454bff9e847ed83db07af3137430 - 82f880a278f682c2bd0ad6887cb59f652e155987d61bbf6a88d36ee93b6072e6 - 656d9ccbaae3d655852e38deb3a2dcf8058dc9fb6f2ab3d3b3539eb77b248a66 - 1091d05eb6e2f297774fe6053598457cc61908318de4b826f0fc86d4bb117d33 - e865aa805009cc2918d9c2f840c4da43a703ad9f5b5806163d7161696b5a0adc + 3431bace4875824faf76e488612472b3a535893056745f0f20e615806d87ba36 + ab0935d2b080fd6281fa5fca325926ba219c04a02aa2e2faca7ba0f885cb90ce + 5bf07a6dfb60f55541092cbb9386ab47438debaed31b648cb3cab090ab2c3eaf + 386a2024899e4cb83e75340933c564a22c060e5ac792316123d004125babf59e + 082dc93d4817ab8a7cd772fe28a400060ca4dcecc001203a474f294031c44dcf + ebc3c73f672556cda6ad193883c5c95fb1587042b733f936dc0977cbc4aa13b9 + fd22794a7204968e0cdb73cc19061447617bfdcef141fb9b87538232d92b1482 + 54b0917f252efc8766d6b09b0215c675ab5d41c87630121e5e536bcfea3fc134 + f57de38eff427a531ed403d903c1c96b5fd71d8431c03ca8d521a2c686051e0a + 5a57e199d65b0a60a086f70a3e42ad6b343e5565e996e7bb678ebdc1e01f9041 + 289f45c3e0f56e5aeb269cfe70deca17153ee46388ac0d88b24ee7a32c607726 + 1664a5d10fb5f64ed925351b2475494920acb7272962da31c8db6f76baadbc83 + 9d94373f8a203ac3c62fad998913277153e1db8872f75cb3ab18f4b6ae785d35 + 54785bd261b66535f34a756e8749f6d2a6049c9bf8aa991b1c5d79eae63ebde0 + 99f853608dae24d68d4709c0898bf1e1fb44198a23fd7a7ecd653db67688153f + f2a1c399cb3379903e31e4c4f06ef50671eb071a2084d16b08270ff203d51c1a + 5334d777d169c331db8e3e1c6653649d69cf1a3853423c7de5e688b10d741aa3 + 5233ef53440db7a3bd6b9a613183820ea7ec1e7469d1743cf1d8aefb599f6f1c + 08865c99afd652558b73955734b36794351c246c9822e96bc276cfa7cd942f6a + afcdb162a361332ee79a128c6ccf67d0ae3dec0b0a80e716c572162e9eb9230d + 83c3d758d4efecdfb573864f7fc1f203cf0c64d2fc9a68029ea67d7e53885c60 + c7dffc6e1af3c0460a64a8b21c62107f7a3408b724e478d0018eaee33e60350b + 7e355758d236bf8fbaa82d43955a9df4a5073ab1eab25269e89c9278097ed20c + 0d46b0722c9a0ab613ae09a5220dfffb930f013f83262f524061fb47f16dde4e + 48ba37d1e73c5b63bfd3f80ea1b36ad690476e0338271555de0e8a88a2f4ec14 + e05ab9753633ee4b792a715c6c7c1d01209619c4a4070235fb1022781f5ee437 + 8514cf87b6b274bcf25551fec891fba127dcf09bbbaad957ea1e4f512b64d787 + f32538f53fdffe99e3914e9c9815c812b0bc6c1aee4d9d5a5cacd7f0d6f5ecc5 + 958a595788400787615d3ab0bccdf9fc94c6bcf7154c0975d90fb60fafe0834a + 1cd44979b52548c875094b1adc9c63b5de19f3e888db7a0b7a2c238b4090c55f + f57734c24e69df21697c650c1d8f5f62e067bda229e4ec3e9da93e6fa76a9ff9 + 48327baba8c7b8b14a63291fd7fd6847e20f6653edabbc21e257827be4089fbc + 39047197e40ad2553bcdc603c82a1b80c03bf5a461f31e073295a4cbbc02530f + be5a6c3092813f37ae9e2ec7ee8c0dc1a2379cbcfe2ad550e90f0a73f4e789a1 + 270a3332e277e7113ed38527c241817d391b5a2742b6a4cb789a407525f35982 00000005 - d5c0d1bebb06048ed6fe2ef2c6cef305b3ed633941ebc8b3bec9738754cddd60 - e1920ada52f43d055b5031cee6192520d6a5115514851ce7fd448d4a39fae2ab - 2335b525f484e9b40d6a4a969394843bdcf6d14c48e8015e08ab92662c05c6e9 - f90b65a7a6201689999f32bfd368e5e3ec9cb70ac7b8399003f175c40885081a - 09ab3034911fe125631051df0408b3946b0bde790911e8978ba07dd56c73e7ee + e6ffc1535a60978d93a81a64564b61821c7125542c0fe5996a93e0da0f5f8a71 + 2d2e444d1bd96837bf0354ca844e90b82bf08746bbc95189e2268bfa686e88f9 + f90f35a095a2ab26402fc87ddf3656edfb16fe3816ffaf99e983915ebbcf2f51 + 85f294d491c47fb90d3ce9046d2f05da6a723ac342a32154d1c18b465b49308f + 41ca2f0475adf5ed46413766a6057bc810aeb6dd593691b84752b883c8a1a422 """); } } - // RFC 8554 Test Case 2 @State(Scope.Benchmark) public static class test02 { byte[] pk; byte[] msg; byte[] sig; - @Param({"RFC 8554 2"}) + @Param({"Test 2"}) private String test; @Setup @@ -224,1604 +216,144 @@ public void setup() throws Exception { 00000002 00000006 00000003 - d08fabd4a2091ff0a8cb4ed834e7453432a58885cd9ba0431235466bff9651c6 - c92124404d45fa53cf161c28f1ad5a8e"""); + ff466afe664c2581845b2c6af92aeb6e5c4dd15affc86c82ef4e807ad3c648a6 + 4561666c975fd9cb150d6c7acd6e577f + """); msg = decode(""" - 54686520656e756d65726174696f6e20696e2074686520436f6e737469747574 - 696f6e2c206f66206365727461696e207269676874732c207368616c6c206e6f - 7420626520636f6e73747275656420746f2064656e79206f7220646973706172 - 616765206f74686572732072657461696e6564206279207468652070656f706c - 652e0a"""); + 322e20546869732069732061207465737420666f72204853532f4c4d53207768 + 6963682069732076657279206c6f6e6720616e64206e6f74206d65616e742074 + 6f207265616420627920612068756d616e206265696e672e + """); sig = decode(""" 00000001 00000003 00000003 - 3d46bee8660f8f215d3f96408a7a64cf1c4da02b63a55f62c666ef5707a914ce - 0674e8cb7a55f0c48d484f31f3aa4af9719a74f22cf823b94431d01c926e2a76 - bb71226d279700ec81c9e95fb11a0d10d065279a5796e265ae17737c44eb8c59 - 4508e126a9a7870bf4360820bdeb9a01d9693779e416828e75bddd7d8c70d50a - 0ac8ba39810909d445f44cb5bb58de737e60cb4345302786ef2c6b14af212ca1 - 9edeaa3bfcfe8baa6621ce88480df2371dd37add732c9de4ea2ce0dffa53c926 - 49a18d39a50788f4652987f226a1d48168205df6ae7c58e049a25d4907edc1aa - 90da8aa5e5f7671773e941d8055360215c6b60dd35463cf2240a9c06d694e9cb - 54e7b1e1bf494d0d1a28c0d31acc75161f4f485dfd3cb9578e836ec2dc722f37 - ed30872e07f2b8bd0374eb57d22c614e09150f6c0d8774a39a6e168211035dc5 - 2988ab46eaca9ec597fb18b4936e66ef2f0df26e8d1e34da28cbb3af75231372 - 0c7b345434f72d65314328bbb030d0f0f6d5e47b28ea91008fb11b05017705a8 - be3b2adb83c60a54f9d1d1b2f476f9e393eb5695203d2ba6ad815e6a111ea293 - dcc21033f9453d49c8e5a6387f588b1ea4f706217c151e05f55a6eb7997be09d - 56a326a32f9cba1fbe1c07bb49fa04cecf9df1a1b815483c75d7a27cc88ad1b1 - 238e5ea986b53e087045723ce16187eda22e33b2c70709e53251025abde89396 - 45fc8c0693e97763928f00b2e3c75af3942d8ddaee81b59a6f1f67efda0ef81d - 11873b59137f67800b35e81b01563d187c4a1575a1acb92d087b517a8833383f - 05d357ef4678de0c57ff9f1b2da61dfde5d88318bcdde4d9061cc75c2de3cd47 - 40dd7739ca3ef66f1930026f47d9ebaa713b07176f76f953e1c2e7f8f271a6ca - 375dbfb83d719b1635a7d8a13891957944b1c29bb101913e166e11bd5f34186f - a6c0a555c9026b256a6860f4866bd6d0b5bf90627086c6149133f8282ce6c9b3 - 622442443d5eca959d6c14ca8389d12c4068b503e4e3c39b635bea245d9d05a2 - 558f249c9661c0427d2e489ca5b5dde220a90333f4862aec793223c781997da9 - 8266c12c50ea28b2c438e7a379eb106eca0c7fd6006e9bf612f3ea0a454ba3bd - b76e8027992e60de01e9094fddeb3349883914fb17a9621ab929d970d101e45f - 8278c14b032bcab02bd15692d21b6c5c204abbf077d465553bd6eda645e6c306 - 5d33b10d518a61e15ed0f092c32226281a29c8a0f50cde0a8c66236e29c2f310 - a375cebda1dc6bb9a1a01dae6c7aba8ebedc6371a7d52aacb955f83bd6e4f84d - 2949dcc198fb77c7e5cdf6040b0f84faf82808bf985577f0a2acf2ec7ed7c0b0 - ae8a270e951743ff23e0b2dd12e9c3c828fb5598a22461af94d568f29240ba28 - 20c4591f71c088f96e095dd98beae456579ebbba36f6d9ca2613d1c26eee4d8c - 73217ac5962b5f3147b492e8831597fd89b64aa7fde82e1974d2f6779504dc21 - 435eb3109350756b9fdabe1c6f368081bd40b27ebcb9819a75d7df8bb07bb05d - b1bab705a4b7e37125186339464ad8faaa4f052cc1272919fde3e025bb64aa8e - 0eb1fcbfcc25acb5f718ce4f7c2182fb393a1814b0e942490e52d3bca817b2b2 - 6e90d4c9b0cc38608a6cef5eb153af0858acc867c9922aed43bb67d7b33acc51 - 9313d28d41a5c6fe6cf3595dd5ee63f0a4c4065a083590b275788bee7ad875a7 - f88dd73720708c6c6c0ecf1f43bbaadae6f208557fdc07bd4ed91f88ce4c0de8 - 42761c70c186bfdafafc444834bd3418be4253a71eaf41d718753ad07754ca3e - ffd5960b0336981795721426803599ed5b2b7516920efcbe32ada4bcf6c73bd2 - 9e3fa152d9adeca36020fdeeee1b739521d3ea8c0da497003df1513897b0f547 - 94a873670b8d93bcca2ae47e64424b7423e1f078d9554bb5232cc6de8aae9b83 - fa5b9510beb39ccf4b4e1d9c0f19d5e17f58e5b8705d9a6837a7d9bf99cd1338 - 7af256a8491671f1f2f22af253bcff54b673199bdb7d05d81064ef05f80f0153 - d0be7919684b23da8d42ff3effdb7ca0985033f389181f47659138003d712b5e - c0a614d31cc7487f52de8664916af79c98456b2c94a8038083db55391e347586 - 2250274a1de2584fec975fb09536792cfbfcf6192856cc76eb5b13dc4709e2f7 - 301ddff26ec1b23de2d188c999166c74e1e14bbc15f457cf4e471ae13dcbdd9c - 50f4d646fc6278e8fe7eb6cb5c94100fa870187380b777ed19d7868fd8ca7ceb - 7fa7d5cc861c5bdac98e7495eb0a2ceec1924ae979f44c5390ebedddc65d6ec1 - 1287d978b8df064219bc5679f7d7b264a76ff272b2ac9f2f7cfc9fdcfb6a5142 - 8240027afd9d52a79b647c90c2709e060ed70f87299dd798d68f4fadd3da6c51 - d839f851f98f67840b964ebe73f8cec41572538ec6bc131034ca2894eb736b3b - da93d9f5f6fa6f6c0f03ce43362b8414940355fb54d3dfdd03633ae108f3de3e - bc85a3ff51efeea3bc2cf27e1658f1789ee612c83d0f5fd56f7cd071930e2946 - beeecaa04dccea9f97786001475e0294bc2852f62eb5d39bb9fbeef75916efe4 - 4a662ecae37ede27e9d6eadfdeb8f8b2b2dbccbf96fa6dbaf7321fb0e701f4d4 - 29c2f4dcd153a2742574126e5eaccc77686acf6e3ee48f423766e0fc466810a9 - 05ff5453ec99897b56bc55dd49b991142f65043f2d744eeb935ba7f4ef23cf80 - cc5a8a335d3619d781e7454826df720eec82e06034c44699b5f0c44a8787752e - 057fa3419b5bb0e25d30981e41cb1361322dba8f69931cf42fad3f3bce6ded5b - 8bfc3d20a2148861b2afc14562ddd27f12897abf0685288dcc5c4982f8260268 - 46a24bf77e383c7aacab1ab692b29ed8c018a65f3dc2b87ff619a633c41b4fad - b1c78725c1f8f922f6009787b1964247df0136b1bc614ab575c59a16d089917b - d4a8b6f04d95c581279a139be09fcf6e98a470a0bceca191fce476f9370021cb - c05518a7efd35d89d8577c990a5e19961ba16203c959c91829ba7497cffcbb4b - 294546454fa5388a23a22e805a5ca35f956598848bda678615fec28afd5da61a + 8b0b372cbd26c8e43b5feee870169c7c8345f7d353980ec3f6f6b81c696c672c + 7d0cfc8f74de7a0950f30151ab06c218c4ca0dc425a713060e1f14a3009ed09f + 565b6f6a07d6fee14a618a34fd02dd43745c7c11572f3e2c9a7d7c80d1d16e5c + ca11706861fb5359bb1a8e78d2da42d528d913cc593b414fe8ceb03e71171fb6 + 6722dd5677c5bd6446c372356e8d4dba0da50ce696b80deeac51fac231e59241 + 84706f9dd5820a430a1d0404071a3ce75f14a8fbee1573ad893cf2f5dea0fe21 + f899305b15fb971b785cb7432ca8a92b13fe055d7a1ddc46628b9591291bceba + 0c9c6d76d8c24b919c2c1b6d5c1dcdcfc177e6c7ac67ef0af08222d6780bd686 + 439b78a5575494330d824b8b6962652b15b3d5d4f8ce2216033741f51b6e3aab + c69817097649124460c9ddd7ffb14df8ed1de436f0958e193ba118334fc12859 + 68ae32b6c3d1af8b8c95e4a620e442efb221ae5eb1953c7b8dfe645587916a4e + c26f60ca2b088accfcf5f8f724b558c527f31cf3ed9311315a629d81f2702704 + 56f237d745ea92ba6777d934df150ed9b3e10ce5a8a16011118081287463793c + 3818c2448b10e1ede5bfa8da646d9417a97ae70db9aa8df030c6019dab6ebb18 + 6b9d4db14b3d9b33d1df3b23169963e371e2ec25bc3d932b8503ccbbe85d5675 + c433e62b5926de825420727da4c6bd70dd93fc4fcf9062d4f2acb96699b910db + 9788ffd122d88911f98e12fc57551b8282e5f296cc0dd075121c88e1a5838c3e + 239e2968af2eceec9ee4f7c3433d3145f2b7345d7c418febd0839fd45771debe + 52c0cefb71a38b55ddfb9b8386ec6e7fb39047df9e963d056d6e0b02a2620ba1 + f58264de9b09347ac0320919df80e5a66ebee3d6e801792b19a31c07cf28fff5 + 85b4788aec445d4d04ca005f6a240d8e90c6bc2398df5ec6a9a1858549b67026 + b6c4a91d10faf47fcc7afa56d228d0518fb7a786d2f24decc476203fd84150e9 + 165f11ec6eb168934bb7055ae2ae0f499ec8205565fcd397c6cb1c8f0bafa90f + 6c61a08a4657a19009085217ac255081bf280c726f2c818c543bde5fd2a67549 + efccf9e0d35144f5c8af2c69dda3b01b7333a31d6d6210475f0168db67c22940 + 4d36818b6d530fb23941ae4c63226ec6135e598c879d6ab88928f84da104ee82 + 30d96494b818b9d7004b2f15c7565dee0f611d1faf2ef538c70f2c08919e7919 + 25b81e658743cf8903e40a1323bec2530288820f2c46e85f0622e50eed0a93fe + 5cf92db7d672d2d3186710c0b7e509afd1d498cb21936befc8029c936f9e1f6c + 587071dae0b5999e407929199f4bf03dea05bded0ddc6ccba2a8e880e972f876 + 142c99fbefd3a362b27416cc2aadd8c595ab31cc53af7cfd87362118e9cb409c + 32cf3600eecd314073e8393fe390e3ed60d105a7d054143227874e96a1a16ce8 + 1f9a17f03aa647ef08670e5ba7e561c025775a574ee84bd294b808c2908b7112 + d02f4d6462be588bf27d418545a64dc6fc472e743c913bf7f702356872166a4c + 9fcda456ca69651832c72786546a9e9011511bfdf7351f2333f944ac82e5f14e + a1be1ad7b0b01caf273c9f3ef540cc79c47c7b32a8febcf8e3c34a3a0641e09a + fbcb9a1c6bbf594e44faad8671d6e4c9d8bc053db2ebdd2e22ddd8a154462b23 + 6b47d1fc2205a4e7405d8e883189d8b863b31152459e602bc6c30d0baed658a6 + 4f2ac6858ea5e11ac3fae173f1a251cd7e5b26693bf994a952cc12a9b684a919 + 77510077cc11002a325697eb0a7f86f7b45275e13e89d959a593d51c98cbb48f + bea795ac5d5e61c4360431bb0712096c1e88a03d2367b2772f34ca938a4c0180 + 68aa0f90314b6b23ae01437178bbf812590e347a7759581748d877a31c94a7eb + 9e839b0f2654a354faae234a819fbab9c32374f3b99ea7deb42e6a169e03d59a + 0ff3a6b4809059fcd4e5c426e5d580f6fff8e49be1c9a1baacad5b1cf0284060 + 6969a2c6d04fbb30952ea3f792a60e517cdd3cd8f427c335b9a66ba6ac321657 + beb77de5e2b8d4a8f5c425665b9cadd6a379b7ef5ba513cfb2b2022d8e057637 + 38d0edad6a24b1e57d7ebd11434a1e6fb00c1f5f9228bcdd2f24c468b7b4408c + 35b54e09fe59ed0dbab9760b3fe415c277e39a0bdd74783d7d0feb4d7428b609 + 319f8e667899fb52c822076dfd07286d8c6058c2fcf8618cb77d0ba1077f49c8 + 8f8ef55e980307dfa8d9a3076d8a7ba32f1c822e1c6bf7beb997e03181bade32 + b0b69507210466acd24cc9e13e4913c7e31dbfcf84021fe947e37f469de19488 + 097852097888f11de144fc03606c68d63c7309c054853e1c66ca1b499898fd8b + 5edc934e7f368022c2576e18db909b88a8f9c6caa5fdc00f7da47995ad2e21f9 + b9e3133321ec6e7f6d43ee30b5376b846ce6390e1168b0543e4a50d961f82588 + 58569f6a98e5bcad0dd90c4b88e982f34e7ad2897d8218aaa9284d947ddba4eb + 25a1f02ea59504d82c1e570a2804dd9fbde7dfaaa40996e9aeb0a3d65c27e3cf + d81005ad070375c868ac754bd849700c52b10828deab05eefd2d0575a3ef7338 + d7ae9fe2c1c6c0f38abb7a63381a6903035ce87b93e0c4927e6b15a32d8bf86c + fd9f9bd21366a2a264ebf96bb1213ae8bf7e193bd3eb041a7beebc8d5c474b2d + 1a2afd2488dd1f5176e99b11d6986bd8a30f2c4de7abc0a8b9d18e591c2e7deb + 05944d7661cce336f0c08ed3283a8500d91030e2553b1fa7839ff232ac8f70ee + e1656c964a627bec73bf015b10b59551a38cc0a7b95b4cce2f8292ea28c85c20 + d51a97d0e0c59f99b9af2fc7585cb97999c298885522e6bd8a102cbeb891eeca + a7d3a2402c0a00ab85f66f0267fbb707ea1052f1f926e4328bfc31cbbfab6689 + 5f290ffb90970a62e506ef39513a7d3792c0c3f8d7cd285db8326c6b0d5d4323 + 261ef9ccaefb1fa8e68b9de82345578729904ad9de4f2c5640fddef0c4f54ca2 + e12115befeecd8145be43d3ade502970e255cae2af3cc221569592056eb9f61f + fe511566f235325bac531d8b25bcbf31429426d002f265a4971927246efe218e 00000006 - b326493313053ced3876db9d237148181b7173bc7d042cefb4dbe94d2e58cd21 - a769db4657a103279ba8ef3a629ca84ee836172a9c50e51f45581741cf808315 - 0b491cb4ecbbabec128e7c81a46e62a67b57640a0a78be1cbf7dd9d419a10cd8 - 686d16621a80816bfdb5bdc56211d72ca70b81f1117d129529a7570cf79cf52a - 7028a48538ecdd3b38d3d5d62d26246595c4fb73a525a5ed2c30524ebb1d8cc8 - 2e0c19bc4977c6898ff95fd3d310b0bae71696cef93c6a552456bf96e9d075e3 - 83bb7543c675842bafbfc7cdb88483b3276c29d4f0a341c2d406e40d4653b7e4 - d045851acf6a0a0ea9c710b805cced4635ee8c107362f0fc8d80c14d0ac49c51 - 6703d26d14752f34c1c0d2c4247581c18c2cf4de48e9ce949be7c888e9caebe4 - a415e291fd107d21dc1f084b1158208249f28f4f7c7e931ba7b3bd0d824a4570 + c3aba396848a87900478ae558564722df671d145ad178dd9ef736fc5c353a8db + 82e4d9999c4c2e0fae928a66cd3aaf71678ff745d5726d65b0dd6a0ee5f85ca5 + cecd79ef77e4aa47d284a0bdb71662148029d8d891e2381bb7e6045efae1f641 + 505c4b31a8d5acae51cbef029b047e52a5b495aabeae20ee94f8c56ae9b0ac6c + 2d01207d212698865cb0a47e73b6247e777118a617c4b49a558dd4f1d0886f19 + cc2344598bf5cd9039bf7879d37abc66aa3947caf939425adc599d3d1190747c + dce7f61a12f92bd2c1ad95eda9a3b2af26c8ee652b9be2f36e1f80b2ef37bd23 + 2a0d94cc605402848df45afd8ae36d729b25f00d1a09e8fbac6e323669227506 + d0b7b2bab0b320bf58e69a6879e67880c6818ce83f8630c91ab0e82a3f54ceeb + 1053a66d540d800956b248e951695e52c4290014c4fd7eee8c93393e593cf54c 00000005 00000004 - 215f83b7ccb9acbcd08db97b0d04dc2ba1cd035833e0e90059603f26e07ad2aa - d152338e7a5e5984bcd5f7bb4eba40b7 + 0f5cf24b2d72360a58d71392202a49fbef628a53b11e3617bbc1723a879a89e4 + c64e0e5dea7faf8cac58d4e7fcd71774 00000004 00000004 - 0eb1ed54a2460d512388cad533138d240534e97b1e82d33bd927d201dfc24ebb - 11b3649023696f85150b189e50c00e98850ac343a77b3638319c347d7310269d - 3b7714fa406b8c35b021d54d4fdada7b9ce5d4ba5b06719e72aaf58c5aae7aca - 057aa0e2e74e7dcfd17a0823429db62965b7d563c57b4cec942cc865e29c1dad - 83cac8b4d61aacc457f336e6a10b66323f5887bf3523dfcadee158503bfaa89d - c6bf59daa82afd2b5ebb2a9ca6572a6067cee7c327e9039b3b6ea6a1edc7fdc3 - df927aade10c1c9f2d5ff446450d2a3998d0f9f6202b5e07c3f97d2458c69d3c - 8190643978d7a7f4d64e97e3f1c4a08a7c5bc03fd55682c017e2907eab07e5bb - 2f190143475a6043d5e6d5263471f4eecf6e2575fbc6ff37edfa249d6cda1a09 - f797fd5a3cd53a066700f45863f04b6c8a58cfd341241e002d0d2c0217472bf1 - 8b636ae547c1771368d9f317835c9b0ef430b3df4034f6af00d0da44f4af7800 - bc7a5cf8a5abdb12dc718b559b74cab9090e33cc58a955300981c420c4da8ffd - 67df540890a062fe40dba8b2c1c548ced22473219c534911d48ccaabfb71bc71 - 862f4a24ebd376d288fd4e6fb06ed8705787c5fedc813cd2697e5b1aac1ced45 - 767b14ce88409eaebb601a93559aae893e143d1c395bc326da821d79a9ed41dc - fbe549147f71c092f4f3ac522b5cc57290706650487bae9bb5671ecc9ccc2ce5 - 1ead87ac01985268521222fb9057df7ed41810b5ef0d4f7cc67368c90f573b1a - c2ce956c365ed38e893ce7b2fae15d3685a3df2fa3d4cc098fa57dd60d2c9754 - a8ade980ad0f93f6787075c3f680a2ba1936a8c61d1af52ab7e21f416be09d2a - 8d64c3d3d8582968c2839902229f85aee297e717c094c8df4a23bb5db658dd37 - 7bf0f4ff3ffd8fba5e383a48574802ed545bbe7a6b4753533353d73706067640 - 135a7ce517279cd683039747d218647c86e097b0daa2872d54b8f3e508598762 - 9547b830d8118161b65079fe7bc59a99e9c3c7380e3e70b7138fe5d9be255150 - 2b698d09ae193972f27d40f38dea264a0126e637d74ae4c92a6249fa103436d3 - eb0d4029ac712bfc7a5eacbdd7518d6d4fe903a5ae65527cd65bb0d4e9925ca2 - 4fd7214dc617c150544e423f450c99ce51ac8005d33acd74f1bed3b17b7266a4 - a3bb86da7eba80b101e15cb79de9a207852cf91249ef480619ff2af8cabca831 - 25d1faa94cbb0a03a906f683b3f47a97c871fd513e510a7a25f283b196075778 - 496152a91c2bf9da76ebe089f4654877f2d586ae7149c406e663eadeb2b5c7e8 - 2429b9e8cb4834c83464f079995332e4b3c8f5a72bb4b8c6f74b0d45dc6c1f79 - 952c0b7420df525e37c15377b5f0984319c3993921e5ccd97e097592064530d3 - 3de3afad5733cbe7703c5296263f77342efbf5a04755b0b3c997c4328463e84c - aa2de3ffdcd297baaaacd7ae646e44b5c0f16044df38fabd296a47b3a838a913 - 982fb2e370c078edb042c84db34ce36b46ccb76460a690cc86c302457dd1cde1 - 97ec8075e82b393d542075134e2a17ee70a5e187075d03ae3c853cff60729ba4 + 4849cdc5ce9923584e66bda4a1e96c856ead6a30672d94cab9ba1dcffe30843a + 646bd1ecba04f13bf7c6d7d8aabebfa8cb9a2190cd93d65d921ab7035cc81951 + d073609e5dedeb6ef7d00e2ed4c2680772077a9ce3f99ca74eb97f91339a81b1 + bb1c0dc10ad799ea594d4e7760463b4e441661c5f8e09ee9cc82c461dcfdf13d + 391db836b3d30fb42d33cabccb8ef9c81d054114e298a8100ac8ba9bcee4f518 + afd7bd2a158db134dd5ed299435ab7d2dc32db8b7fe35b24186e3c4b6114f7d0 + 46ba7de17e65ce9e1c5618c308c650a828d1c0f786a3d6a69ebbf04e51449308 + 868ecd7a5ce8f87f796396dc4837d08740376205249d8517a47c2ba816ab6c9c + 8bd8fd841ba4667ec53d353a661ea9e5ffa1769d981e4a31178e4f5ad3d99623 + d58c0ab2514b3c5306f3c83927f1b11a3784a384322780b100b44369f80b340f + 8212ad7f5092c44178a22a54110da8f8d3e8ac473aaa687587ea725806f44eaa + c1e340bb7aa801b455914418c1cdd6b59007f4ac5e9d519f2158762e40957507 + 3d6f30736f065bb74cd2c5d60b917cbad94af657ef37c1b92938c959e21d23f1 + 6950c38c2f6eeede9b1675dcc4b4985bf892f3a2a0ac601bcde4acde5ccdf71f + 0a850d9813f92f7279482ae2697fed0722d456d8557ab5bb3fd49421f8d2e71f + 06769fcd695fc186ecb0236051b534bb6a6641d859fd013afa975c0bf889b900 + 433581712b4b04c758fc121deea327817456f70135c3db767e16041f933186c4 + 081fe52635b917bc809c2063d035e14fb512a452c8f443f2a66362ea6b08ddd1 + 6d3a04065611cc962ccad06598fce7821837302ba00d57a83654130f582ce62c + 3266cae361d7db6f2b740ed7f90dca1ff4bf9ec4a0b7cbce226390bc2c38b3bf + a27a40508139f985749420e6fc4ebafcf4799248661e1134e5442f1ef8714739 + 1d589b45ecb61ac90ad6f82cb2bc3f006b62c40dcda5c362b5d4a8c56e42f672 + 1b8598de29d5d6c1293b3751d48ccff5c5805a59a41c00a6758913c86861f2ad + 2400f93fec76e1062db46e4e21f70d7881b7c91bafb9cd34afbfb05ce072fb3d + d4d9970ea49b57ed3ac73a2d75973f8d2a29de6e963d10bc62b695359d5807ed + 7ea0eb6908207698d08e96b619755872e840248550f053cc2597a65df404577d + 828c4604dc143cd42df691daae06a50502d7ad26d577478a00131fb4de24e780 + 39b56b4fb1408a26fa72a9f5db80fe39e49e414a27d57ab3abef508628812bea + 6f61e9e182148ddd920efb7493d3b68a79c3946c8dec31fe6963e8c2dea92dd7 + 9f789b20036b493bbdf605f45654498b93493181b71f261194f1faa6180f23ae + 6417720055d0b966a650e5f217bbfb1c711470fc9014874f8283d6efcabed894 + ec72f5887580f5fb9eb5e9be81a9e1f8ad650acd07069d499720815d052f4e11 + 8d14be427742a206f275a1b6570f684feb8c4cd62cbc89d0a93de601a7f0ff40 + 4125b7d29c1820d0b26490efde697f1699f4490a8b5db33a07af8df86da46817 + 2ebb99d63c45a3786d2be23395d5761f1c59ee591e5ecf35ba5cf2b5d39e8615 00000005 - 4de1f6965bdabc676c5a4dc7c35f97f82cb0e31c68d04f1dad96314ff09e6b3d - e96aeee300d1f68bf1bca9fc58e4032336cd819aaf578744e50d1357a0e42867 - 04d341aa0a337b19fe4bc43c2e79964d4f351089f2e0e41c7c43ae0d49e7f404 - b0f75be80ea3af098c9752420a8ac0ea2bbb1f4eeba05238aef0d8ce63f0c6e5 - e4041d95398a6f7f3e0ee97cc1591849d4ed236338b147abde9f51ef9fd4e1c1 - """); - } - } - - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w8); - @State(Scope.Benchmark) - public static class test03 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({" h15_w8"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000001 - 00000007 - 00000004 - 0dc6e2060bd57f6893d7934b26515ce751360f93dd74a648fa015aa79c862407 - 5ae5daea402617abb48a1f6b9e2c9f28"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000000 - 00000000 - 00000004 - 96755d5f8af0aa32419be743afe779842db52a82387fedd67881aec7172db8c0 - 70734189eadc76de06e2fc999e8ce42e7ba68c942515b4547abc8c6659a42fd1 - 371b03ef9ddafdf755b4ea374bfd00b259baef59fd87fd23b1ca5c254ae54fdc - 65eec03046b0ca68e8168f82c2e7d28f456ab4f3c69c67ff550cbabdf0f25437 - c890347db9d87e0fd243a0341bd6d6cde5190d3c3e7a249bfb757228fe6353f7 - 69ce313fdaaee88c0416622625f3b6206c2302633e81c23f81de067393a3e3c8 - 537d3b6b800e7ccea2d90787fb8b7c73cbdf1e778044786ad3b47cab75f9238d - 4ef8913fd5ad1e9f762200a649c3e42915f66210c6674a9c0f5a1dc780607b36 - c20ea9e299b2dffa4cd144d0715d18cc7130736ebaa67db1c69336ac3c4295a9 - 94c725bb75a5638a569399f4905f39ccf87999e053fb08ac6e3c04dbbb9c9196 - 121306e02152603817a574f15dcf010ae68401367024a62ecc4c0dc68bbc76df - c604978101c1ebe4f5fbd8b0bd14aded6740c60b3cb18f8d166c4857940ae8b9 - 25b707b56637499984f24194cdb2aa66b1bb80a679a8a40bba732ef19b80c301 - 91bde4b32c6ec0267d81dc86a07ab30afb24b422e99285faae17e8679cf3a6c3 - c1682a1d91afb678700fa40fabf03e8b795bd06c4b0b2f8f124ee6790f5aa410 - 5b8eb7b845efddad84488ebaae01ba7f28e9c670bdf4a142305f3376d13c1a55 - cb3e8618e05c11bcf244ae51b825d221e372f45b9c0f512a8ebbeea9a01f213b - 75f69f8090f50c11f13ab092c947ded0689803c834c2bbc8b80310be3ad15972 - b745678270a0a670806ff1dfb00c65bf661356634bd9466946d79e7e59d4bb63 - 008f22127172f54c7c15531003a7d31dd949ba15a401b6e8b574f462ee296fba - 00e523fe2c54b4b763eb18028d49f5fe60fa88c7c26188710a2ef040c2641c1f - 0499a41352ce2c397bee4fa7ffc84a4834419bc571bcfa9ecf17e5e30e14042d - 424d0651e85b826e8bf592285e83d01b8b67eff87caaca112fd67a1ed4d5ae7e - 2a587d4390c8fd1ef366ff80b83ab02973bcce0be3352656c7e07dfed0df04df - f886adda121035831bf24c31a47157fa19f1e29a7c329a8c0647365886d7914c - 969f5477211713dcfe40883c9e00037b200190aa8bd6441e2e9caf895b9ad8d9 - 52dc7e2ccaaa1d5181b1554c90da50f53bbc993e9a04caed8aff848b72470d1c - 7deb858d9baf393f63d8f85cf570161d74a12c93de618d0b1112d5c73164358e - 92ce5e4d344b0c9a20e045b47f7ba00567b49cade32612222a5178e5868d88a3 - 3ec703145ba626a497a716db4ef391cd6c4061dbb904bcbf6ce0e9010893d15b - 991b3b0b1d48e2973a19bd94ce2de05577e3db8961dd40c2107ad39aca37e101 - 66a1788260c7cd125e615b0f19493923a17c0bdba2c982a6ab29fc28689e2b55 - c6460afe1e49332835228ea102e9bebf60fe64e44dc1643eaf49c569331e8ca3 - d4c7a8206d4b088d786aa514322d9030266fd52d5b92170a112c36b86117f8e7 - 37520d176ee71b88a13e22b74afb78915c8516bc2967b46b350c6cb5462cd3fe - 00000007 - 7547b8dd925185bf123233ebd5d6efb5b84c25f193ccc96f3cf5746053054d09 - 274b10a2e41c5b137cc6e3008f6fbe13a32b41ba0ca3d5b95d2ca2af3a7791b4 - e4e80d0a837cc7ca2660105679d28c7230bacf244b74e89c9d1a00ec30a96d12 - 5ff86a045d8d1ce2cad8df211cea8053336b35a4ce75ea9b6a3693c906486a2e - f978e4bc95d39450ae4c44b5204a0f463061cecf2f4b5a3182b40305b57d9bf9 - 130d38397d257fae6eed3ccf5ed8739738f948aa1e99ada7da70e2f4cb090758 - 21323fd7b9934344bb47a53196150b88c4e016363132e798a5949a2b52e7194b - d4babc9dc13749f7e69ed462f42de21e03186b6e13aa496b73784d071f8f8292 - 63b37b71c24b1316bfe5dc48d19cfb4a3dfab112311cbedb59de0fc6d139676c - b5cca0ed495ce2251895447f4983d8147999a9e8a3fbae038e0d3c941b81bdc9 - 6a80dc3b8569237837940d148150c400d2a93ffe7f2b62aee591498b6c659cb3 - 1da85478899ad1bfce0803419a4b5bfcfb0ffc27481c351dc594af1146d1ba70 - 127968e379d34fa22c03a1ca9f2cd8d2f255e9ee2058a6b018cc464d758d633f - f4197291b1ad4257f8f76e1633c19f77fc361767a7a3804d5607931d975d3b19 - 5182fd0867719ce10daf0f0c0d52b16b8088ca9a26a22aa05224a1765fc82961 - """); - } - } - - // LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w8); - @State(Scope.Benchmark) - public static class test04 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({" h20_w8"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000001 - 00000008 - 00000004 - c8568f619f0d5429eab1e63c80e058d1b8a326640a6ab457d776c52eec545dd9 - 7fedc7e225ab0cce270d961ff9b1615b"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000000 - 00000000 - 00000004 - c89e20317ae8d2211c381fe7354bf382a750e37c307588a30d1bb9a5868e0fbf - 414378b30f8c59ccb95a603f03679a417c01bcb191677d629c37a396ffe313c7 - f27f1553e993102d1b311b92fd7669c2d1ada6cc808c11477c86fa928196028d - 3855d6a39fb56a73ac8eb812fa1974778ab1a7838eda03e4b7ff32d8faad4574 - 1ede66888334c584ae4086d6a5446772c3f18041126e1972d5acb593261a0a5f - 2685e71bb75fae408c4d8dc359bd723d97b5180d96d57a9edbaa7a74f2ef4aa7 - 316bf4b8232bb32b32bfd3e6c4b7e1356d5822fb90b8c861e8ef9a1f7cd67b32 - 2b632c2565a6ac6e3635568f1c2cda59cf4ea6a83ec622f81dda9db0b91fff87 - 080fc8b29ee5514cb25c943a714bd298ea0bba527decdd546c76151b0a9b6c60 - ef9de9b8aabc3c979f08fa1a613682eec4c564e5c0d87e932bc618b6009ad575 - 59489d25a58a4338a03c9ed4c8a89eeea418d5b4a7f813eaf163e2530a40ee84 - 9b8893f91a2f5aeab8ddd32ad8bbb8e0ffac69d0f1b5333d5211d11f32cb89a9 - 9f7f346aa5f3c68447e831dfbce57a0a90ac32cb59066f1e5a0c7eb6bb5ef4d2 - e941f0a8ffe6e8e944cecdb7124a866e4282ecd848bf53f94f0323828a2250f8 - 9a59dbc5a0dd02fc90fc433219ce64e982d86c5ddf3bc8bff3ac7f2c6e5dbab1 - 50a2f4371ebab285f70e25fb0f64667c5805381ff1031321e6f8cb1c85250393 - 5db51e0032f2da99c0bcc22cafe3abd1d7fddf676713a7fcf2388ed13d60a8a1 - ccfb996d9d0accf2be789b949f8cb8ee895f870c4b0c4280a99713abfa29377b - b22a6cfa5f3e0bfd7b6b65c395ac40f8e88980fce0c4ea54b55271a6b3a78a15 - 957cee33a498d237cb0b6457e7b539591b4c3c01b3ed1e75308cb2d85b1a5d46 - 40086d1f3c01a244516beb5409175179cc112c16bef7041c92be7e25843703b3 - c9fdbb1e9e2d880f9e2c54b8cec53bff94d15406cdac5793dad36af28abf8f16 - d95606410d7a8b2af01ddea64572d77609bc9b1f26e0f61ed6115709edaefe5e - c3c44e62d93ffb3dd868f799de31fdd82a5ddbf9126a5271fb368624ecfcba8e - 859e9d644063e2d016f3bd6984495bb67a92295a7ba6958d09fb3fa5415cdfbb - c25605e991a5a6d914199f50842357226438c5d757cf1d0bbffdabd32cdb1559 - 3167d8e672bf1653c2c7466ab7a84e4b587e62be7fe73270cda64513e39966ae - 71108c4d187175ae14d9d36dfe6754770febe70c88515b108a20e4fddc240531 - 3a47377388104fb2597ab1c6ba6aeaf96bf9fa3ef7aa8fc61fdb46fb4c99d401 - 3ec90362b3b2df6b9be155ffd520f696950ac931d1d32c1fae4d0da0ef76065c - 5070edf2043fc9b03ec3c250594f92b8f80862182501a4cb2637d79d347cc2cd - 966a3d20415bc34a870d0e9479da62a820f7973e8737a3d1f1cb04507d70981c - 5f30c0319443ba0a03cab8c8460306b5a66dd1efe29956995ab4488ee20ceb83 - c0891c84eb01761ed74d514d483a51e11a938e89e1f1e6b4a23ebc71150b9381 - c01faf71b0ab4f2842f342b80d6bb58bb410091e314127d1c33520e5f38f02f1 - 00000008 - 44feef16ea19cce8296b02d3955c58a873f2adb5672f5408d2a1c404c0a955a0 - 45f483df1000b0cd4dbf5c7918b5259866135714df5fe538b26c10d19b29c5bd - 3e6d7f04bf4544385f9fac1e216e371888f866ac840a83518f940f1d0c77487c - eca40d5fec7174006e7255ccd1a85fbd745c0d17797e0425edf97a92b8eb3b79 - e524988e3aaaeff9ae4762289737a39acf87e381b5cbe4fc2a0ec29bb3fb5dfd - 77c4ae959b46e038e7150c7bb26613125728dbfaf900aa6696c6f2ce0f590c30 - 14d6b61f70897b732564baa09674b12ff2412eae3378a15ca8ab7d79af7372b3 - 3dad3878699eda11cc5265d591a2b00a5d948c38fb4e9c4bfa2f34328d590c19 - 26396c9db7355037bb9e7fa0918e9d2467d358898bad77ed3fdd2cb6f0d14f92 - 67ba57212ea080200635419bec21ac4163aa41209865b212c5f4b000968e2837 - f55c5dc8389f44824427b4e6cda1917e73f7fab883717a0304373e95a7118909 - aa1e7854e2546c766823e2f2f4a52f001763692bdb45675ee65101f10007fdef - b5205b6f2d74c42396a7de0a55ff47855e50cea65f46549f845ff855ca6bceee - 450eb11b7932b6465736893ca654e1faf280ec2da99dad0b833f5c4e7d805af1 - 0e95359ba4e23b2640e2768075815adb2298fb5d1dd3552b0e868c2b69a92da3 - 8b83713af275e933354c5a02438480004d26d0667c3d31236f2e42e594b3108a - 2631d63f6b0d6abfa0cc338294019b38bed8da4b49b0ff1a64871ff648687c5c - 97b863b78eb60844af1e94d6d3ffbaeead48a974e65fff24776553b3dca6c7b3 - 072a39cfd09a8bf9c7591c605659c1b103288486475f54be0fb80c18717a944f - 51b6d317fba486e1e0ab5afea205335836e717a185827ea4cd47d557be53cc4e - """); - } - } - - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test05 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({" h15_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000001 - 00000007 - 00000003 - 7bce4db5bd53cb23819d0fa2181e4d441453ff821284c9d83b8ddace22581469 - 593d6dd0aa2c99feddc84f8242f6a002"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000000 - 00000000 - 00000003 - 92f6ada5a00376437675ae462a5c40d4b1123d97352fdeb3f0b6dd741a3e4db7 - 60ec956306dc6f2900f5e70e427265deab2d979ebef270cb61fac22a6b6ddc78 - ec265af6ef86c9513f3de135f674948c08e5cda0cb953fc6846e2720eb669fd6 - 2d7e1fd5de25ea3491a4d018782cd929f8df2684ed20c2f71950ac606e86a475 - 4f60cfca6810ff34233425f932bef13cbb334981f71d54ea71de3510ee52fd31 - 85cb24191f426bdec8c10caa831e74498ee52dece68f886e9b157b68f2f521b2 - 17e5907d824bca542126b9d79c70ed4cb1431146025e42ecf8f12b970f109f79 - f74e4af4511d966b032976f93ae8118cb4cd3924e92bfe5f508101b0abdc53d2 - 6f5c1720448e2efa4b97aea98e2069eb4495e2c093601fe70193ed469162e976 - 4ca3cf64866c59189a488a9e7a510149e0e9b92b0fadcabf22140841946997c4 - 51410e4954faed09bc3e3e5dfdcfd598e5e70966356718230db6ea8bdf22256d - fb337383d342212b6fbe4be731aef548e86e628fb372971e20d878d3f003b06c - b363799967396381c34252b306a67cfd469710aa9664222dc22fe41008919439 - 9394d75ffaeeac3b621b0643de2e98f723a761ff6e695f673c3d70918247ef5c - 39f222ddedaccc63b6da7ebdfef33a1aba8df3e2444610f6c7b72ba15352f783 - b1cac31841e58f6f22a78e2f8521379e226c6890fe41682f2c2a74a44f619f05 - 84a343deff837d809e41e82cc6ca0b568eb4dfaf5df71de6ad488a3733d07db9 - a1d4137cb10244167dada62b3300e5329f886bcf2d35568f39ec759ca82687d9 - 37fc2b6c7b22d0016f856d9ab353503399bd525298a460b5e5b748942affbe5d - 5f562145c6018f53175bfb1c145e512baad481193889f487eb6a007ab3fe7d0f - 3e7298c3519fb6d6f6f1c493f5e18bf64e5d421ad60b5c01b599aac05355e674 - 1966c4d95f3fe002fb936c948121db57a921baef1d9aca2aa918641705a7618f - 59df64211e2a0043088af6e970e6e87997a7f9b1fc85513dba92dc8d1f990ada - a8694c4b408341d2e1e01e07ff329486d322ee9b5fa7c3498558c503358f29ed - 7abf96c1928b3d21f5262517800587d01517a3ec8fbced7d3f0f7523e6544d7e - 2cc5afb15b709fac35301940ca8cf4ef09abe8d1b175cdaa84caba9dad175890 - ed9f51d762881e16cec7fed78fe9324bea6b372c09e1ec8078c73192e6869830 - 5f16d35fdbe5ce305473399014e15c1011329723df62e3f39d28b9e9576e16a2 - 1199b8eb076017b0500ec5da3e33789a48f6115856a586923f23f167912a307e - 19cc96697a4c3198211e95defbc541b797718b0a59bd330a069a3eadd2c285e6 - 275dfce172e1a109614f0a23ca45fe29dbdf943710176ac138ca10e8a09d87f0 - b59ecc4073fa253e0b6707557d075175a167bd0390e089b300d3106c21e83aa0 - 0ab384f9b301da07eba951294252a421e373def9205711db8326e1558bbd7a79 - 3665e5663ecc7a552223edabcc6333f07095f274d3e3aa8ec114b8e124aaac0a - 4e99113d1950ddf46edf9ea8c8af0d9fd72146885e381a9d899b84d404906db5 - 6f7f3c209be9da130b0011de9916f7d63c3172637ad83e9a9566d7938559fae3 - ac94602daef9f18a8d908e55dc962c48aeaa49c29b4fdb2a3ab38802f650225b - 8e6b3d25d3590ed13c3d22e3f1253d385fb02b1feee7770b0f5eb66df2558d5f - 3fa6a247e297e96b8f8263648f5f469c8e5313fb929c801e61a16ebe10286010 - 2c2e9e1a759b7b1f4b2586f3e916970479a0d836c5465c1345314d3dacbe5ee1 - 074d3a15e4bcf37051d9b1ad76ffbf5bc2826c2311e53caa05d22a7d0315f096 - 51be069f7903a00b3a1b38a632b00b2e26d3946d151c6a7413cdd7a12593ee70 - 6307d8dc0d822da33b7e335bc674d287f944fcfbb12af664ef889c9bf9e1175e - f4aa47736532b9a79c489e0130fb2f49456f189cdda60e480ff0cc8435537374 - e7619db6a06a6e2eabbbf861483003673f5998dd31c722a6c7d17c7e43d94acf - 311e726e12c51805db6837392abcd880b2c5ad035b04bfca7b16ba9b82212c7d - 6920b91da7c1e6eaca690756d9b0d403c67ab0f258067f1ae537ad794bb2f2ac - f1132d35e83bc8de5d542f100ea092c33499c5577617dd56399448c6e0719751 - f322e16abf3e792ed0014b49354e697f3d4d78b19431d92cbc97aa12bb9f339f - d4be05c666b3215e8450f4f27e5a1a705eaea74c312bfa7d76d4ab39d957fb33 - 1badfe1cda019460c5011897430e14ad9e8101a5b25fd3de752f47e97452f8d3 - 2170946b4c905f613953b6a7ea03b96d67b9bee3651bdf1a33f63d2d8bce2867 - 2e90ef39a066557e991c78201353aeaa47094542581506a5ab258f8cc7757738 - 9f3d8fc5c19f91b5e7ec60e88bd8c6665b649ac696341229cc1b2cc2224c5da2 - 7f2c57a53f5824aad8198d9cdefd13753ce10f8cc14f1b764b19d247e6872fd1 - 99624aaf8a3def3cbb72ae940868870cfb29edc1354532df028dd61414a107ea - 83e5a86aad58f52306ada8c12e6817a870696cbec7f5d4ac6a8c5cf63a0494b5 - b51617e04794cdd195a1dbaf105175d0219b97fb15efcd172cb3084dff951a69 - 0b2a0490f8641f245b03a67e4cd75783a8a668483789a3386899d888806633d7 - 023ce6b77ee7b4c011be72d52eba18cc5f87fc702c9bbcad61e829c78b8faa6c - c6882cfa49bc6ce98f8975bcd88c5c3213c422f20294b4bf960c79911744e18a - 1e54b91c78ab7de3f2f5bc69b20a68d7c76f9b0ac029355c523db8348e9bd854 - 5bc86e1005eb48819993dc2eb96712a71528cfcd69b38c44f668b2ae1e74d985 - 2303619ef5f54d927d41db399f7273a8d42c85fac74705880b50aee227dab2f4 - a2c96d9d6a0cd66ba0c062796c085b0d351b203421f0c1b4ef61330faa31c5ce - f1e91688a35b7c5feb455d467c275049ec330af627d90ac89c7696d9ba06a402 - 69c347eb6e9114d0f95f0b7a0e3058282988cb2c2cf33ac135d3b108670b8ca0 - 90e8a770cc1b522fcfd3a777e6efb2e658743a9e65f8dcf218828556626d87f4 - 00000007 - 8f421eba67cfd61a355895a87fae815f4531f5ad25dd1832a672321836cbf772 - 77099b27748d0dcbd08bbd4dd5bc67ff64d630c41bebbd7bf1072910745fcb42 - 867b9b5e07a6614df38dda0a0f4c89b393b27f42e0a850852a75e9f178e0ee70 - f490bdb5266af9db46a2ec1e0fcc6ccb609808cf460048df6a5e8c8fa864ecd8 - c87266261ad5e79c874731e2c00a9efc9649895f30ff4a46cc860ebdbeba90fd - c47cdd5e8bb67584f2758b25b032e1462caca6e1f026ecd855856765ebe87f04 - 4e749f257bb5defbfb826cbfc5de07baffa680e520ff8663b523f151bfb772c2 - a6297ab5a9977fb15367eb960050d4c23e42bfc89ac812c1e6cd9ec37668e37c - 1a594e0ce90de5cab6341b1e77ea447521645632912a0682fc60de7f7831d0ae - 72604756a4416573c0cf6a52e0868b857b76b1faa5bb7e3607a339dd32f33263 - 4b210e0e31da922ac6870ace1a068f3418588071996ff816b95a1a478488f82f - b54e27fd3f7037360b20e1b3e8674325253ffff578dbf8108927a966cf4163b0 - 40aa99d98df801f0e241c1607d9e8484c9755f6bbe299a6efe96ec0836e9d53c - 213db6d352863854781c78c4cac3083210f979d3f7884aca69fa83429c1542a5 - 51b8e95ffad4f89b506bd31ba613fe66a375434114dfbdf11741a8d86a239ded - """); - } - } - - // LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test06 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({" h20_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000001 - 00000008 - 00000003 - fe732f6abc16f3b1c0d1b78d9e72fbe118904abe9b33f2e03d0728ff4cf15b3c - ebea5149fe955d36f911e528d2aaff42"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000000 - 00000000 - 00000003 - 4da59d6dc70132d671114d7e3fafb184a898a603a60119dcb55148775618754f - e4d35a9594db68ab5003f967e968b97101307219d000d16dbc58bcc2285ddb23 - dd983189c34e7defa68a7682e26c50668bb20c6d1340fbb127d1d5b805454a66 - d2a7f43d2a579568bea4187ae180cd1038d80655454c5dcb9700821d55db70f3 - aea2d5f8e1b1b99cfaa86b253e13a72af3389d33bd51329171d666c260b71a66 - 7f1f7e4256906c0247ac361fd2cb11ab9f3d8d042bab28fd5df69f14a54f88f3 - 4339c81c02a0a9256292566ed753d2f4312d4103bf25f7b310a86f96301143f2 - 47c2291674797bd1088920eb5bdc049b8f9809c3c6d96ebfe49084d1021aadef - ec3ece50b4b42e4af022038c6b5363c2dc24522a2e641e352363d9149d68cac3 - 5bc3d973071e6b7aed2f4f96ca91aa22e162ab985baec0e56df59d3e8b37fe89 - 59c00aeab5f3713093105cf7db782fa45ea8ee2ec8feb56c529e6b42f18043f9 - 79d8c4c9d56a4255ec9747d31cc62a7bf70cd8777ffb75ee43dbb2c394e36525 - 71ce27770f6ea480e89f05ba3cdc633cc3ed269eb2ca0131268fc0579d738334 - 504b477e8fc2264c421e2e551b1a93713281858ba2cb588a2adcce4d11c2700e - 31d7ce6936b267ebe96b4f9bbc4763cccb4f245d371177c258c6d23c30bc5dca - 0f6d8fd8194b683f2ac4e0f3ddb7ba1cee1c47e5eec239f5a6b661aaafd2960a - 5d1b3305e53d9bbf8f6413368b7656723bcd47e7ab18b41d7e29b511767ba267 - e662ee59a004264ec2f88b8ab6fc778315ebc2a08144503455b8b2c1bb410eec - b767ee1eb779f9f2bca35184fa4ff7d8d36a41a9ed3a76fec7fd9a68f8bd35ec - 2dd1aa14e7ed9c41db03de868b266f8cfac7fcc887c78e1aa3e085cf0883eddb - 74d483dd177f9168ab14134a5e2272bca7e6e31185c34225e05de4545a99a4d2 - 949a75f970b862aa3b8c9218ac34ad1e3b70a64be25005fd248463606275b9d7 - 8d96725b39d8b9ba08acb91c3103c7e31f7970f937e176a34f4f4bc601dd8f5f - f83caff6c72b2e7bfeefd49c93cbc270cdd4d442be431b8e9b68e011975708a5 - 60095a8b784850a3c5bb3bdf2778a8aaca9064b6f1d424f4b41047efc7088639 - 73df9b861320e66779b25d134bd4528920b64c79c9eed64d5a01e39f8c2e1a62 - ad2e6e68bc5de644f5f28b09a9479abe5f96bc6d3e0d77763e3cf61feb31f152 - 98864c632b450d37a04e6aa4a2fc67406acda826ae98b7c52cc82da5da333ebf - 8b1c771dd994f6c650bf24cea6f25963fcf11a1aab7574b888dc89f92659fcb8 - 1aadd497eb6676243eb9f65e66ef97ab8da3fd9678c8166d1b2aeb724211f4c8 - 4e72749176f5d63798fbd16b0006dc8d92db7ee411a8ac90eead5a08f89a89bf - 295296b8d1d27e97d472cff51787b67a3d6d2a29b66e672647f395e21c9c83d6 - dbdda3d3608968288224494a815103549960155b1594d36580ca1db90c54b783 - f9e732fc2b14d58726a17bf5869a296985058318adccf6e56672e8dff8beddbc - dbb4bf30d2c59bcb8eedc0e713cd39ad9bb748e5abe75e05179a856c686d1c6c - 764f8422372d6f2dbe76f277a21c75c7f778a4056a1ff3bb9f0022d931612411 - 819c5a8a7b2e360c0ccaaa910e2af0d7ec87e9ba4cb90e85a18ebb8fafb4eec3 - 40ee8cfa4b9d9a92fbe07aafd07c58e06baeeb5c587279c2b2c344db5e43d5ae - 32547dc5f45bc855a9dfd6c8d3ff174d0fb999f4819e3b09ca53cb328689486b - e715f148dcbeea8f46ad00db30bfb087b8ad53ad6e1cb579ed51007289dc5b0f - 691188592e1beb23243ea4ab09771552fd03bafc9619dbba025764a5290a938b - 3c61ceb22c480a0985cc89a790e189b9e0022f772b30daaa218978208ff94c4d - 2f357f74fb93c961de0c97e95efa3a11dfe80caa3fd04051a717bdff5f5cd9ba - 36170cbb14defceac5ce20479b564e0d6a3b978a16cc48ede540212af06de08d - 300290cdeda5a9eb4c35f6b38cdd04a959370a929bb7c3372cd2a3130e1ae19f - adb54c2389079bd8c7f0249a2b53bf23687cec51b529411fea705fee52504ccb - fa64f7185c6f3601967d30a644a5fb4051517c8560b64009f6de5993c85516d9 - 2c81e47c076a679ce96435939352d67d11fd5bbc94e6e90881d70311cba88a55 - 83a7ec14f853f128da2377d14f95b947d00219638e712573223ff1aa2762d1f8 - f93d421e70dfd5ff040eb8f2f435d487e2d91d6d9cc0fe2d9066a01eef8a6c92 - d3a437a8ef5d8c8c5ea5be932d2f71b4d04ab3dacff9508e7dbbba3a01ea63ed - 4b7eb611e35e7d70f0e4ba82ab8a86719bb0e28fc9b3ad28bfa91f227a34b005 - 418ae4439814122d5e79336d63e1554e1137642a98e67654ee73031166c34726 - c4e78848a55ae01b1398338217771198db5973527a82ada98aefa954edf09f55 - 9f4896aa3b6117592599fd4301dd304d73ce8859509782bf60e8398ff311bcbe - c26cf13b8a6448f2aebd0ca29d06fca7ea09f559aff3a315b1ee70bff8038b06 - c381c9630896666c83d14b7bc3b07eb153efddc2b09568c0ea3260c26106d1d9 - 002ec640f4ed596991b51c20e9d4bb78de99588a33d0a64b20f8ffb2c18b250f - d5f7ed0a4a5e2a9ff94f62b8e84cb4e2ee898b85c11db384a26e9bddbd300128 - 2d886b7485166c7fc982be8c417f8fcd1a7fd98e529f2fe88a46f36d5091af16 - feb75ace51927a339c79cf79fb222b223e845126c73e4e8103fdd04786de373c - 9586d13460949c080ec557345dbb88ff1ca59701c889dfbb6492bb9086f05ccb - 330a2bff05ebba97a5358702a8d2aee46bf1d7fae1b934405d652a05e532b65d - d7ef2e6599af8683bfe4644ae2fbc77424f31bc422ab791de730e4718d080603 - 8dbb78b84c5df001047502acc3efe437cd46b8a0a7b4198d5598dbc343db47ad - 9c379d5147a5d4bb3c8b962a7368a7405a580f7daf312327141cb5681e198795 - 3ea2d2d95c7b9ecd6899428a8966203a9ce586357c631f7af27aaef3ea3a47bb - b8a81a7b83bde6f223b270576427c02f0fbb8e9232b2d70f9a0af16ec6544eaf - 00000008 - ff48f2d9fc8998f7cb6685a1d980003da426db35481323c56195cd5142148269 - 5b064c6f98dc3289b8244a5a7cfedf3c1c9a96ae48c79d6c9b59e713e91d90bb - a0212398645f8c55bbd03832e57397200b8127d6f38570e15297489040fbe0de - a21d372dfbe5098b1491d8efcfd2389e506039bd49fc976ae940b5e6bf3c394b - 189c63af6e799ed580f999ff02a16a5915f9b2ebee58ecde057345f4557e87b7 - 8828c700ec978f41e9b9ea78cf8dc961b0ac33c54d0f91a1d05b4910e981a050 - a2c319c8cf5470b427ab09159fb17e5393176683e6e0b3fcb11104e357d75d66 - 6b13356454c5bd0e70c18ccaa775ca568ae50d924c2ba2d74babff2fba05ed25 - 4d9e8dff7d8770738f2e666f8db461fbf0ba307cd638950692c65254b03d739f - 72ded6f48b6a9a37de6cb2f3c4498626586ceac37a2644e5fdf9b7794fa4b472 - 37bc4d45381e5bcf6852d15fd572e0062c8b1fc63a31312737f2347ea40b2117 - 03f23f5811b7ddbca4a3f19fccaf4860773bcfb872000845166c61243b05b033 - 4ce5faaac3ab1a7e950403b952e0b0ef4396e5f12abd08bb1354c28afb9bdbc3 - edb94b15aad3a85ba3444caa1019262ab6e04f343284bb5a21320440a95edb16 - d3317c875cf0187f0ed79b676ca45203c2d4a83233229f0861c58164b2b80b30 - 0c13ce8899b0ba1e470ead23836fefb921ab6a472beb63b655a1238a5b8f039b - f1c2916a44168e288d4c4aff2ec82c8189a7f7b70837e0a5756db0d38057c9d4 - 5927418b9fc50048b6ae0f16a9b3e3399d9b08b67c41c84bbc5f8bb9b23f08ca - cd742fa9e1225dc8e6cc32b86d6f57a3ac4b6d733a0655cfcc036c4b4c004a61 - 1efd58035b06ba03b4a701a68f5945cd90bd4d69d702fb43f0ff10a5879ab709 - """); - } - } - - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4); - // LMSigParameters.lms_sha256_m32_h10, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test07 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({"h15_w4_h10_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000002 - 00000007 - 00000003 - c56e39882736881759e92ef7a37a1953322e3e9742a70e3f401e9bd35c973ace - e06d7f77bd11b4a6082bbf7a5429dd4b"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000001 - 00000000 - 00000003 - c94b744512be0c92aa45ab245dcdb53513877236830106ce43f09a2a6fb083b4 - 53d15c7290b92cc2864d0780ae105d535de9f9651db43ea47f91a1334bc215e1 - eada1413a30a5917c0da8a5ae8256a0d40e98f33d6bca2d93579a44707a4cf0f - 6cab795d4e332685898ff004836490805f3b7eeb675c89b46f6d0d76467ffceb - 18f41176ce105214f4d57d1058aa1468cd1c2a894b62502b22ecf0b4f73f110b - 4b9726934786d58ad59b57ef1fea528421968ef136fd2ca7131c83ca9f03ece5 - a8c81765c769d79e8fa4093235c857d3e2864e2614be9535de95a09f60f2c033 - fe0125946b47bf09ecbc92123d486411c3c715f313b178818e00a81f02c8b7cf - 6c9f6babe65218f5caa8b0c38785fcc9dfe8c35b59077db5084c49f99fa7fccf - 5d3dca81c273f72a8f3e8777ffed035edcb9696f9a062a7befa59741abdd8952 - 1dc585d1f8b37141c6d07974d768ec338ba71f98581fddc7db7f6b11602f2bce - a4168f7959b621d7e298936a981e041092ebc13e944ee2150b91dee55a1f6724 - 66fc58e24d8d1844237dbf4ae6d5623001afffe971174541fdb7bdf8695d8afd - cc56ce99cd603ad02b700983e6b97b76b9d95715a57baaa5804dee2a02b88894 - 0260b58e99c05f05bb5b2280e242a40d1f443f3a37ad051dfcf3e1888107c067 - a67379ba8716e167b862fcde469ab62a4d84162f68d74a6631ab0a7c41ba7519 - 096b72110d7a9561eb8bed3d7a87b383a5085c99c54149b56d5d40c747ca28de - ffc08f627609600d2e8f40bd7104bc99a2ec73952b857eda20475530c1fb969a - c79c062c6a687bd2e008b8574260b822de26c9e7cbf32338348db43e4130026e - c2dcd20b79e4b1766762037af058cdd89a9bb2ee4148d09653f0366c7e0b018a - 2b72a195a6b1c422e5adc23fbca25968f7bb97e51e01a83b7d1e83b22a118b76 - ecc8acac709b3e5de5cfba07d8e81b2dcac4a476359b1541adb24c2e9fd68a38 - 32f2ae30b1db83470cb50a9f36777fb02b98f63818a078449de16c3108c0b724 - ce49b7f5f3beeee04ffdad3cd5cdd2e7955008d6e3123a42a46574a8237f2d54 - d54b3f8a6e01185287b167237ef736cef9881ed8478466124d72ac30a3caeb2a - 18fd68be71625289e05e076b7c290876dff1a95fab3503533be3ef0c5ad356c9 - df59630f3eb5fb6be37c61171243c0cf72ba2e2b83c4d84ef6ff9cac6b9790cf - 09eba6e0dc76664cf957c91b09b67f0e5c0f933d503c7a6a6be06f78019eaad0 - 302e68f499e87d84627a7443bf1e2a8a2673247b1dc6aff3ac940d5f0e3a3ad7 - c888cb961d8adc05a85cf2c9af4ac80eb0109b7ae822933ddbfbbbb36e05bf24 - c3538c645e22946197d21091192cc2ece6f866fa2c37ce1f4a9be52428d23913 - 3952f89286f88a7183ad17416360e0143d266f730cfdedd42437eb4baf9c3e7a - 1fe7a3e084c2ef4f50e2730ab9fe44c90b1d0167fbd1b6bde2f1457e2a7521be - 7bbd3bf2fc64dd111c185062afe4b90830747c68ad4ba890d691bd66d95fde6b - ff7b1b1c4d13c69d4beb23ba90309fa17633ac5c6d3c0571530ee61e48eb4e65 - b2482bca9bb230d3fbb6a6e83145a8c918059befc05143a5145ffd4fffb38114 - e4026f262038e7d24d5f9dab453899daea13fb4bb07f7c7fa875ff4b8c1600bf - d05be8a945f323243987db289a19bb29250a6a2d8d53c26e4cd5319324676f38 - a2adc2fbbedb324a5dd7ef804dfaaba33b4d7fbe17f134e1883400072d5f30ab - 86bbfdfdfacabc41b80749abb2271f903c71b383b5779aabb317db34ac01424c - 174cacff3dee16cf50e7ecb99d50afead31ab13363f49050463c25aea4d65235 - 0797d491ebace80bfd2074095f1ab5dceea9866a62c1e7e3c7683c3d7bb50272 - 741afac834a1e48ffe3e3dac6c168a33f40febfe4ede57637653c7731b4f5d81 - ac275de086acfb63133ae49b40cecf3e8a0333764957ecb1fbad30d80e0486d6 - 5a9727a590494ef7aae57f40bb0d75b05fc8a99d98b28f2294585234894c3f58 - a1064bb824afa73938feb5b96b279dfd3f9145ccd4a8339d2be01a62ea25efbe - b4bd970ba21c53d31fe66efba0450e8c5edf46c7116701b52954a11baf31727f - 7f845d9050a6a29759850af2d55d47be9646dfd6321af2677806335ecd6812e4 - a2ee84aff5aaea12478c36b822335db52a6cc0bac5b59c79f5d947fc526288d6 - 585abd23a071c6a98bcc6909cc3e45b15ee4244f19fb5e91b9c408870a37741f - bff097374f1da1ac712561ed5f908926f9c05748291de93690cc863d998640f0 - 963a92ec0b5246745477c83c600e52fd937d4a190d621a114c185a0a84b5ff3e - 782113864ccce2b9acf86100bf188d9a00de08bfc9b1fdfffcc1f2ba68420bbd - d6df840fb782a21cda9f051610663e8eb0d1e3e976886fbd98134101fabe1ba9 - 33b2546f1a468697d453d94716b157dc8dbab7052424b095d3dd7a19ed709da2 - 60d7ea9df24170f6feea4712c56f82158d1870b1380e7dc4313a4d419ece9ea1 - dfd7b3df4ede21f29e050156d5089bc0cff7e15c7983476e890b41f29a2bb373 - 26dd2da928dca53655602886fd1c4a9c8153cbe50652741ba398857e37ad2231 - 973c24653ab47e413ca95097a984e56f3fe7fcb3e8a7621d8cd710dcbf8faf0e - 2be05dd70a0e746a010fbabf8dc45963673f8e009cf146688852ff02eb1c00b0 - 5c4adc1ebe2dfcd31a15f37a4ee935bad87bda3e27df9724a7b1564b3f251602 - 50e722a50869d1cd39784b362bbee70c3a917f18bf92b77a5322e8b5c1a7d101 - 77fb7a50f3d1b10669d570f7cfd4d5ca1401a4da432d4f68137986c456507611 - a050b0ae0b7b8ea295bf78ba9b8b3acceb14aafc82385928ee544ee068171a2a - 34a7e2e5b37a19a70c0251910c0966cc6b8a689cd6fc8a00f73959388624f9af - ee57d316054eb23ff1aa63879e13519f416a8449942da592e727073bdccbfc72 - 52baf02a65ec66bb9504199a147a3616ec20e7c57ab6a4f4c7def3eee13dfe48 - 06372b85bf3d32cb6b3407a59af02c5549f29a76c73f43566b868e5f1092bfc9 - 00000007 - a22f82a1ca76d4b8fce179e98c2b8f53fc36a1be0c8ecc5ac22a6c65b02101e1 - 0da5ee071fa5a641198ad237ddc7b03f50612080ff3867ce11df78150d06c9be - 35bd7d0befbf473bae9f2f8e077e9358e8bf2b4ca45c7a6af889f56564a22470 - 43b4b86db63819c4f9d024e3e09b96e731e315d10c3db8312e9bd33d477c318b - 3a5f886dc3d8595363de2e2d4053aef8b722f7fe4e092c1c9de6942c6597babb - 91ba0b88467321a8762daed53a5e31bd91a76085d559718fa3368aca9c5defbb - 6402193da3e293fd7d5df6c0d0b36e4696dbb0e6683dab1e29740b2625faf976 - a86910e194b46ca4857c3a1fa37b2a932ee300fd69ff2987fdb6e8ec7fb0a57e - f50448510f72818c87f0a51be0796e20d9fabb66244ec5e99d6fa786b7524992 - bed245b61066371a4d0b3b91b64ec0e4e4912b5064f4e73a684de396f73b9531 - 397506e10da845520a724a419003445e4b3a02ecd83a5fbfa392725054acc609 - b9d66d83ca4981ab5a826ac0c675706a0db4ea4f4ad55b3c3a9cad8ebdabcbb0 - c1526eeb2f678c0782ff98858241abd90104f0a89767cbfbc8584062ec2f7fd3 - ac911a09b2188c85a46b71ed13f71c740cb8f78513476f33b7157b49422e2710 - e4ea2efd66b147f1e94f512d5bf7ec40fbf020094c03626fc71053c6984d8b15 - 00000006 - 00000003 - 6002a704915e03814410e7c4a86744b6269cc17650b33496e73414170f642ad0 - a5a308f58beacc5b39af6b988b906c8f - 00000000 - 00000003 - 4958d1fa4dce4ace05d93d530b008131b8c01191cb9c6248842e503676f89c91 - 12431e2d9276492e1dd36fbdcbdced7dac7a4d86fc64cd8a1f6761d6072eb0fd - a335e5a374b7139a62537af2d20747b199f32b97aa98b7ed722e651b4ea2e8b1 - 6741525a4adf245446407ef3a0f8da6a374245bc5796fffad397d33ac887ef8a - f1eef9ef53f9bf5ad79d0ca617c69bf8d5687551779762530a71c15a1a833cce - ba629d85f03eb30b065fcf401282632e97cb505e41993ea121aabb93c5f5188a - ae98a85213bfa98bdbe14d2b53fdbc4c00b1826ff9b34ce84293eee25a440622 - 677e290239095d199a3776d2208ff1dbe2382657e83d1e29f8da4cad0dc2fefe - 2d17350229b945718f71d17c646c881229a4fa47e2dcf7485e9096b47c24ee1c - 4f051855cd19d787be09ea221bf827f6c2e648435f4d66d2028a011e8536dfc2 - 66fe9bc6c4d342b95a692567291e6e2ddff81179eeec69fc135983fb550569c0 - 4d90c040c2a3ecf2b81a55f5368ac0a7a3d9c2bfdb8aa13568c3147f56b0a504 - 84c4a00b2b1c795e784498d4bd1951eb5733cab4a7b6103a4823f2a94f890c62 - dc83c57ac233902bda5440eaea0aa553e0528458b39e8b58ef98e157c95a723f - 7c074b5e3c4b2d2c15ded5582d2774c71173be7f7ecbdc659d8d5a132e39f64f - 4ae6a81fd550d8dcf7a1e695bc985d059892567fc502399123ee3f1131d113f2 - bdcbe027fbf6ef0738f78762982ab379547eee6b4276635d1961b7cfbf1bf6f2 - e9c9512fb4699468d882b382bfe6c479878824a52fd5bc0ffbc5cd857d1b96c4 - 18ef6c59e799b93f14bfe5b769ee28aeee86ff5caae4e7cf19491a00f084b818 - dd61b0f97675c85077bee6ce5a44d9a47603491ba1d5e690f311037d7319bcd5 - 74542337ed91eb7d65a01987d32f17b08d62c9b2cd326fff38e3a6e280c31255 - 950b7911c262a17193bc9fbe9c43da2a3b69e61a5f09d67f667f64a12e91ab8b - baf00cd7647b9fa8ab76057e5c2dbcb347c26ba18b03c25af8f1bfe18491f962 - b537cf3b24078dd8f45a2b3f707657592872d4c3c050bbb69dddc885399e068c - c4d13709c8533f650e48780663b28218bc4e81ac3265b505f4d4ed6c8edf10cc - c9db22b1f92029727cde22f4cade608fcc64372da7367886290828c478ab588b - 4473c2e9bfb975368fe6b53b71953eedc62980b60f3da18acbbd292b723d673b - 217d17366586344be60802ae9b4bd945c27e196317f9b8aa91299863a6dd336c - 9a321b7445934edcfaf6dc7f107a06ec6aacf3c4e7e04d83a938741912a9a34d - 6d6cc6598ad635c8299b4c5adb149f935f39a1cae255a8116e544306330ce49e - 6a46452ce0420c655ecaf659b8723780c9d2a7946f9b7781ca0ae983dc68c0cc - afbaad6792d3b31b728668d91de0a7927780c78406521bcd483d3614d20a4265 - 62c6435a924b998e3824351706be646e2d530a2389f6c09a2d8c443611e7c092 - 330b56ef2672ad807f1ea8e249b0a15a57881048f91b00c4fb374201f8b92259 - 739e521e10604eb307d3638090c0a4e4eefcda271a5387cebe0fd48d9a146232 - 37b9380e40ef1108f00a980c4cf9abc88b3edbc7826c48508e02069ab34578f9 - db6bc3196dc806e0b1659577ff34d138e53cf784dfd03e3d8289b0d8fa9ab004 - dc35ead8fc1433b8c2b1265241f17d9629829c658513051ad7feea28e1d72a34 - 05a2571a4af94b7ec6ab2ac4cbc810077aeed2237831eb42e303511a3b79475a - 9f9284f00b3baaed51ee50f3ec7af02effd2dcaf7abcb9e4bdd639c28293c8f0 - 63d35b3f3934df46eb853a2b8f9e1e8e39abd9f22a7992325b9965ccc14e7910 - 829b503007fe5a521c03ffb48f154d908a7f145988de3d35da8710e8b42cf0b3 - c9197a9d250dcb5ab5ac724e0eddca2f1e92baa61c2f2862087794fb6aadd837 - 229c58b673f4a682b6f16178a8bffc71e696a29f9116cb896dfd05780afce77d - cba573170724b067964901112baa343346d2c82e705b842e8be9e5b56577015b - f86f9b27be99ae333bff689d93c7e4ba77be967cf8e6328284c76a2e1a3920a5 - 515bdc7e5b65e6041aca2268ce13c17195274cb0461611421521e79a2d53af61 - 1728b35b71db1b6424b6382aaceee899b495fbef4184911ed1877a3b17be2276 - 571a2347d613ceee0c9de7e0d2f0bb5e18a63ef05f424b1ed1353409f926f84b - 4ebafa712f5ce1d36de03c6c90559a60f80e2b4915fa57d08222f6735a6201c9 - 4931dc8a50f88b537031855c3824f617334f9ca13a9603ac1038d2cde3dab425 - e5a3ff1a7fb7a7c25b315187f202eb5311d078cb2e2ffcb1a509cedee7c372b9 - c06c6cee6b66b6bae7bcb158e4a74769805a88f5c9cb7c581e12e1d05ece3865 - 4b5261501fe414ba395f446a846bf736e1eba29fb30fe80ee174677eaab90e1d - eee16dec7a31c23865a38ee8c052a757abb91b104d1b5e0150e535b1c4669e7c - c6b23f57a8dfed44b3f853049596b7f149e5d21be66ae72df95d1e969b054cc8 - 49f2bc06a1d6bc5565bde1093648ad2581d691cad46237bb920deeb5facabe8e - 52e1e02d07903a17332198526a9214b6d4d4bac9f13994f6ae01ee74e673aefa - 5aa33ec67c4e0fec44bbd163fc6c317c0db4ce0de479115cd2a9474c7b222a81 - 23cb5c784e3579ee3805c8a606d2c5d113fcd12bd83d03a9d72c8f72d6c577d9 - c891542cd3f3e59abaafdd2b0e9195f57e9c826039647506f0fdda125a1403f3 - f007d6db2555125c33de5b3a90ac9cd8485e48bf1db995708b697b5b47741108 - 1b83dc7bdfdd8aa5a3506cf5a828c0e9803320af6a8b8949edf8fcbe65226beb - aa2930c5502dc34b4ea9588ecf3e69edf41ec734be808b3e39c85a54a7eb5ce4 - 33994c40209f02eef0e43adb560bdb26a969216b521812c6364bb336d004c56f - 91bc928887ae8deae2ea6bde44ddd39135222698c491759ff20dfb6d7686c284 - 2ffd232c9544e3c39d37e9ce8bac185d58802050284a5fe653aa64e16c9b1777 - d011e2ab479a85d33e041423e6a50e5dae059eca94b6c99015e4b65047ae8c6d - 00000006 - d67b98d51d77fd23841bef1a34fd81e4c561c4f085b02c791553ed46c7644b51 - b6b97076d18c3ff64891f63784cd38c9fd1580656d4ed635023f4fca45bd49ad - 7958c3201c2233d8e1444a58b1f03221603f1c3b59b72eeac085fdccb79e07b8 - 37451bf427cb58ac9234253ac0c56906b0540fe5bdf35b47b73f04f56b22c8b2 - 1ff441f59983c2763a021e6d8f0ee5b73a16ef63d89168563b086698507fa56c - ddd5d64bb968b0763191da92171580f9c404720254cad5c7d6900a4997fb0570 - bb9fcd4d249803c3ba2b3e5758cee761ba4c2df21f20ee2d36a547a0cfb216fc - efcf58231cb7d6112ac2583fc1e52f3062c1cb8b14df921eb4b702eb703082db - 7ffe104cd0be40b96a04048def98caffea64e25ecfdd3566d3775200c5eb9182 - e9a45d41023db850048e05f200a4e7ed2e0b48c532e10c1628503d5b7f394cde - """); - } - } - - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4); - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test08 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({"h15_w4_h15_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000002 - 00000007 - 00000003 - 31b6c6a3b78feaefaf459a33e2acfa66a208240984abbe18996896c0eda7b999 - 9d9786e59e41179854928ed5c5726bfb"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000001 - 00000000 - 00000003 - a3e30c30ffb7b27a99e1e53b030fbbe5f901b7fc38b059190b9ccb9612503d10 - d0b0266063d5e234c985b0278428e147ca9686e3540e6d51964e27d0334c0043 - 3564dc02fe8b1f911667561445bc9e61773d4ea4fb7b5c8e637ce482cfbb69e1 - 15e118eb5dd28ad2db03ad6618af5a0a919aefafb46d8ae5ca011274032445c9 - 7a49502e49064fb41fe28aa76c103f0d98edac1d71f51010d7e89d04028394a6 - 87c98d1ba0b07470add461bdbc5dc553cb7225bc12d6925319253f50e8b8b1ad - 1d5ea6304ce5e69150b0b2953e38ba7bf75b5900e1b4e84e81d1ba177c7dad91 - 956511d74a5b79c22aba2b821ec31021244fc4ceed9b1d992382e7f2e188eb68 - 841b09301ead899c0857194939576e830cab8fede0f14eace0755d56d144eebf - 1eaf5f228f3c3a915de564ffd8c50b7a0e95834eba10737082d38f1c459f2a5b - 6479b129f77f57306bc9888a469ea7a7f69be2f4784c472d90b3a84c8a10789e - 5984c01ca390681ef94b483be22c2559222a3c8505055fdfcf3c1d5dbc22f342 - 8d07178cb2736d930313812c30cb9fed3c083e3319208ed600d449df46106898 - 1f7b3201a9f1760f388aff82eeea616ff89301ed98de1fc9d3a820c7b3e8d5e7 - e7a97f3eb819f4f5a08ef7e435d9df748d631539205204f269000d423bf195f8 - 02091fc8f25e186da3ac3b63f7fcdf832c9a8b849a3efc207dbc39b7d6e67184 - 4efa7ea995aba735be8d69ea2a7fa954f23d9cd548aae96068e4cca1e53f5fca - 2940cf78a43865ff1ef52ac1ed6c347a38b217537ebb6052a094ab8a7d5d67ca - 0ea8e46f10be7f07e4f5859f6f940c308aa156268a2378e36b6f642cda1a0e31 - dc3eac909426d8e9ad55ee21971c60f58571877e3c9e41bfec8c50c5775fb8da - bc78c18abf1e9c3c9d6a1fdcbc42bb613e5019d95cbd12bbc820df6304240a7a - 0aae87df42881ab1e5df3906453ff32acc16a3bd5c01c4bfbe28240a05621899 - 104994f21e87431596a2c43a336be790cc095ab7fea51a5f957caf3f221dd875 - 59bad735356ed5364fd9f034ae53c1ae7b7a3672a5d7bc0974650923dca467c3 - 0f826ae5bfaacfc381469b93825cde82e5f631936bfed860a786d35f29ee326b - 18e215c6e01630e811683da0d8d7b9fc24131da9de35a36d5e541896b79bbbe0 - eb15ade43e39134013b0de86731d17e7ec7c7cc1cb46d925c211e23f427ddc10 - a0d25b18c397a83b3be64eadf9106d5ca75286f599059b2cb0c3cfc892ae5e88 - 6fb873326634a5231f555a4dabed9fd3370706c6e4af23e5736f5449883d446a - 593bbd6f36749f5a71a49175ba562855635511fe9005ab1fdbaa224f55b95a03 - cd08a215b8cb400a02896138900273216402241caff7398067b0f6c18edff0b3 - 3b5e1350ee6157b2d79065ca0beb45feaa67795a821d783d3c566a0a130cd310 - ddad078aaa83a319ee6ffba73799bbe3f14a406be25b3f989c316256ae0120ef - bf3593dcbfde8d1f1dce1fbb1cb1c6c8258623112a05b70389b1e801e17fb17e - f10544099ac788eb4cf045ed1fdb9e5e957d7fd930bd927f4c15c253b145f848 - dd1ac985fee170307f56d34dae9926d67d1f97fa014fa3ad57c10d76d27dfcc0 - 0a088a043021d5b053b6d69e912d3cb85b7c2cc029ecec40089333c7c9ec45b4 - f9c3ec3720df8fb592f5c71d7dc230f90439ec1ae12643a8f4a30dc96e798cba - 269bcd463116dd9657c89c569b519cd061816150e8c39ec3e798574610cd13da - 83b52042a890b37d10797ad80f74928a96b697bc810867a4e0e96e98585bf386 - d0df41627d76af70436258dd3ed1ae49554d8dc5a2c7e54d477af70e2a407747 - 227fdd0bc0b5a9019c4df9fe95dcd8ea6251ef1bac071771d364fd428c3db3cf - cb4eb26b7908ed96d30eceffbe634c0184e8cc2b807376d7d5fd9f4d9579f148 - 8f085df80f032c6c382a48dc80b07bdeca6085aa59f97abc666c1a73d4aeee34 - a35e3569ac357a84fa1a9fcd84af37b388dae14e03be6b5e088891060bd69e5f - 419fd7d2ae50eb97bfb24c7dbd602de5db1f05c84f1f47fc7c6d40c0fa4c95d0 - 464a18d0b6338ce123b46188492df786abd9075a535a38de4b42d8d8bd6691d8 - fa9dcd8af407d5f20a59cb959802735c2149c18a067367ab9e457e93e569ec1c - 42741ac055420fd531dda33faa9f179e272faa5b32c1e6d3029b55e21140f4f0 - 104a89760e5e038c07a770bc85726fc57159089cc3a2ca2b8a14e9f040b41e30 - 3e2c57f64dd7579eb094e8deb536a45bfc2840428617117a1b2ae8259764e860 - efc03fadfca03511a370256420fbda932a5ab58c98d0df2a9aabeaa7d886ccd1 - 59281e77e7a1c70094722ec788212885674e90a3134c2471c399bef65cece979 - 0ef61cf83201cc137a09115b0fa06ebed4de9104974f80fe00b54367ab267483 - 35e0f8fc02d52e4c556ab748a98aa161d4c9cb712c88155b0177699f5fc4d037 - 02560279c2be7db70603f03c0c2ccac7437597c79da01ef70d84ae5ab2e0ecc5 - b77e9f6a4c412569589d97bfda88efdffb626dafd24408eb79919cf48a619744 - fe4c42f3c49ec4c1f94ec8e79366f036aa1366ad559553d102efb9b3a913bb06 - feca31ab71949e4aff7fe00be4bfa36e7d6dedfd349c0bd0d8a895b7f8fc55eb - 09933f061f0c4a756caea8790d134c58cd1469ce78edd16be26e0208d449556f - b02f343493fafaf615585320902dc4c606d3ae2fd4df7619817b49d47a672121 - c18da014aa89309814f49d2259540aa4897cccade9eb94351950a21ef3aab45b - 90caa42e3e41f39e1da7b341cacca50a8978f1dab0a54becc79c9501c9ad7c06 - db29ca593441ea36ce2d48aa5ab2455efdd70e558ad9f208c2f26ce7c716ef96 - 44a12f904f4cecae04cb68a433db2d3aefc192009355e6f67f7b565c746c42d7 - ed6645ca837351fcc9534c66451e8e1fbc327999423aefe4f5f620c8e15000d3 - 2c621ba53d572da4d4871d36173e83b1550cfa40a3a8fd7248d351a703389122 - a4b070ee87b44ec6543adea6921c567be95a8034a06a00c3fc102b8d2fa4e6b8 - 00000007 - c792abc23c442a9822041aa5889816e9e127ab2323bdf2636cc672b47d055dac - 698074f11a96c53449a1ee30e1bc27fc8be61d85f4e5738725457d4cda5f7d62 - fc2e949005146d26590fd090a3c50e4141c63b8cfb14087affe86e9ad5207b4e - dedd578be3e0a969d10fcafd1ddb134093d026a9055615e07ec4419786a82aef - 0afd2ee68e706169d7688ecfa37c8533d9f7af2bbb02adf614c680db745af017 - 1676255f9e319f00501c43e4787e8349c9b04bf6bb3e7763fe6e40d6c21e6ec4 - d4611c5480aa2f8ef0f6ce3208748b966eb5d1c5945c54f8421ea3c2bf7602ce - c1dbfc1c8408f84cbc3a2b7932764baf9c45e60404f60736cdcb8bd3397398b9 - c0e64e4555efd2c94f04a87ae037fd685591599d5c0b1a7197b6886df17c5225 - 5ad8fec5950668c3dedefbe53ce5ede382633962be26da09260ee48b5d8ba67f - 900b54dda5630094a9fa85ae4217faf60801fd315f1f0dd58d30190fee4ef279 - 51fc2c5633cb46f70e9ee9678e27ac8482a2e48415b14e5d1d3bfa6a86d5b972 - 93f2d0a32d0c567002b03df6cc7a4c36129ecd04f9cdbc53cee787a344f305a7 - b1e61609f7df2745c75a88e07f071d1e93c868409b67afb114cdd539562046fb - 7d85f590ebe6969684eeaf7b42547139b50d64400bfe76c687658bf7195c9791 - 00000007 - 00000003 - 052aa96293117df09356c119dd4b9edfe3d7c53d62d9855912682d1c502d64f2 - 3b298883ffe67153ae1a23d0c6ca41bb - 00000000 - 00000003 - 9058ddc450f6e1e7b9ddf5fc65edb6c55d60cfaa3b3b1e62fd53d7286903b9c0 - 63656485ed67b07407c84e1c4a34841d6e88aa0d6a22b262da4265063f3a84c6 - fabdc96e1c523d68043290d7d689e7bbd572880f0fb2a1fc2d247c622faad758 - ccf2f8751b983a86c29d721002f14050150227e594ab05b2f6ef605140511290 - dc213ca6db06bed09f33baaad9a0eb840c7b510bab2a31f7bc039f944b5b40a8 - 1f047eb423d306a8a190dc1023c6433f39edfe68f2a11357e70356703d15a46d - 6df90861e10f84cbffb6efd1b3917e38f6baa2602f4a3d1b4bcf6ff6fc61e22b - edccb0831a655474d5d701fce378142a307819d5a1e8156d655276f1f0b7d9f6 - a250c938935f86a2f12410cd5756526d70bfb17e0f90fb440e3e8c760b693ce0 - 5c5cf7af31049ea0144f6ccfa9a2ca892df28504391c3f1e7fa053fdd29c9767 - 94ee174f23267131aa62d5346150d9f5ed14867d86b55643ba6ff94b8065a85b - a33499a09fc620e81a57a5d059e37458801464aa461f07ecb15cbd0239272919 - aaecec880c2f5bcc5c73af198324d06d9ec48d8a75a0d7aae6fa704bee98eb62 - 77204af01e13cd80bb8ca5f243c67b02d2eb535041b0b41713c155fc5d5d2ea3 - 61f27770cf31264a034989896edab335be1ec9b2c5df0106093162af112d1d7a - 9913a2edcb1c2fdf732b25c003ebd9df617cc5fc47d8413c2b3b34dd542a217c - 32e4aa7a283809f8011dcf59b639e4ca7baeb9b408a100188bd719446c77964d - 4865d6b138e9ef1c76d13145218c7de1827ef3599f8c9883ffc2d2412e48ef13 - 4ef821e1d426748803ddcf325df9b49cd61257f2b2d3fe2bdc960b5140f5ddb6 - 4696063fcaa699de790947a4ddbc8fdabd46f45d2640a07b434e304d00fa8310 - 8667fddc1e04a671548ba468ab83dcc897ffc4b776d1694618ab131118cb7830 - ec1cf9e432d8f04cf48d8485d58c51b18d5a0bd795588bbcdf65a583f7615e32 - 4d4a76cd5bfbfec3a0c37c97f9b5b1c5d8795e3149fb11096ab600cd9f77ab37 - 0fd5970b641fefcf83870fea3d7deb9a4b0d4cc53a9d28330c07802d52635ad4 - 3cb76a04b6fc09a7129da5a3d617935d144ca865c4a958d4592dd9dff080a696 - b2c7301fd3d2974df382562eaab239df41289c7a2b9b55264a879b322d693acb - 52c38d9a31559fae7592bc29b1a83e35caef47d793fdab943ff2e3f98a898c80 - 73ef087f8d4419f1aebd705d2e0ae8fd137f7a46912c6a0ab7cf33f76d523cf4 - d27e5c2a22783974134846d923d8d966041d88f113451b439db3af3c90747739 - aba2de8ee7e1a7f1f84c6826cd405404c838eb387cba680b5c8f62ce8376c23d - d7bf26386855df8f8d554445987bbee37597171f7849590db96281fba0cd9055 - 92980b85e0f29f57cc6536e2172695607dee4f53fab7b123a34a97e12182e13c - 623f3ac68807718ec5d7806072dcbbf087e6f1e5b834cbbf7d8e85c3021213ae - 4100af501e8f77f57fd68c7b339fd649357b396a45eb2826fe06373928cbfe51 - f1de9fae833492e42f82d01ea9da9f4074ff22f5b59760d776241c73ebb0f05d - 6856dc9e07a2af219e38998afa04ac953dbeb0672b13277bca76ab02566d3f42 - 2c6763dac87898373b69a1fddd92ef198f52388644be117fd8192b592325039f - aac41b147a73162a5e297f82e09604eab0e06866450f8cebdffa2ff475e83daf - e5eb9296626a895518872a97608ffe04f454a9e0098add3bf581f53490a1e2da - 324ee87fd47b7ed7551c0f222f475a57fd041b6e626979434d119525da68fbbc - 1e23d8affef88ad8542bd99f981c29435a3a7f3b40ad86426c6bf0a0948a15f7 - d8dcf09f4d083cc3c3ac77191afea39e3852f2b679bf2b3028a551e91bb41272 - bf59c1bd443dd6c71ead77700dfcdc2a9c686859b12ecfc1f75cddef50ed5eec - fff75007bb26c09b836c32950104dd417ac60622bc57df8e55815204a75d9c79 - c13cb605dbc321cfbacdcdebb24ed3fbcde6d7d5b667262a89346598d9f2d9c1 - 6e6f6886a55caf87221dc27a911cf4c389503d7715b1a791bdc17ba5bffe862d - 138b52768c1608f356dd8c88d5b28903a2295891fa139e4cfb16dd22ac8a755b - d496864c95288aa4197ceaa54112e60ae999a8aeca4bef48602298b906c673bd - 93bb62da2d0cc7dd0951d304fb878513d2ed70ae39d1f56bb2c665281551ab74 - 0c1976060bb67bd898868a2c245747a58ea6c1e71eeca9d1e196024b8df0314a - 96c278e9387e817caafd11c0cbd517b7cd3b1f1ca9c38a5741b7a46cbe180a9a - deca3d975759eeb165354ca2ac5aa5bbd15841673f5aa25313009e570dc1e70f - 58d5d5eea6b10c36f0d5d09fd02021ab10bad7ea9dbd04ed909c7f1b6632eb03 - 827d67ee609b96079824394bcb3e8f99d7ad77e27c5970fdf56f33097cd38c11 - 1a095a7cf2ed76014b32a5a73e6a4bbfd86755d2b6e403671fe65ee3fbdf5c30 - 3b261e3bc613468a46a8c04fb761fcf8b262b142ee4fdcee6a1a8c7baa76f442 - 2880206b06d406ca77dbf75bf5c0885405e9446e6d0cc8251c11b2a9bf12900d - a45b2515e240afa6d6091cc0618125839efd0e0cf55368b10f9ca04d9e18830a - c0992ca32b1923c1b950215e3eadae1e3fd102f64cb7edf371fdf743ed553048 - 7e7cc35827d94b7a2462fcdcc7e6eeacbf3626498d66ea1e7d98118431c7b823 - 5ff390bc68d3063cd42bb63daf5db50edecfb9ce8a83cc5565f1d3ea2d843df8 - b899deca8a36e07b79a38be4c064af92b908658743c2808b94f8113490163669 - 4b50d40b246e3f87930684ebfa0feee96a150e74d3e9150619ffa8c12db5d951 - 2e55dbd4dc21e09d0262a3b4c9ebe995ca12941e0bc32091891c68614df8ef12 - bf34b0441c2204694236631cf4b1992daf2f4511f9f3adc29858dbe1100bfa09 - 1a8343cf5987fd8175ede1a11e6a5e419d48d1fc834cb83e71e2d2b16a4d724b - 0768682f72e83797757e92a04fe738db302cc39622b33ff37a6f3f39503bf229 - 51af13e28a4f1210f8b88c5279464dcfbfcfb8c2cff3d2ff11321b7f5f1e188c - 00000007 - ba78a4b874ece30e24b271f4f1a44db792a841a7405e270accf650a793961fd2 - 09499109aa03394808cab26bf07cb44a856b76a52384c2c8cccf3e343a724d4c - 203d131c29a5060c9d518b60ecc1754c52c7abf223683192a40a6831bed6dff0 - 80a26b30e52b268c8a9184857153af60266b0eb40b0bc255d0e96649c63ec359 - 6686c1f11ac84488c6ba20f76649b257b6a3bc60d24d6cece4f8396716455dbd - 9b9df1ad3ddcd6db59e41d67d52d6648b5da92929d61a17e5b8c9b46246c5101 - ef8f4e1b64c8fd471deab9356fb1f5679ae5ac71059a1d54f7a1d72705128c50 - b45902f8da6e82e2851bbcd51d8dbb8f824a222596648dffbd61a1d6c95f9885 - 68500d1d3b084594e0a5c3f3150ed15c4ddf484f45f1a615d63be1d7aebca110 - e80efb7a86132d6a57d296343d7c784f50859c9072fdd30c08d71bff9667caab - 65b044ecf87e90d7943acb7b5f26a26562ebb6b0a2aa31514c096125ea73c2a5 - d17cb68392d92e6c1ac7805a57466a3738256bf8de6cb3c5ee944f45bd4f1d6a - d9977f46826deab2abf93378819376fdc7b61cf344d2265b9f8cd22a1632f738 - 244569171a23d6d593bd19634758b7ff9c8731720e771023fdb0a6241dda4f61 - a4385d3b9c5b6f6bb018324528aff429eca9c1264de9ea434a1a90e07f69015e - """); - } - } - - // LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w4); - // LMSigParameters.lms_sha256_m32_h10, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test09 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({"h20_w4_h10_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000002 - 00000008 - 00000003 - 4f9fbdfc21ece22a13965cd32027f6d4e5706e751440d214da485f202309a24c - f90dafc3d8f09f797b1b6cfa3636e18c"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000001 - 00000000 - 00000003 - 7d5dda179d7f33bd79840ecd9c46c0274f93453448b4b3c8eee74440b900b7e9 - 9da9eaa94691fda7716fdf2354ad1858df27d29b79c91cf30423c32d5e093b71 - b0a141ae160487d8a4451622b5ff1488167cbbf342a876d53671eb0272c6d1b2 - ab8d8fe4b51d50ecaa977f379903c9dab520df31beba6f6dd2a310b8514d7a3e - c78e2fd0a33369da3d5e8fde5a3df3669474ada32db4854eeddccb9daa82270c - 9f1f9d7d0f45d6b59db36355ccdfff8a08ce7c16cc5c15066b86fa955c7036fd - 5706b8560fd06fc1612fbd2aa9866eb40d962bd12585885321fef67dd80c3efc - c0a9f620276038b0850e9598729efcec780d56a67f98d1392426308adfb4d8fb - e4128ad38aad50060186b40fd63eae216d8761ad4b66600f90ad39dbac2c4771 - 6986754a8c505c0d33906b8a66ca740f68edf3ea55c9e0df72e7f5f1c3b6fdd3 - 67d8b0205a880a3ac1c9d2a9e48616753a0b9b34d63a8ee4b7f908cbd0a8eebd - a55823c0abeb1911d369ec16414ff39a2d1068ae1331af1eceb6ffdebd3bbc6e - e9ce74dbad7e6fcb362d111a9992b875d4f993a413348d91d7f217c0239b52f6 - 0140cf51777848ddd04fd1b481033b9ebcd8e4b129db0bb801d99d05ac2490e8 - 1f858d6f35ff29abd35c40fb650f97a0b32061aa7983822868119dca5c2c78cf - a4f76d26ba91a56bff8c6e500fa35aaf89cce3ca8dc5c9de98a89981cd9283ba - ceaef88dfd5a177d2c71fc7c1131c6ce74be3a2a7a673acaa731482cc4bd4dd5 - 8f0de26586c2a8863bd96d505821b7e78f88a0560860d022961e6d0ed3cbe9d1 - 22dd27f77208ad85d12dc33ad819e394841ff0055ce1649b20cd00af1942c76d - 14cb6b645d459caa7707f081f47b7a327b3596ab1e3af5b741e503f4888f5261 - 83d0607e274c4b544e72417aa98326de9bbf51b035bc70e75211b084a947119d - d7929a16d43cba2663a8d2ff8934ac0ee157f01c13fad772bdf15c52bc1cfed0 - 24aad7e06e3fb72f7ba7bd03860b804ebbf3a78b40cfdc46c147a393d8f88ed3 - f921398995697a51b5e3cd8a3b363d03f60f531e3f2d7a8205bdaa4e652f8dfa - 42a17bf406580fc7d2240314bc3632850352a9212fbb56e2c4055634ddf76f30 - 3c9818d2e806b3474587c3dd95d871b7b7b9987108d837efdbafc10735285f3f - 3613cffa7ed61e402e08cae00dd43aae21cb70c03cf1fd0313c365075a2927df - a2af481b3026b81aaba7652b8c27a1bf64df4b079ddabc4e142678e86021cfe8 - 35347ad78e3877a35bfa9da1325935bfd8ee76437c95e95a9199db1949a1d034 - 2ad2e61b7459e9cc67832093240540d8c1c69af238f5ff9ac49829c5a06db24c - a0cea539f2c58a52e256f404bf0123d03979c32da4b35847f01b253105d71a87 - 86972babf78052003d2f1183c5bb1f986de6b443ad2b8674a8a88cc6dd1c658d - 4efa74da693e5194a7c8eb68a7ea8313e7d42ace9ab5f15e2c536eb4c0da7579 - 5e50ff72b351c773c603cb749d6410608fe64e191715276fb36a97ee81720d98 - 06209e53f728bb3be9021a5ac2aa157616b6c9f4f587916732cd682359c8b616 - 84d3f0ad309c03a3d168f3927601544c622b99a3ddf5291e2500126278122794 - 5dd8244314b972e0e6c303089055a449aceeaad870a1171b3a93fb329cd777a8 - 9768b54671a3e87c9861d2c4fbd68971da747e0e12a70211574f5cbd8c98df42 - c7439886d089c3515f30ff5c5fb9e1e5a7f0d901ef76a8b5b290e0236caea5b1 - bef9f583c7d7b07bf793fabf560ebda31d56a19707fec2a476842dc8171faf3e - b572452a092de32ce195160efe384e7f5c6c5ccfd3201dc34d33fed0fa0fad24 - e13053dea01c5ef210e1d5c2d77a94a6acc3fc7d2bb7ead6ef69c5877c1d1587 - 931fef54754681e96904f5c24050b8d7617843674f4b652bbbcd19860da98aac - c1e00d9c6cdf4a209c8b530b243b7b8f1646b55f9c4b0a35b0133c67eb16b7c9 - 05834f2e392299ca1c61863c89e333f4530c25c7765379b69fe8ef30a644e746 - f09ad8a6090c2548e9294c1ea78695b90639e20de1fb47d3f378689254780b7d - cd4bd7dbc66b62976a5e5df5fe72eda740fd4e38382283f1b335ed72000f8e30 - c0de5eb9256808cc5082611a10395710c17861bb7513e52ceb23d005bfb419da - 440025643128f9d074351a7ac35e92e9d9eb1520eecc78fd7a8de4919d428642 - e1641c269261d4eebc817c82d5b59b3e34bad0a081aa549c02ad7c7c1e8b936f - 51eeb581e9a27104a1d210b49c8882234b2de3a655ca4b69b3f72bda9e910875 - 8cf881ffcab37b11ccd7991b3e12493f4a9e237c3184a838f029be09ac3d511d - 12dd84068c476afcf6d18c9516ae5800547b26d0a7d366af96125775f5fda02b - 9ac818f4d2209610d48e86c1f57bc71e31519363ea8bcdae791a88b50a84420d - 020b627b80424dd377577f0665503dad7d16d2f7532ac51b7adfe5704592dc76 - dbc6a32081f3435723b51a7c61ab2b8ffd27179561a8debafff46f1f6ba6a7d9 - 79a12962352728770024f016cc28caa3de3e7d9695c3c0d2c53d45b7b57e797a - 10d1b64e37fa8dd2981d010e95fa9c75619606aac70dacc633d7b415f440d4b7 - 37fe944f936990afa5f0149776483ead9759af9984c0d37a710735854f526e9c - fcc200c16bc62b6c0a7d3c18189f721eba9b90a29fca15de8d084e44c97cff27 - f28af689a7670286687cdd40e60a9f68e7eca10568d5a02561c3f437afc57ad6 - 9dd6505b04690530c9ed30c5278299a58057b7a24581a0eac0d26166d3f6b49d - 796f516103f61ec8f5a6e4307f97b77fed8898190b744c66eb661706fa71606d - 5692cb08973738cc0ea9a247590f23dfa8f2c0d406da850c8fcc639b0070c2ca - d9d4c42a42255611b781104068ae3d09e94a7b2b46df774eba4dc6e712509a28 - 2735e898bef0675f988568bbfdcd09720fa6e2afdc5590ecc9676faf12986f10 - 9eb838e4e998968dced593c337607f6190b1f32a3cf5aefda5043cbc57e0ac09 - eed1660ccaac44af2c55b12ab13a7ef3763eed79cd5ab1b754cf15883c0ce966 - 0000000856bbc3dc1996d6154a8847e9800276e50ab54db3c75f879f03c48c91 - 7cfad26d2199acb69cccc8149332d3fcb94f076e55818aa59dc477ecf1bd16c8 - f362695da854c55030e90919b40f9aad3d43ead32e97f596c066eafe89d4a8b0 - d228e9ee47b531dcf1337b4e45c4ad21ceda14ee10f5f60ad341ba84bda14500 - f4c6a8f5317bd98da8713f1d76508046c62decaf44c61d752a9ddbb539eb5844 - b4ce4a5ddbc1a050472236a437713603e34fa0eafd713017b932814b6b24a74a - 1ff7a6c5d47b4153e2007d87dcaf47573425647f7e6f5f032a934967ada85b7a - 8e8934b8aa5395988a6fa50261b8ce6b7900bd6a8bba2d2ac54cf7ce04a0718a - 5eccf4551ae37c7b136081189eedbc1793ae7dbf368361f00b1df0cf236bad37 - b87b7cec97715aa6daabdb2b30301c376ba7ebb44cd9e2366411aa3b3a1a351b - 46c45cafd23213e5c6aabfe59d622904bcaa84d90fa9da47d522bef92a523a84 - 28e1fec7cac1137532af968d413345dc3ef38b7d6e5f83594f31570ce12c3d8a - 2a046604ec433ae94cdf82eddd28fcf603fe605007420fbf34c917e7104fe1ad - 1ad45d346c2ac6058bed0f4c44d003e093e4e686a9dd4d80abbb716f7363f204 - ede2d0aadbf882db09bc75284fc29b6208b3b8d7110cf847e1cd9a1e04d14cfd - 23accde55a2975b5537614fe1809bfa01783c0e3bdc821eae70a5e4ddcf66b4a - c27a3d76e12189a03eab3cd40feb892257213b1318bed0efeac00396546f314a - 97b9afc7eb3ef845b4d53bc8593184d734ec19c93fcc0431c5d74afc8f9eebae - f12c7f186a464b0d1b6bdf7ebba592ef9f6d3b3af332a7f100f82619535d7ca1 - cd99e4134b50e84ea167948c244f928304f6d008bb7f8a10b218f46c227f5255 - 980ea31a - 00000006 - 00000003 - 5490b78c72751e0485c63a1bea5313f0462907f953a8d3ce7e585426c07e608e - 33cfd90fa196727a43edb3759b712afb - 00000000 - 00000003 - 0cb7dce4975f968cae1c1affad81ef53fc2d68bed7d3c9bc83d85204a209e24b - d73256ce79a2e8d2d0ba728a526248518d5201250ea5f831a58c2d03e7aa2fd5 - f4eb1081f5e8a7b49ab360caa46395d5c48a527cc84a2db4476194c13e6cbfa8 - c11e825f438552014a816e147410daa4ee0ed43c696e78c704f36e924a76008e - e231372d7f50586276da32b3b340d5714d3d1ad1e12e12de00d0a67c61fb6226 - 5b5a22baf87d2f22d9cbd79b2bc7c9cb0f90a034dd861f50cde7b41ba64df79d - b6c288947156685454739621b526565851d66ad7a47929a97bf82932664db663 - 550b4cea602c3afd0691cb363df0f8f1858d7296bc99d490df0ca5b5bc5d2a69 - ec20f1f85634b7a87b82b4d293d6996fa02678af04e42801871aa56138465452 - 7f699809d424f62b3d0e4a4e106c3dec086854ba3f61d0edb799612df24ea4a6 - a07a7811abd4968500e344948d1293baf4d6a194905d5c526b16e4c4ff28bfb9 - b9e03d7a9f184c06441b0631f781f56d5a51f62f3fbc7c3769e32f68d623f406 - 94fe7179b89289c24493041f4e2c653173cf3a8b2051453d31422bdd50af4a81 - 2e7bdf63d04765a1ea6a397797a827b7c5ac38d58a7f6196ba5db478dad6c031 - 143f7684b771a4fb7999152a69106c72642742d892233147e085f5e4793850bf - a83660db5b53df4e67edbc37b4a6a076c419e02ed54b923d708f16d8561c5abb - a10fde6c6043f88137bf80672273924336a81be63d44ec26a4afa761164a0c09 - 640b1aff3ba0f4dc43d16b382d1135a57936a150323ea3587717a3dd0a8111b0 - 0b875aed7c7be5250fd2ef9bfb968293ca8121d227efb07b8dff9dc819e6a5f7 - 459fa5ea01f62b2a8e278e9ef2a7029b08df3a76198de1e840ddc15533195403 - 197be0c8d1a086651e4dc09e3c59f4b3352662800af531e927b9e52e8a1d0631 - 1df831a487760cfd6e7a713bdfb2a9326bea28f59067a989d1189889b8a6b9c4 - 011f0d28113d9f6c2e506bd120bfc78223f6415cd657391dc3f9259e5d9f44b5 - 4eae3ffbe634eb9880c16f6d67db25f0881fd59e5796c9152efc63c7cfd4e3df - 95b98f5aa6a9bce0615a34bf15114dd65e0f44ecc7835754ad6ddddc0f2b69f9 - 2c41470fb6dbfcfdd1b61292b353665c6fe8601e120ce412bd643049802e3903 - f25504f80be1778e24d9166545e2da6552d4c409093a781e33447179fc260164 - 8598234c932642aa4c307da2670c70fb4dbba29a4aa21fd2ff302364cb13bced - 84c0da69d60ce846095ef042f7213be8ff94c23b12e5e5f7bf4818c461355383 - c6fbb50e0988f992d82f75db4b98246aa6e6d50713c3b436add3b95670df646f - ebe742cf69c6970b93c7acc86a868c979980e2dc313afcaa67d31ce5dd0c5d97 - b20f6fbaeaae2a1b2126e259c2d0b3268eaf96a6a42e3eb0dafb9780ec17c01c - 40a85efc413336bcae40324924a311b8645e6554004ac20d4c6334a505ae5c7b - abec7871ee593d9ca8cfd9760417966892d916d9125a81822f96d3d3fb5ed343 - a6a8ac47a863dd3bdf502d9d5ffa040398788c446037b82e00392a00ebcc7c7b - d81e85e5986422735ff38cb189dc7c24510a7287714d58aa7b3e645a9cd5bd44 - fe4a3573844f5df0ec015c83a15eb3c483b2570de8d105a1fdf6dea1edebd26a - 1b4303814b30f16bd064051d077f07e97e825372ed93a10d2022d2a8d93c085d - 862ad6006364ab5742fd3e3451ff62c1e8c966d200e18f3f55d79d1ea49d62ee - cd2e2a6202cda533761451e34b691d45b5a6b2227856dfe27cfe777aa9069717 - 3341aaa79f07975b73cf8c5a26baffaa867f1d41e7d866895f1ac652c19db1df - 3124d5d89668032c62c6862aefe101158705e3c735bb1f211eb5faccb167a11f - 5f2e043d8c7ae469a28759f25cb477fbd237c44a33a74dd89723aae046ae56a0 - b15d415184f0bdd947961a7d3e66480cc3b51d0ca2c1db86c327b0d3270ba864 - ed76406b22dc6d107bc172fb9df3513e07ca6365389e41f4a746f56240b921fc - 464d1b28d047026abdf970f2767e114da3ff0355a9ab0932f3a9a3097520f9e9 - 3bf3b03e9b460a7846afe5f316188fe17751857d3bb43ea3a506c974f5d0270a - e519d5ad24b407372f0323730bedcd660f9abb0acc1221ca9e2b0259b1cf4ed8 - c64b74776399928598a216ce6ef437056bb752d437347978369b7a578bc41077 - d57a6aec7258aabd4c623c03b1c03f5c73931e675667d0c10970f5c620fdaf4f - 80d59b70908b30c7a40114d67e92eb93ea34944fd12d6cc7df10bc0d1227999a - 200d3a9e92a01a8736ee839d0e72e59a709581e58c6bb03ff7585171f534b97c - 4a88937cb7c6a6bb9b1572fd3c2312057ff5986fbb4119a440600496497a91d3 - ab0e2b5a744eab30325471539fa9116fae25fc74fd17eb1b75329850ceeefc05 - 20fc7dbbb35a679cc0c813a19abd5a5730d5b9f0c0bc08d2bbcaffaca6e7b670 - 1b9f5dcced66b888e93f27c1586e3eb3637e75664f8b88fa2ea8408cf5b90a0d - c9fe016cb773fc85e0b4c5e37a4dd9320fed177e0718862be9a1535274b70668 - eeae69369e3746dbea3e3b459f4d20d4fdfc534d5c79517b9c74d4095e4388a9 - b3c7ed169f83a079bf4a883cb2bf5d88b9196667f3e2eddc26ea24f192e5ee3e - f68712a78d1ad086eb776a9be9b0301e50e019fb78c70ada132ab3a5bfd6df92 - e8a78d837f96ac5e7ff5ae5284d4add69b857bbe06312ac0f579d7f1d537ef5d - b6cb3f775f6a40c85a57ba0f999196368eb0939e68fabfc913d29ff979a1a3e8 - 74706d3448d12c2eac1f520d5c833138c67233a6109bc3f13d1c9a763c795cbd - cf94a0682257a16401deecb7dc787be82ebec9938df10b1d7ffa147661b11a13 - 2ed1a432ba87fd76a5be4ac11ebc04e7c151d37b9031e35a9cb7890c2dccaf88 - 786f3186acbc3fa033ef3fcdf1a670453b07bb1e4bd96e0bd77749ba9c1ae577 - b5499b24430d7b3d3786a4dd04c7d69fd052f4a192bd58048b4aea01ad7a14a5 - 45301c513045cffac021dd9a8640b184b86f915b5967a0996cd6e706e776da68 - 00000006 - 180968d5c2d73bddf40eb18e436c809891d2689205550e01993e1b9c0c767575 - 2dd3d8c2c702aecf34ad3ef16e03b398f1e3d66e490c3d6e086bfbeda5efe599 - 4cfa5b469a145858df60fed7c71fe8c1fbdf5fbbe5dbe85c9a51016bd9ccbe9b - 6bea3b494da9d308c8a85db2fa6848c7db1881615a99b452484c67f96be55785 - 7b43336be8ff52c5ce5291806e2118337f9a25b26029ec4d1d8023961a5424a5 - ecf2b18beac1653790736e6f6a5c7a95ab77caf54ea06c0c11ad6981a2af0b7c - a3e964dc09397caf0e78a63d57aeb5c3acb9c65894b134092a2643d992d53107 - 5c43c911d5577be8fe88fa023a3e36f32f9333e3c6207ca1b0018c0e0f389827 - a7a4cb92d8b054a206adec09b35ea6615069fc7d49132549bab5548b9e1fe61d - 2b7a9ba0d6d3e0336f17f3caa18e0ea19d6cf0a9c0e48a83cf325369b6a091ba - """); - } - } - - // LMSigParameters.lms_sha256_m32_h20, LMOtsParameters.sha256_n32_w4); - // LMSigParameters.lms_sha256_m32_h15, LMOtsParameters.sha256_n32_w4); - @State(Scope.Benchmark) - public static class test10 { - byte[] pk; - byte[] msg; - byte[] sig; - - @Param({"h20_w4_h15_w4"}) - private String test; - - @Setup - public void setup() throws Exception { - pk = decode(""" - 00000002 - 00000008 - 00000003 - cc453a482bbabfad998dbbacf34c0d89151995177fd38cdfa301b645fbad1675 - ff8083187b30a36242b11bac4bbb7e0c"""); - msg = decode(""" - 466f75722073636f726520616e6420736576656e2079656172732061676f206f - 757220666174686572732062726f7567687420666f727468206f6e2074686973 - 20636f6e74696e656e742061206e6577206e6174696f6e2c20636f6e63656976 - 656420696e206c6962657274792c20616e642064656469636174656420746f20 - 7468652070726f706f736974696f6e207468617420616c6c206d656e20617265 - 206372656174656420657175616c2e204e6f772077652061726520656e676167 - 656420696e206120677265617420636976696c207761722c2074657374696e67 - 20776865746865722074686174206e6174696f6e2c206f7220616e79206e6174 - 696f6e20736f20636f6e63656976656420616e6420736f206465646963617465 - 642c2063616e206c6f6e6720656e647572652e20576520617265206d6574206f - 6e206120677265617420626174746c656669656c64206f662074686174207761 - 722e205765206861766520636f6d6520746f206465646963617465206120706f - 7274696f6e206f662074686174206669656c6420617320612066696e616c2072 - 657374696e6720706c61636520666f722074686f73652077686f206865726520 - 67617665207468656972206c6976657320746861742074686174206e6174696f - 6e206d69676874206c6976652e20497420697320616c746f6765746865722066 - 697474696e6720616e642070726f70657220746861742077652073686f756c64 - 20646f20746869732e2042757420696e2061206c61726765722073656e736520 - 77652063616e6e6f742064656469636174652c2077652063616e6e6f7420636f - 6e736563726174652c2077652063616e6e6f742068616c6c6f77207468697320 - 67726f756e642e20546865206272617665206d656e2c206c6976696e6720616e - 6420646561642c2077686f207374727567676c65642068657265206861766520 - 636f6e73656372617465642069742c206661722061626f7665206f757220706f - 6f7220706f77657220746f20616464206f7220646574726163742e2054686520 - 776f726c642077696c6c206c6974746c65206e6f74652c206e6f72206c6f6e67 - 2072656d656d6265722c20776861742077652073617920686572652c20627574 - 2069742063616e206e6576657220666f72676574207768617420746865792064 - 696420686572652e20497420697320666f7220757320746865206c6976696e67 - 2c207261746865722c20746f2062652064656469636174656420686572652074 - 6f2074686520756e66696e697368656420776f726b2077686963682074686579 - 2077686f20666f75676874206865726520686176652074687573206661722073 - 6f206e6f626c7920616476616e6365642e204974206973207261746865720a0a - """); - sig = decode(""" - 00000001 - 00000000 - 00000003 - ae258cca017619f7c85179c0dde1f48122fe5b3adcd5ca14475308c6d6a87c8c - 6cbbbca7a2dbe83a7fa7a0814e3d692b66bec046ed590831e695e0391c0028c4 - 9cd5e4e561c983d1640fe534964a4e5725705a4d907f5088b265e329011b8047 - 330fcf0030724ce62edb5382e59af394eee06b0fe84d95ff8d22b0ba06c31876 - b85d29135bd4291f49db0f22c1a304ecdea5137b6b59c49cb053c6ec32b276f2 - 9dea3ffe6c10f3e99e84b00221bdf587f703e81ffa90e9835839b693fc3e2b06 - 1cb47c8e3392750c4f53461e419e151004df01da6d8bf8a7998e88089d18c487 - d1adabe4050214ae3c5aff0b2e7de19a734d6cc06ff060c5ca4ad5c68178fc7c - bb66b7de65987ce1dc966f1a2f9fbe301f43e6790df0fa452884b3b9ea30fd33 - 689cf76ae7eb4f6c79f6fae9e89cd9d0349928757dcdee074eacfeb3e1860d0f - 1e8f335be9d0ad131da1932730fbe5997a813439920d53c4a36c6ebbc4a2b8d6 - 96fd511a6b92404421674f1b1b79298243c60bd524cfca71057377b0d0c318fd - 341759a91f4b47f5b0df61d1eb1533982707970789297a1af0bb2fedf8fbd582 - 87708cc4c3304246313b323df92f36fa6fa516c333197253c860b2ea4eb92cef - aa33311f2b9b3af958d67a9e466357f671a1255530fff1c2a7d976c26837bfd5 - d7d9d6ea5f87c81abedf1e1b83602250e2226f54eb8f3f1e00bcfcf241e655e1 - bf79b0d57b947c196f6c33360d303735d323406411416cd1fb2391d3adbbf0e4 - f0ac38767fc2e9ebcec97a5c80712bef5deeaad9c85fc4d024ffe7cba0608c98 - 90b023852af96a6dfca090187a4f07447d89b1162d0a65e4cc7e2481b057e199 - 0ed2ee333d2c4f26c6321e2b98017fedc0b42202caf469405678a63108359387 - aa240fe210d833914423e02d892fe26290dc2ba89bebdaa2273fe265b5d518dd - 5b406c33656466f865c1ffd671b46e2b9044c256798afb1e1d49dfc025aefc06 - d6cb1a968c5bb3e200944de6a81bce2ee450559fa3e302effeff2b4e919539ff - 3bbeca0575eb8abdc635fd330c1606b1c810029ed55d8a71253ca89587762629 - 1aa537e4b0c155e7acbac37d1e447586adc56ad262b0ab2421291a28b4e664c1 - 70750274d82b7850fdf745374c2c2eedf9828300b3b2b9f8d2d774063658ad05 - 92ed8b8a26e8021ed63f413996d1c12c6a5e80a4fd1f6ede5f431974147d9116 - c356e49fb7cda7d35bde52b1c0efdab1dfea8db8b13c608a5545723ee3611456 - b21da6a343ca0c432a2353dbf926e2f3227e9659618cc6b46f46da614666f33f - 1d979c6d838b678fb027a2ea5ae601592cb28efe10918509418476639bfd1f0f - 7dd8bf91f7b28499dc72039218bfe37595e1741942e4a2f640a92dacd809521d - df34aa2b549d2b666089a9df02d963347d565cc5fa1af7f700237db8a57f0cee - 4be997ef40f8ae0631877d07b71a4a76d3f6f53a737f14e2fb0f2222e8649144 - c3f8ac33595fd9290a2a0345eb1e4c06187ca4b5ac77098e473a07fe0cb58d88 - 1967f7f645ae144a289744b0801165e9c47d5137f79d3538d6f3a45c962d06a0 - 13248d125cc52ebd2f3e4ced0d7c1e2429425da6b6aedf96db2c2524522e95a1 - dd83db37e92f782b6db3c84ed3f55f32600003d9602c17b6280fc735787f8381 - 853d02d4b03a97a9404bfe6cd4c58c1a67a70298f29094b454aeb1bc0d59e0d5 - e24015f9257d28554905003a687444ce51b19b7e46f4e56e899e3ecdb9415119 - 924b0a28f383b7e8f817c6430dd9c7b13b6f93179f77c5678fe51098e4c0425e - 7d44cd2e82c07bff8b8e99ed08d86982ef7680f8ac3ac2228dd286a1acad546d - 43fed64175190ecc62f1662a2f2c29cf2effdc9f9a18e681e96cce1bfb41de22 - 5b3c02ba65b4c5cc5591d5b17b64a3e8df530ea10627ed29d096f30934d10954 - a642548ff04651c9f24ba9c0496bdc1a8af76afc27eb3dc9e28247ab5fa7274f - 0cffad5af2cf50ecc35f0b466fd7b8c6973d1ace0cbde0d793cac473ff151aa8 - c9bc3d26beb8d819f21ed0ff1fe6af5be4cb4c61e1ed6897496fbbba14f2719d - 721742fa7249dd251e501b98936ab43d0fcf4b7a2d551471d3e663595e19e235 - 674d7d525b6a5ae14ac45913cbfc51e80a7fe351d0cb24a8af1b970d309517df - 7a7dd6b12c6edbaab5addb1711abca1c412eb7270e9a8aeefbf7cc5ca22436dc - 75b0b5989e1c25f578f8d0aadbde0175e67b14ab05a4c5a5e061a030282f5415 - 4eebb5a717854b02877ac1fbbb732e52b18dbecaacf16bbb74954f83c0aa470e - 35d099b7efb1e17beeeb87ec0b9e706c331f1b20f0a903dec2b7ca1c196b1d63 - e804513d3f474cbe6f9bbd2900b79b073011004c49d20f7420a01b7745d490c1 - 0da63786119d895d58b44eb066d80c88907aaa211dfd82681634be98400099db - 8cb82b6d6172478cc2e63d4ea6dd48b47702b24b6fc7b49e09d87b61d15b59d0 - 39a6d49b3e4896ebe0c83c70ee6926d498ace6148ef3449a7830a7ed4923866a - 3f479a708a7dc319c1161d0f29cf425682c389bb173f7681c193ac982c1e4012 - 6a122b2c6e3fd20906c2921987b2a20d21c722c5fe899fc15089e7b7ddce4262 - be8acc27fc4b4b5176740f8f3adcf44240fd1d92c5b1db869bf0bc957175fad6 - 2d8ad0368b9b47da61e5afffc4ed80ea49890178232dd021d94af7b15bd45059 - 67bd91eaa2844169e89320c92914e27eda9800cb81b8ff11a52043439035a275 - 53cf146c9c765b3d5f13bd348475a8bf9b3021168364b7cf0b35b4a2df95adda - 7d1d386021d0ddf9193934ae4f0958d2ef8b15a0278e5234aaa976a8ac6acc45 - 7fff27c4d64da9d374ddccc55285069074ad79bedfb606c95a5d294e97a49571 - e4b89696b83a69b4c65568e7ba4b4da0903f819a75ee42f6539b4edd45a53dc4 - 07c7028834837cb1665050f13b3f69560dec7f042d3d8979fb170257bc024764 - 627d369086f127e1f5a95f45cf49817c2c699b8d0b20113259ed141e6c01e23e - 41a7bb7415f324ba3710534126db40da893b8df672bb16a752e873bc3203dd83 - 00000008 - 24bc09be9c410f127964bbf6430a7b42f53ffe22f04cde135d46a847de0844ac - c15c1197f938dcb5adfdcceeb52f95ca113148d07192ab76d83185054df0b38d - 8f95cd789b916bf8f7d4b7094802df6ed52cc0573756df7258f12e439cfb1037 - 01dd72bbdb60753be01822a1ea210eba7fdcea2c9736e79e11ce2e3b50f21a4e - 0d84d9c578bfcefb4087146a40c95922b2dd69d29103d9f50fe3368b19015172 - 36922e837fe8bd50e8063e5f0c2d4a961f1816bf7a5b3eb7ba63761368cae83e - f2fa4e03491acbbfd6d0a6048e3f2589e67aabeb32b3619085ff2d6a810065b0 - 5a2f5526fe1f188ee80bdb9788f68c1e93cc2ea104e404faceef91fa6a28e27c - e6c2a6a4b03b81c7ca9ce94f06ca7762cb344bc738add901e6496a3fe739343f - aad8396b832ac93f039adad869401a2e590dda2d9c571e136b55053e8bd17af4 - 2e5518ef8b8dea3d9fefb811e7248961af4f67921c5812bb87c27b22d1384109 - 85f1f48d40e4c86a1cf7b1d47cb2c776aab2b980a8a1a5e14f6a6c3e823f8b91 - 9d7de7705ba30357aad9b1d5e7c3404aee1fca2706bb97e94ee56ce826d631c0 - d03a93e676a557af5b3105c9cce0364907f1c7520a3a9d70ceef18bc86584df8 - c707e48982dcb6221aec3bbe75151d0c50662caf1b401466f089f464b23e4b10 - 77f4c2ff6efd0ef42202fd51494093459329eccdf895e038c3f7e2325775c399 - 4ee435f799d7cf0ba8308d018a1c748a5b96786d4b1090547165d30cd9e50c9e - 25122424b4d89b5f13949af9eadb7e9bfb95820bfd2053e339dd154593c8912c - ede4bb64b3dad525f55bf6640d99876654d3a9666ab81b38f1e7d41036a2930a - 3b4ba370e6fb1cb4436eeffb3a1f4029eab69d47e328e3e50034e3facd1ab396 - 00000007 - 00000003 - ff29b4fe1b544b372b2922adf63187d1a8186efd415d82a993a79ecd884987fb - 984f03f786948f53a3632e75f622a334 - 00000000 - 00000003 - 9818148e2b3f0b1b92424b8df20c31aaaf4d2d49997d481a2be32680e62eac63 - 4dfc4d390876d14599c23d59822e0d6f525a9afbc8319f75de7370043d33e413 - 7b9f1fbdaeb3e47bdbe29fb7e3247ee5a1c637bd739be597e5513b81e5b717bb - 593037bf97b4c1f216566a944bb19bdac86a5be82fc34eef1799e07d7035692e - 687024660a3a83fe17d73c919513c12660edd8af23975ba3816d027b7cff5e5e - 675f5375bb1eb6eed9e5cc49b962a97b1cf41d79422f2d8e290ff119d1cd562d - e4f65dff4a7408b2eab21093d096707cbdbb70e8bf6394969e1e51700a500a98 - ca1fa371d96eb24b359db9af3d2a5e125e33b87edc22eca8764eefce39dae0b6 - db5504c256375a7b6bd8ffcaf48a1fa9b246bc9952f8374d8d65cf22439668b0 - 3c02ef6fb4a1512dea8d7c38cbd8946114bbd57a0da2ffff326bb83873f4ea40 - 09270671b0d9a88e10c9552ac580160d248daa7bc3a10cb393a1a2aca8ed55e6 - d6983861830557e7001d65d8656c07fa37b459a5bc3ff26c2109be9f395d1307 - 8e27e75f85f388562f555060fc040650be7c5a4984bfb41fdf0ebc2da22a8719 - 563aa522fe36af768d95d49da30c899f3409c8a6587403411eaf032a84354039 - 1b136a795a0b3da15351ece2f62b7cc15d8f9e3bbacf29bd73e96c9761fd23ff - ed75c8131721899b2b314c61537e3d324706de6dbb4adde305943ac6a2000e5f - 6e193f83b9381ade4d61a9ecb2591ece400ace7735eb6e0958d7d1c9b0ef4990 - 2ec4592c935303c71049c44a518d65537cd903c95c37811501028a20b4aa4030 - 2857c970a589260073ea093eb913a11ac42c67034d27fed38b300eede2ccb18f - 7df10d09d9cbeaccba52471fd01d42361343889e5725a7f2d23c723517337e94 - 2f53fcefef8c4f091fc1a02790db7a987bdac6f67382619a84c003fb76f27e1f - f070bb8b7786ce47d4455de311230a0e1dbccbb8bd37c45f36e84e3f15c1e4e9 - daa1b4a082f85a5c2c71371e39661792284357a7cc40451e39444e8c352185d9 - e7aa1e7524a1eff33b5839c2247b1430a517db6ef4963b23a1579a3803c0d2ae - 3568e0d83d551eb68dcd301e75f4cf38792cc504a94559c1b1a929975aaa38d6 - fee0aefd1aa4c99cb1412736b2f5978c21987e651e391c5b1e61cb84d92d3806 - cb5fe46edde39efbce75d0db86414e82f6ce07b6c304c7f7fa887d13a02e8f59 - 57b8f07ae9b80a10b3f050902a230e5b33230473691af8c7c2630d899c8efa1e - da5afd1db629318736132466c1970f9753200e05a30ee13e38b4a60e15fbac33 - 986a6e7760c5805b4f488580db0008e574e173a34cc62fd52c9cd56980249a2f - 0c12238a0df04a06dc9895413b31fd0aa0d9eee50ce7fbc178f8719bd9df399f - ce72a57e8571fcbfa4f174f0c37c053238bb9225d480547b34eaff09d00fd29a - d2daf5b694ba4ca8a25e42f14f2cd7c10477ed29b22936989cb7135c8034f81e - 2552fd1d15f54ae69054fa03a36ff48d1ccec9c45dcf642dd4bd0e2aed42d4bc - b3df5f9a10805347ec0524c13d49014ca1d983d7de40031f530a34ca1e8ba45b - 5b304303a71942388b61779ec6ecefab91cdf705c41d6c2fe72a6be231acc3b5 - 496661b0d9f5908d0f39463b785a98348a0f9fcf714255e6d9c9c33549541567 - 55980f2d96686e98f5a990f821504cf2a1c32d2b654f0071dfd85981d59da1a0 - ecac2d30b1e2833ea108982aeb059d8c2b7facbcc4391bdd88f900cfae20cfcf - 99fc75fd68a85bee6a75be7cf8f4b8a66d9bcab17094e51e745c9b8980b69cfc - 4d9bbacf338fbaddad1fbcee745ce30b8ea8316e597350bf1372353d38274c31 - 34c9e3ddb3affb1f5d5b30a51c3dbbd7529446f4bba26eadf4aa53e7641f70ea - 60710d773b02d930a298f8c6957b71f6841a6391ae9d5d2ebee3600061c57244 - 7ff9e16c211a5b71ab1e7ee811f70a76aaf8617648083959b327a8f15698ba87 - 3387b492ae7a7ada5d78ae4fdfce67262cacdcaa0717c4e52d7ecd85491903db - f64073dbc2a0f77ba5489f0af146ce8d4e1544f60cc51d2a9db84eb5d8b3da91 - c10ad2437744c8b3077d592e5b42baa7846d4250df4c98112b688813988a6759 - 2fe7b707276dfbcf7cbe3daaf0be3c8c13917d4f2c70c6b6945e05457ce7018e - c167bebefce80d10502f5a2164492a8602ee7db978c51f79612b5b9d69013105 - 05bdcbbb66a385ed2702a630303fcc30900b8d9c345229f7d539185cd2cca328 - d40dbdf3511715cdf195c7565bfcd7ae7830374d4c77acf746874068f7f0ec3f - bc22fdbd06fbd4a4bc018d6a81bdf9c5f3ec45c441333cee36e2f3d28f4d4ac4 - e45299a3ea7151e2f314ce1d8c7f8aff7be4886bf8ab8de2893f17baf2969125 - d4b8e4f036b3b60c88e0c08450a8e7ed005831f2030760d4a97c419a859ded43 - 85e855bed5b966d1a97845fe8a6dc7467a2529ea005fbf0da3fd3efa28142c92 - 058dcec7ec1e1f199ac8c777857295b34a33e2b678c04475b7dfeda7656dcc5c - b948ff2368e989a4688c16ba02479ccb107f6fb27dc30f0e49b9641aff149d07 - c6afd31db92c8a5d0c0f4234aec0c0e1e05c7336378b387d1a70a4176dee6835 - 74811cce4b20f0730ef92932d1d790b6cf73081da8c51b75ba8950579b92c117 - 567f3a1fd8a049685a7aacd9cbb997a0aff7e6a34ea7e70fc8cf24b11f96d2f9 - ef5327eba013bea5cff327f3a5aece1b8a2fb45f80c2454a9cba86a55a1ef63c - 7862d07eb1274fb68b69db5a0cab9b5aba53595f6e0cf643efbf38ed33e7bdb7 - 3f887e8bc0e50c003bb8523b7aa459bd0517fd3b502ad4fdaa22010cb6ac5bf9 - 7d6ad67c2317a9d18fa8efc4c02345bba30bdfeb788c001ff4f9a899b0d11043 - 454b52fc2828fc1891e149b42ef897608d95f568f3eb301023dbf18f40da3148 - 45821078487199e71a6b48b2105851702fb6319052ca642ed6338c41cc8b3d95 - b101a08835e9352f71938d24f8789d32add82e7ede0fd1858330a451015f7e87 - 9c5eb59c8e534beb771aee8b0fb2bf4937fdc9cf07d891ccda61ae4aad303282 - 00000007 - 2e0e7708bb0e589d2d818a8c0e2c53b3e59b9e43c7a194fd18d19ab1554a9f85 - 90b31f08e2fe1b38486572cc3b36ddaa9d85b795fcd93acd531283688191b5f5 - a744b89faae49989127685cdc000e001a0d77df3a5c3061e312377b1050e7371 - 24a68d2a00a848e141d274dccb8e4740d33ef7970494ed316447f8381ba06791 - 001e90b7f36ef24e1dbbd68f7074ddd233d9e15cbd4efa4a249cb30fd3095c3d - ed096e87d6c179ff8dbadb1bc6493bb6f944ccee2cbf24573017817e586475f0 - ed51bfe889b298a2fb76d16dde0c966a70a284dafa980442f870d640e11079d0 - a4f6834a62ba0a4eac4d7334f3c756ea6b0bd8eafad227b5b8eb4e937c32412f - 201780dbf5eab317f3a21293e653115bbffac4899830eb28e6e43c1a77b51884 - 8f68887ccfa366175be2a88d3fc178e671073736bd94eb4e16720a6b3ee119b6 - dcba885ecb46126614c7a677c1662c4cadcda742f27fc01a8bd5af474ee4a29b - 4e25721bb931b8bf898afb3cb66d3fcab70b80005e737ec5bd88d5ced8941226 - 720dd43655a9ba1d4bf0a723faa4bb3651ed2ea7e0bd08113e524777e6ec592a - ba5cab16b084d208d20bf25ad9a7ae31bceb00b07ef20cab7d1f6883ac331c75 - a2aefb8230ae97dc34577785b123af406040d01fd072c493228d7583cd023c25 + 2510a21e43c9b53b86557646b2c891ba432813ca61fffb57c4a8e598753542c1 + a179d3af5254a37c01eeb4393d626771858d06041c76f1960e754e9e04aeb91b + 1d9b7736193f49e15c47f44a8f1c8aca6133c34eeb682fdccf94886fe80d971a + b4a0bb3b72197d2d5b2111da8647be1675983e8ed1c0d8ec7cada282dc698656 + 95f1e8806c7892b65fc17103ee3b5366b3fe31e57e653336be283962f488eaa5 """); } } @@ -1844,78 +376,6 @@ public void setup(test02 test) throws Exception { v = getVerifier(test.pk); } } - @State(Scope.Thread) - public static class verifier03 { - Signature v; - - @Setup - public void setup(test03 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier04 { - Signature v; - - @Setup - public void setup(test04 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier05 { - Signature v; - - @Setup - public void setup(test05 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier06 { - Signature v; - - @Setup - public void setup(test06 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier07 { - Signature v; - - @Setup - public void setup(test07 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier08 { - Signature v; - - @Setup - public void setup(test08 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier09 { - Signature v; - - @Setup - public void setup(test09 test) throws Exception { - v = getVerifier(test.pk); - } - } - @State(Scope.Thread) - public static class verifier10 { - Signature v; - - @Setup - public void setup(test10 test) throws Exception { - v = getVerifier(test.pk); - } - } @Benchmark public void verify01(test01 test, verifier01 v) throws Exception { @@ -1925,36 +385,4 @@ public void verify01(test01 test, verifier01 v) throws Exception { public void verify02(test02 test, verifier02 v) throws Exception { HSS.verify(v.v, test.pk, test.msg, test.sig); } - @Benchmark - public void verify03(test03 test, verifier03 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify04(test04 test, verifier04 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify05(test05 test, verifier05 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify06(test06 test, verifier06 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify07(test07 test, verifier07 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify08(test08 test, verifier08 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify09(test09 test, verifier09 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } - @Benchmark - public void verify10(test10 test, verifier10 v) throws Exception { - HSS.verify(v.v, test.pk, test.msg, test.sig); - } }