From duke at openjdk.org Mon Jan 2 20:11:55 2023 From: duke at openjdk.org (duke) Date: Mon, 2 Jan 2023 20:11:55 GMT Subject: Withdrawn: JDK-8296322 javac: use methods to manage parser mode flags In-Reply-To: References: Message-ID: On Fri, 4 Nov 2022 12:33:44 GMT, Jim Laskey wrote: > Manage parser mode flags using methods for easy of reading and maintenance. This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jdk/pull/10981 From jjg at openjdk.org Tue Jan 3 19:16:45 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Tue, 3 Jan 2023 19:16:45 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet Message-ID: Support for Markdown comments in the standard doclet. To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. The work is in 3 parts: 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. ------------- Commit messages: - fix whitespace - JDK-8298405: Markdown support in the standard doclet Changes: https://git.openjdk.org/jdk/pull/11701/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11701&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8298405 Stats: 9618 lines in 140 files changed: 9345 ins; 113 del; 160 mod Patch: https://git.openjdk.org/jdk/pull/11701.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11701/head:pull/11701 PR: https://git.openjdk.org/jdk/pull/11701 From vromero at openjdk.org Tue Jan 3 21:23:53 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 3 Jan 2023 21:23:53 GMT Subject: RFR: 8219810: javac throws NullPointerException [v3] In-Reply-To: References: Message-ID: On Mon, 19 Dec 2022 15:44:57 GMT, Archie L. Cobbs wrote: >> JVMS 4.5 states: >> >>> Each field of a class may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS ?8.3.1), and must not have both its ACC_FINAL and ACC_VOLATILE flags set (JLS ?8.3.1.4). >> >> and JVMS 4.6 states: >> >>> Each method of a class may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS ?8.4.3). >> >> However, when reading class files these illegal combinations are not actually checked, and this can lead to compiler crashes as in the bug example. >> >> This patch adds checks for these illegal combinations. > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: > > - Merge branch 'master' into JDK-8219810 > - Merge branch 'master' into JDK-8219810 > - Also disallow field access flags from having both FINAL and VOLATILE. > - Detect invalid access flag combinations for fields and methods in classfiles. src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java line 2268: > 2266: > 2267: if (Integer.bitCount(rawFlags & (PUBLIC | PRIVATE | PROTECTED)) > 1) > 2268: throw badClassFile("illegal.flag.combo", String.format("0x%04x", (int)rawFlags), "method", m); instead of: `String.format("0x%04x", (int)rawFlags)`, you could use method `com.sun.tools.javac.code.Flags::toString` which prints a string representation of the flags passed to it ------------- PR: https://git.openjdk.org/jdk/pull/10826 From vromero at openjdk.org Wed Jan 4 03:24:52 2023 From: vromero at openjdk.org (Vicente Romero) Date: Wed, 4 Jan 2023 03:24:52 GMT Subject: RFR: 8155259: Suspicious buffer allocation in com.sun.tools.javac.file.BaseFileManager [v3] In-Reply-To: <4ACny_Pa1V2gwf0xo1lXQTpgYDD_A9JtVHkH16NMuzA=.aa79f43a-46fb-4ab4-b14a-020340684282@github.com> References: <4ACny_Pa1V2gwf0xo1lXQTpgYDD_A9JtVHkH16NMuzA=.aa79f43a-46fb-4ab4-b14a-020340684282@github.com> Message-ID: On Mon, 19 Dec 2022 15:44:53 GMT, Archie L. Cobbs wrote: >> JDK-8155259 notes that in `BaseFileManager` this code: >> >> ByteBuffer.allocate(capacity + capacity>>1) >> >> is actually equivalent (assuming no overflow) to: >> >> ByteBuffer.allocate(capacity) >> >> because in Java the `+` operator has higher precedence than the `>>` operator. >> >> In the bug it is suggested that this be changed to reflect the presumed original intent to over-allocate by 50%, i.e.: >> >> ByteBuffer.allocate(capacity + (capacity>>1)) >> >> however, this patch is more conservative in that it leaves the existing behavior alone and instead just simplifies it to: >> >> ByteBuffer.allocate(capacity) >> >> allowing us to at least resolve JDK-8155259. > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision: > > - Merge branch 'master' into JDK-8155259 > - Merge branch 'master' into JDK-8155259 > - 8155259: Suspicious buffer allocation in com.sun.tools.javac.file.BaseFileManager looks good ------------- Marked as reviewed by vromero (Reviewer). PR: https://git.openjdk.org/jdk/pull/10803 From vromero at openjdk.org Wed Jan 4 04:21:52 2023 From: vromero at openjdk.org (Vicente Romero) Date: Wed, 4 Jan 2023 04:21:52 GMT Subject: RFR: 8064931: tools/javac/scope/DupUnsharedTest.java needs to be updated to add the bug id [v3] In-Reply-To: References: Message-ID: On Mon, 19 Dec 2022 15:44:43 GMT, Archie L. Cobbs wrote: >> 8064931: tools/javac/scope/DupUnsharedTest.java needs to be updated to add the bug id > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision: > > - Merge branch 'master' into JDK-8064931 > - Merge branch 'master' into JDK-8064931 > - Add missing @bug tag to unit test. looks good ------------- Marked as reviewed by vromero (Reviewer). PR: https://git.openjdk.org/jdk/pull/10777 From vromero at openjdk.org Wed Jan 4 15:40:56 2023 From: vromero at openjdk.org (Vicente Romero) Date: Wed, 4 Jan 2023 15:40:56 GMT Subject: RFR: 8200610: Compiling fails with java.nio.file.ReadOnlyFileSystemException [v3] In-Reply-To: References: Message-ID: On Mon, 12 Dec 2022 16:14:20 GMT, Archie L. Cobbs wrote: >> Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: >> >> - Merge branch 'master' into JDK-8200610 >> - Address review items (add UncheckedIOException and reformat). >> - Merge branch 'master' into JDK-8200610 >> - Catch and report some java.nio.file.* exceptions along with IOException. > > Thanks! hi @archiecobbs, it seems like you need to issue the `/integrate` command again for this one. Thanks ------------- PR: https://git.openjdk.org/jdk/pull/10818 From duke at openjdk.org Wed Jan 4 15:59:54 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 4 Jan 2023 15:59:54 GMT Subject: RFR: 8219810: javac throws NullPointerException [v4] In-Reply-To: References: Message-ID: > JVMS 4.5 states: > >> Each field of a class may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS ?8.3.1), and must not have both its ACC_FINAL and ACC_VOLATILE flags set (JLS ?8.3.1.4). > > and JVMS 4.6 states: > >> Each method of a class may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS ?8.4.3). > > However, when reading class files these illegal combinations are not actually checked, and this can lead to compiler crashes as in the bug example. > > This patch adds checks for these illegal combinations. Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Use Flags.toString() to stringify flag bits. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/10826/files - new: https://git.openjdk.org/jdk/pull/10826/files/94cb9924..90aebcd5 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=10826&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=10826&range=02-03 Stats: 4 lines in 3 files changed: 0 ins; 0 del; 4 mod Patch: https://git.openjdk.org/jdk/pull/10826.diff Fetch: git fetch https://git.openjdk.org/jdk pull/10826/head:pull/10826 PR: https://git.openjdk.org/jdk/pull/10826 From duke at openjdk.org Wed Jan 4 16:00:00 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 4 Jan 2023 16:00:00 GMT Subject: RFR: 8219810: javac throws NullPointerException [v3] In-Reply-To: References: Message-ID: On Tue, 3 Jan 2023 21:19:05 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: >> >> - Merge branch 'master' into JDK-8219810 >> - Merge branch 'master' into JDK-8219810 >> - Also disallow field access flags from having both FINAL and VOLATILE. >> - Detect invalid access flag combinations for fields and methods in classfiles. > > src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java line 2268: > >> 2266: >> 2267: if (Integer.bitCount(rawFlags & (PUBLIC | PRIVATE | PROTECTED)) > 1) >> 2268: throw badClassFile("illegal.flag.combo", String.format("0x%04x", (int)rawFlags), "method", m); > > instead of: `String.format("0x%04x", (int)rawFlags)`, you could use method `com.sun.tools.javac.code.Flags::toString` which generates a string representation of the flags passed to it Great idea - thanks. ------------- PR: https://git.openjdk.org/jdk/pull/10826 From duke at openjdk.org Wed Jan 4 16:01:52 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 4 Jan 2023 16:01:52 GMT Subject: RFR: 8200610: Compiling fails with java.nio.file.ReadOnlyFileSystemException [v4] In-Reply-To: References: Message-ID: <4laXViDbKyMKq28-4VvhPxSnwwc7V-RpDq_kE9Vs5UU=.405d9f09-867d-428e-9a07-583893a7e3bd@github.com> On Mon, 19 Dec 2022 15:48:34 GMT, Archie L. Cobbs wrote: >> In `JavaCompiler`, when trying to write a class file, if an `IOException`s is thrown, instead of crashing, we report a normal error" `error while writing [file]: ...`. >> >> However there are some I/O errors that can generate `RuntimeException`s not caught by this logic. So instead these errors cause a compiler crash. >> >> An example is given in JDK-8200610, where the compiler tries to write into a ZIP file system and a `java.nio.file.ReadOnlyFileSystemException` is thrown. >> >> This patch adds that exception and a couple of others which (in my estimation) could reasonably be expected to be thrown in various obscure cases involving alternative file systems: `FileSystemNotFoundException` and `InvalidPathException`. >> >> Any suggestions on what the most appropriate list of exception types to include here are appreciated. > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains five additional commits since the last revision: > > - Merge branch 'master' into JDK-8200610 > - Merge branch 'master' into JDK-8200610 > - Address review items (add UncheckedIOException and reformat). > - Merge branch 'master' into JDK-8200610 > - Catch and report some java.nio.file.* exceptions along with IOException. Bleh, Mr. Bot is going in circles. Now it says you have to `/sponsor` again.... ------------- PR: https://git.openjdk.org/jdk/pull/10818 From duke at openjdk.org Wed Jan 4 16:03:58 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 4 Jan 2023 16:03:58 GMT Subject: Integrated: 8064931: tools/javac/scope/DupUnsharedTest.java needs to be updated to add the bug id In-Reply-To: References: Message-ID: On Thu, 20 Oct 2022 01:47:43 GMT, Archie L. Cobbs wrote: > 8064931: tools/javac/scope/DupUnsharedTest.java needs to be updated to add the bug id This pull request has now been integrated. Changeset: 4c0f24ef Author: Archie L. Cobbs Committer: Vicente Romero URL: https://git.openjdk.org/jdk/commit/4c0f24ef7108c889afdd4443d07e58c1798633cc Stats: 1 line in 1 file changed: 1 ins; 0 del; 0 mod 8064931: tools/javac/scope/DupUnsharedTest.java needs to be updated to add the bug id Reviewed-by: vromero ------------- PR: https://git.openjdk.org/jdk/pull/10777 From duke at openjdk.org Wed Jan 4 16:05:00 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 4 Jan 2023 16:05:00 GMT Subject: Integrated: 8155259: Suspicious buffer allocation in com.sun.tools.javac.file.BaseFileManager In-Reply-To: References: Message-ID: On Thu, 20 Oct 2022 20:15:12 GMT, Archie L. Cobbs wrote: > JDK-8155259 notes that in `BaseFileManager` this code: > > ByteBuffer.allocate(capacity + capacity>>1) > > is actually equivalent (assuming no overflow) to: > > ByteBuffer.allocate(capacity) > > because in Java the `+` operator has higher precedence than the `>>` operator. > > In the bug it is suggested that this be changed to reflect the presumed original intent to over-allocate by 50%, i.e.: > > ByteBuffer.allocate(capacity + (capacity>>1)) > > however, this patch is more conservative in that it leaves the existing behavior alone and instead just simplifies it to: > > ByteBuffer.allocate(capacity) > > allowing us to at least resolve JDK-8155259. This pull request has now been integrated. Changeset: 6a07fd0e Author: Archie L. Cobbs Committer: Vicente Romero URL: https://git.openjdk.org/jdk/commit/6a07fd0ec1e6b57ffff852bcdc4f3304ac828018 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod 8155259: Suspicious buffer allocation in com.sun.tools.javac.file.BaseFileManager 8172106: javac throws exception when compiling source file of size 1.5G Reviewed-by: vromero ------------- PR: https://git.openjdk.org/jdk/pull/10803 From vromero at openjdk.org Wed Jan 4 17:29:51 2023 From: vromero at openjdk.org (Vicente Romero) Date: Wed, 4 Jan 2023 17:29:51 GMT Subject: RFR: 8219810: javac throws NullPointerException [v4] In-Reply-To: References: Message-ID: On Wed, 4 Jan 2023 15:59:54 GMT, Archie L. Cobbs wrote: >> JVMS 4.5 states: >> >>> Each field of a class may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS ?8.3.1), and must not have both its ACC_FINAL and ACC_VOLATILE flags set (JLS ?8.3.1.4). >> >> and JVMS 4.6 states: >> >>> Each method of a class may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS ?8.4.3). >> >> However, when reading class files these illegal combinations are not actually checked, and this can lead to compiler crashes as in the bug example. >> >> This patch adds checks for these illegal combinations. > > Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: > > Use Flags.toString() to stringify flag bits. lgtm ------------- Marked as reviewed by vromero (Reviewer). PR: https://git.openjdk.org/jdk/pull/10826 From vromero at openjdk.org Wed Jan 4 17:31:52 2023 From: vromero at openjdk.org (Vicente Romero) Date: Wed, 4 Jan 2023 17:31:52 GMT Subject: RFR: 8200610: Compiling fails with java.nio.file.ReadOnlyFileSystemException [v4] In-Reply-To: <4laXViDbKyMKq28-4VvhPxSnwwc7V-RpDq_kE9Vs5UU=.405d9f09-867d-428e-9a07-583893a7e3bd@github.com> References: <4laXViDbKyMKq28-4VvhPxSnwwc7V-RpDq_kE9Vs5UU=.405d9f09-867d-428e-9a07-583893a7e3bd@github.com> Message-ID: <_lWpPzso_4uMJX4JDgwM-m0Pxw7q20imYdus7f2qbRg=.b9f1daf1-3808-453f-ac3b-5fa92ec18df2@github.com> On Wed, 4 Jan 2023 15:58:58 GMT, Archie L. Cobbs wrote: > Bleh, Mr. Bot is going in circles. Now it says you have to `/sponsor` again.... yep :( saw that too, let's wait ------------- PR: https://git.openjdk.org/jdk/pull/10818 From duke at openjdk.org Wed Jan 4 17:35:55 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 4 Jan 2023 17:35:55 GMT Subject: Integrated: 8200610: Compiling fails with java.nio.file.ReadOnlyFileSystemException In-Reply-To: References: Message-ID: <7SS294m0RH1Kew1b1qMgxt05RCgBy_Wp9cCv4to4sL8=.f66b06b0-841b-41fa-b927-b4b870a28333@github.com> On Fri, 21 Oct 2022 15:33:22 GMT, Archie L. Cobbs wrote: > In `JavaCompiler`, when trying to write a class file, if an `IOException`s is thrown, instead of crashing, we report a normal error" `error while writing [file]: ...`. > > However there are some I/O errors that can generate `RuntimeException`s not caught by this logic. So instead these errors cause a compiler crash. > > An example is given in JDK-8200610, where the compiler tries to write into a ZIP file system and a `java.nio.file.ReadOnlyFileSystemException` is thrown. > > This patch adds that exception and a couple of others which (in my estimation) could reasonably be expected to be thrown in various obscure cases involving alternative file systems: `FileSystemNotFoundException` and `InvalidPathException`. > > Any suggestions on what the most appropriate list of exception types to include here are appreciated. This pull request has now been integrated. Changeset: b9758d22 Author: Archie L. Cobbs Committer: Vicente Romero URL: https://git.openjdk.org/jdk/commit/b9758d2201655cecfdda48660e77c598c52fcd9b Stats: 8 lines in 1 file changed: 7 ins; 0 del; 1 mod 8200610: Compiling fails with java.nio.file.ReadOnlyFileSystemException Reviewed-by: vromero ------------- PR: https://git.openjdk.org/jdk/pull/10818 From duke at openjdk.org Wed Jan 4 17:53:58 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 4 Jan 2023 17:53:58 GMT Subject: Integrated: 8219810: javac throws NullPointerException In-Reply-To: References: Message-ID: On Fri, 21 Oct 2022 22:30:27 GMT, Archie L. Cobbs wrote: > JVMS 4.5 states: > >> Each field of a class may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS ?8.3.1), and must not have both its ACC_FINAL and ACC_VOLATILE flags set (JLS ?8.3.1.4). > > and JVMS 4.6 states: > >> Each method of a class may have at most one of its ACC_PUBLIC, ACC_PRIVATE, and ACC_PROTECTED flags set (JLS ?8.4.3). > > However, when reading class files these illegal combinations are not actually checked, and this can lead to compiler crashes as in the bug example. > > This patch adds checks for these illegal combinations. This pull request has now been integrated. Changeset: 44be5edf Author: Archie L. Cobbs Committer: Vicente Romero URL: https://git.openjdk.org/jdk/commit/44be5edf5aa661169c665aa9386e5930a3632524 Stats: 194 lines in 9 files changed: 192 ins; 0 del; 2 mod 8219810: javac throws NullPointerException Reviewed-by: vromero ------------- PR: https://git.openjdk.org/jdk/pull/10826 From prappo at openjdk.org Wed Jan 4 18:25:04 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Wed, 4 Jan 2023 18:25:04 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Thu, 15 Dec 2022 23:47:45 GMT, Jonathan Gibbons wrote: > Support for Markdown comments in the standard doclet. > > To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. > > The work is in 3 parts: > > 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. > 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. > 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. > > There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. This is a welcome change and impressive work! My initial comments are inline. src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java line 158: > 156: /** > 157: * Used for instances of {@link MarkdownTree} > 158: * representing a fragment of Markdown code. _Markdown code_: is there a better term for a run/span/block of Markdown? Here and elsewhere in this PR, _Markdown code_ reads slightly weird and misleading. src/jdk.compiler/share/classes/com/sun/source/doctree/InheritDocTree.java line 31: > 29: * A tree node for an {@code @inheritDoc} inline tag. > 30: * > 31: * @apiNote 1. Consider wrapping that long line. 2. While it's good to have that fact noted here, it's more important to note it in "Documentation Comment Specification for the Standard Doclet". src/jdk.compiler/share/classes/com/sun/source/doctree/MarkdownTree.java line 2: > 1: /* > 2: * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. 2011? src/jdk.compiler/share/classes/com/sun/source/doctree/MarkdownTree.java line 34: > 32: * The code may contain plain text, entities and HTML elements, > 33: * all represented directly in the text of the code, > 34: * but not {@linkplain InlineTagTree inline tags}. IIUC, constructs represented by `BlockTagTree` are also NOT contained by this kind of node, right? src/jdk.compiler/share/classes/com/sun/source/doctree/package-info.java line 30: > 28: * trees (AST). > 29: * > 30: *

Markdown

Consider updating the copyright years in this file. src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java line 214: > 212: for (DocTree node : nodes) { > 213: Boolean b = scan(node, ignore); > 214: if (b != null && b.equals(Boolean.TRUE)) { Could it be `b == Boolean.TRUE`? src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java line 668: > 666: print(" "); > 667: print(content); > 668: } This seems unrelated to this PR. src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java line 550: > 548: switch (dt.getKind()) { > 549: case RETURN, > 550: SUMMARY -> Indent. src/jdk.javadoc/share/classes/jdk/internal/org/commonmark/internal/inline/AsteriskDelimiterProcessor.java line 1: > 1: package jdk.internal.org.commonmark.internal.inline; 1. Does this and the other CommonMark files in this PR require any copyright header? 2. Does it make sense to add a link to the place from where the (CommonMark) snapshot was taken? If it's a VCS, maybe include a revision/hash for future maintainers and archaeologists. src/jdk.javadoc/share/classes/jdk/internal/org/commonmark/internal/util/Html5Entities.java line 15: > 13: > 14: private static final Map NAMED_CHARACTER_REFERENCES = readEntities(); > 15: private static final String ENTITY_PATH = "/org/commonmark/internal/util/entities.properties"; This properties file is missing from this PR. If you add a test with an md- doc comment that has entities (e.g. `&`), the test will crash. src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java line 1248: > 1246: } > 1247: > 1248: private class MarkdownHandler { Changes in this file seem to be the meat of the mechanism whereby Markdown-JavaDoc-HTML soup is handled. The mechanics looks good. src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java line 1249: > 1247: > 1248: private class MarkdownHandler { > 1249: private static final char FFFC = '\uFFFC'; // Unicode Object Replacement Character Can we use a better name for the FFFC constant? PLACEHOLDER or some such. src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java line 1281: > 1279: Node document = parser.parse(markdownInput.toString()); > 1280: HtmlRenderer renderer = HtmlRenderer.builder().build(); > 1281: String markdownOutput = renderer.render(document); Curious how heavyweight the parser and renderer are; should we cache them for reuse? test/langtools/jdk/javadoc/doclet/testMarkdown/TestMarkdown.java line 42: > 40: > 41: public static void main(String... args) throws Exception { > 42: TestMarkdown tester = new TestMarkdown(); Consider `var tester` in the spirit of your recent cleanup PR (#11746). test/langtools/jdk/javadoc/doclet/testMarkdown/TestMarkdown.java line 211: > 209: /**md > 210: * Markdown comment. > 211: * @throws {@inheritDoc} That `{@inheritDoc}` is ineffective because the enclosing `@throws` is invalid: `@throws` must provide an exception name. There's probably a warning or an error masked by `-Xdoclint:none` (BTW, it might be a good idea to turn on DocLint and assert exit code in each of these tests). That exception description is inherited only because the exception is mentioned in the `throws` clause. test/langtools/jdk/javadoc/doclet/testMarkdown/TestMarkdown.java line 248: > 246: /** > 247: * Plain comment. > 248: * @throws {@inheritDoc} Similar comment to that one above. test/langtools/jdk/javadoc/doclet/testMarkdown/TestMarkdown.java line 285: > 283: /**md > 284: * Markdown comment. > 285: * @throws {@inheritDoc} Ditto. test/langtools/tools/javac/doctree/MarkdownTest.java line 2: > 1: /* > 2: * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. Copyright years seem strange. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Wed Jan 4 18:40:54 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Wed, 4 Jan 2023 18:40:54 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Wed, 4 Jan 2023 18:21:48 GMT, Pavel Rappo wrote: > This is a welcome change and impressive work! My initial comments are inline. Thanks; I think of it as the icing on the cake of the technical-debt cleanup we have been doing over the past few releases. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From prappo at openjdk.org Wed Jan 4 18:40:56 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Wed, 4 Jan 2023 18:40:56 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Tue, 3 Jan 2023 20:01:48 GMT, Pavel Rappo wrote: >> Support for Markdown comments in the standard doclet. >> >> To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. >> >> The work is in 3 parts: >> >> 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. >> 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. >> 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. >> >> There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. > > src/jdk.compiler/share/classes/com/sun/source/doctree/InheritDocTree.java line 31: > >> 29: * A tree node for an {@code @inheritDoc} inline tag. >> 30: * >> 31: * @apiNote > > 1. Consider wrapping that long line. > 2. While it's good to have that fact noted here, it's more important to note it in "Documentation Comment Specification for the Standard Doclet". Ah, I can see that you added such a note before in CSR (sorry for the noise): +_Note:_ When using [Markdown comments](#markdown-content), there is no requirement +that the comment containing the tag and the comment containing the inherited documentation +should either be both Markdown comments or both normal (not Markdown) comments. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Wed Jan 4 18:46:52 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Wed, 4 Jan 2023 18:46:52 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Tue, 3 Jan 2023 21:20:20 GMT, Pavel Rappo wrote: >> Support for Markdown comments in the standard doclet. >> >> To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. >> >> The work is in 3 parts: >> >> 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. >> 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. >> 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. >> >> There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. > > src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java line 214: > >> 212: for (DocTree node : nodes) { >> 213: Boolean b = scan(node, ignore); >> 214: if (b != null && b.equals(Boolean.TRUE)) { > > Could it be `b == Boolean.TRUE`? In general, no, because of the possibility of `new Boolean` so it will depend on the code in `scan`. I'll investigate. > src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java line 1249: > >> 1247: >> 1248: private class MarkdownHandler { >> 1249: private static final char FFFC = '\uFFFC'; // Unicode Object Replacement Character > > Can we use a better name for the FFFC constant? PLACEHOLDER or some such. Sure. At least I took the first step and avoided repeated use of the character constant ;-) > src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java line 1281: > >> 1279: Node document = parser.parse(markdownInput.toString()); >> 1280: HtmlRenderer renderer = HtmlRenderer.builder().build(); >> 1281: String markdownOutput = renderer.render(document); > > Curious how heavyweight the parser and renderer are; should we cache them for reuse? Seems like a good idea if all works as might be expected. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Wed Jan 4 19:52:50 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Wed, 4 Jan 2023 19:52:50 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Tue, 3 Jan 2023 19:56:51 GMT, Pavel Rappo wrote: >> Support for Markdown comments in the standard doclet. >> >> To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. >> >> The work is in 3 parts: >> >> 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. >> 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. >> 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. >> >> There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. > > src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java line 158: > >> 156: /** >> 157: * Used for instances of {@link MarkdownTree} >> 158: * representing a fragment of Markdown code. > > _Markdown code_: is there a better term for a run/span/block of Markdown? Here and elsewhere in this PR, _Markdown code_ reads slightly weird and misleading. I agree it is not great. For some reason, I wanted to stay clear of *Markdown text* as being a source of confusion for the plain non-markup content in a String containing Markdown content. I'll look at the Markdown/CommonMark spec for any precedent. Failing that, I will at least try and ensure the terminology that we use is consistent. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Wed Jan 4 20:08:53 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Wed, 4 Jan 2023 20:08:53 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Wed, 4 Jan 2023 19:50:01 GMT, Jonathan Gibbons wrote: >> src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java line 158: >> >>> 156: /** >>> 157: * Used for instances of {@link MarkdownTree} >>> 158: * representing a fragment of Markdown code. >> >> _Markdown code_: is there a better term for a run/span/block of Markdown? Here and elsewhere in this PR, _Markdown code_ reads slightly weird and misleading. > > I agree it is not great. For some reason, I wanted to stay clear of *Markdown text* as being a source of confusion for the plain non-markup content in a String containing Markdown content. > > I'll look at the Markdown/CommonMark spec for any precedent. Failing that, I will at least try and ensure the terminology that we use is consistent. A quick simplistic scan of the CommonMark spec reveals no clear winner. 2 Markdown and 1 Markdown code 1 Markdown content 1 Markdown counts 1 Markdown document 2 Markdown documents 2 Markdown from 1 Markdown have 5 Markdown implementations 1 Markdown inline 2 Markdown is 1 Markdown meanings 1 Markdown paragraph 1 Markdown practice 1 Markdown program 1 Markdown spec 1 Markdown started 6 Markdown syntax 1 Markdown to 1 Markdown treats 1 Markdown version 1 Markdown will 1 Markdown with Of these, `content`, `document` and `program` seem the most applicable. * `content` has the potential for confusion with the `javadoc` `Content` class ... but we already cope with `Element` and `Tag` by leveraging qualifying adjectives. * `document` seems to imply a file full of content, and not the content of (part of) a doc comment * `program` seems too geeky. Of the choices, `content` seems most reasonable. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From prappo at openjdk.org Wed Jan 4 20:08:55 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Wed, 4 Jan 2023 20:08:55 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Wed, 4 Jan 2023 18:42:08 GMT, Jonathan Gibbons wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java line 214: >> >>> 212: for (DocTree node : nodes) { >>> 213: Boolean b = scan(node, ignore); >>> 214: if (b != null && b.equals(Boolean.TRUE)) { >> >> Could it be `b == Boolean.TRUE`? > > In general, no, because of the possibility of `new Boolean` so it will depend on the code in `scan`. I'll investigate. You are correct. I keep forgetting about those now-deprecated-for-removal constructors for `java.lang.Boolean`. What you have now is good. Alternatively, you could use `Boolean.TRUE.equals(b)`, a Yoda condition, which you might or might not find aesthetically pleasing. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From prappo at openjdk.org Wed Jan 4 20:35:52 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Wed, 4 Jan 2023 20:35:52 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Wed, 4 Jan 2023 20:06:17 GMT, Jonathan Gibbons wrote: >> I agree it is not great. For some reason, I wanted to stay clear of *Markdown text* as being a source of confusion for the plain non-markup content in a String containing Markdown content. >> >> I'll look at the Markdown/CommonMark spec for any precedent. Failing that, I will at least try and ensure the terminology that we use is consistent. > > A quick simplistic scan of the CommonMark spec reveals no clear winner. > > > 2 Markdown and > 1 Markdown code > 1 Markdown content > 1 Markdown counts > 1 Markdown document > 2 Markdown documents > 2 Markdown from > 1 Markdown have > 5 Markdown implementations > 1 Markdown inline > 2 Markdown is > 1 Markdown meanings > 1 Markdown paragraph > 1 Markdown practice > 1 Markdown program > 1 Markdown spec > 1 Markdown started > 6 Markdown syntax > 1 Markdown to > 1 Markdown treats > 1 Markdown version > 1 Markdown will > 1 Markdown with > > > Of these, `content`, `document` and `program` seem the most applicable. > > * `content` has the potential for confusion with the `javadoc` `Content` class ... but we already cope with `Element` and `Tag` by leveraging qualifying adjectives. > * `document` seems to imply a file full of content, and not the content of (part of) a doc comment > * `program` seems too geeky. > > Of the choices, `content` seems most reasonable. Could it be just _Markdown_ similarly to how it's usually just HTML? ------------- PR: https://git.openjdk.org/jdk/pull/11701 From prappo at openjdk.org Wed Jan 4 22:07:48 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Wed, 4 Jan 2023 22:07:48 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Thu, 15 Dec 2022 23:47:45 GMT, Jonathan Gibbons wrote: > Support for Markdown comments in the standard doclet. > > To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. > > The work is in 3 parts: > > 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. > 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. > 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. > > There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. In case you've missed test failures in your GitHub Actions (GHA): `test/langtools/tools/javac/lib/DPrinter.java`. A trivial fix, really. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From prappo at openjdk.org Thu Jan 5 10:40:51 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Thu, 5 Jan 2023 10:40:51 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Thu, 15 Dec 2022 23:47:45 GMT, Jonathan Gibbons wrote: > Support for Markdown comments in the standard doclet. > > To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. > > The work is in 3 parts: > > 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. > 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. > 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. > > There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java line 218: > 216: * @since 21 > 217: */ > 218: R visitMarkdown(MarkdownTree node, P p); This is supposed to be a `default` method, right? ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Thu Jan 5 16:45:49 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Thu, 5 Jan 2023 16:45:49 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Wed, 4 Jan 2023 20:32:54 GMT, Pavel Rappo wrote: >> A quick simplistic scan of the CommonMark spec reveals no clear winner. >> >> >> 2 Markdown and >> 1 Markdown code >> 1 Markdown content >> 1 Markdown counts >> 1 Markdown document >> 2 Markdown documents >> 2 Markdown from >> 1 Markdown have >> 5 Markdown implementations >> 1 Markdown inline >> 2 Markdown is >> 1 Markdown meanings >> 1 Markdown paragraph >> 1 Markdown practice >> 1 Markdown program >> 1 Markdown spec >> 1 Markdown started >> 6 Markdown syntax >> 1 Markdown to >> 1 Markdown treats >> 1 Markdown version >> 1 Markdown will >> 1 Markdown with >> >> >> Of these, `content`, `document` and `program` seem the most applicable. >> >> * `content` has the potential for confusion with the `javadoc` `Content` class ... but we already cope with `Element` and `Tag` by leveraging qualifying adjectives. >> * `document` seems to imply a file full of content, and not the content of (part of) a doc comment >> * `program` seems too geeky. >> >> Of the choices, `content` seems most reasonable. > > Could it be just _Markdown_ similarly to how it's usually just HTML? Prefer not. As a noun, I think Markdown refers to the abstract form. In these cases, we're looking for a noun that describes the concrete form (string, content, etc) with Markdown being an adjective to qualify the form. That being said, I will examine the use of the phrase on a case-by-case basis. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From prappo at openjdk.org Thu Jan 5 16:55:51 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Thu, 5 Jan 2023 16:55:51 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Wed, 4 Jan 2023 15:29:33 GMT, Pavel Rappo wrote: >> Support for Markdown comments in the standard doclet. >> >> To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. >> >> The work is in 3 parts: >> >> 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. >> 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. >> 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. >> >> There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. > > src/jdk.compiler/share/classes/com/sun/source/doctree/MarkdownTree.java line 34: > >> 32: * The code may contain plain text, entities and HTML elements, >> 33: * all represented directly in the text of the code, >> 34: * but not {@linkplain InlineTagTree inline tags}. > > IIUC, constructs represented by `BlockTagTree` are also NOT contained by this kind of node, right? The fact that `MarkdownTree` is a terminal node and cannot be decomposed to constituent `DocTree`s is understood from its interface: the sole method of `MarkdownTree` returns `String`. It seems to me that that doc comment aims to convey that `MarkdownTree` never contains character input that belongs to `DocTree` of any other kind, such as `InlineTagTree`, or `BlockTagTree`. If so, then we should rephrase that part of the doc comment for clarity. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From alanb at openjdk.org Thu Jan 5 17:13:51 2023 From: alanb at openjdk.org (Alan Bateman) Date: Thu, 5 Jan 2023 17:13:51 GMT Subject: RFR: JDK-8298405: Markdown support in the standard doclet In-Reply-To: References: Message-ID: On Thu, 15 Dec 2022 23:47:45 GMT, Jonathan Gibbons wrote: > Support for Markdown comments in the standard doclet. > > To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. > > The work is in 3 parts: > > 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. > 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. > 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. > > There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. This seems a significant feature with several design choices that probably should be captured somewhere. Is is significant enough to have a JEP? ------------- PR: https://git.openjdk.org/jdk/pull/11701 From vromero at openjdk.org Thu Jan 5 18:17:53 2023 From: vromero at openjdk.org (Vicente Romero) Date: Thu, 5 Jan 2023 18:17:53 GMT Subject: RFR: 8163229: test test/tools/javac/CaptureInSubtype.java has a main method that is never executed Export [v3] In-Reply-To: References: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> Message-ID: On Mon, 19 Dec 2022 15:44:08 GMT, Archie L. Cobbs wrote: >> This PR deals with some housekeeping relating to compiler unit tests. >> >> JDK-8163229 points out that there are several tests that have a `public static void main(String[])` method, but because the test expects to fail during compilation, the test is never actually run, and so these `main` methods are just clutter that can be removed. >> >> However, there are also some tests where the test is never run, but the `main()` method generates one or more of the expected compilation errors. Obviously we need to keep those, but they don't need to be declared as `public static void main(String[])` which is misleading. So instead we rename these methods to `meth()`, and also we remove the `String[]` parameter when it's not needed by the test. > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains three commits: > > - Merge branch 'master' into JDK-8163229 > - Merge branch 'master' into JDK-8163229 > - Rename or remove "main()" methods in tests that never actually run. test/langtools/tools/javac/4980495/static/Test.java line 14: > 12: public class Test { > 13: > 14: public static void meth() { not sure about this case, but if a method doesn't need to be `static` we should remove the modifier, consider removing `public` too if not needed ------------- PR: https://git.openjdk.org/jdk/pull/10992 From duke at openjdk.org Thu Jan 5 18:31:52 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 5 Jan 2023 18:31:52 GMT Subject: RFR: 8163229: test test/tools/javac/CaptureInSubtype.java has a main method that is never executed Export [v3] In-Reply-To: References: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> Message-ID: On Thu, 5 Jan 2023 18:13:15 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains three commits: >> >> - Merge branch 'master' into JDK-8163229 >> - Merge branch 'master' into JDK-8163229 >> - Rename or remove "main()" methods in tests that never actually run. > > test/langtools/tools/javac/4980495/static/Test.java line 14: > >> 12: public class Test { >> 13: >> 14: public static void meth() { > > not sure about this case, but if a method doesn't need to be `static` we should remove the modifier, consider removing `public` too if not needed Yes - in fact, at first I started doing that as well, but it turns out that doing this wholesale generates a bunch of test failures, and therefore requires a good bit more analysis to figure out which tests can handle it and which can't. The primary goal here is to remove misleading `public static void main(String[])` methods, not minimize in general. Perhaps more a general test minimization effort could be relegated to "phase 2", i.e., another bug? ------------- PR: https://git.openjdk.org/jdk/pull/10992 From vromero at openjdk.org Thu Jan 5 19:03:54 2023 From: vromero at openjdk.org (Vicente Romero) Date: Thu, 5 Jan 2023 19:03:54 GMT Subject: RFR: 8163229: test test/tools/javac/CaptureInSubtype.java has a main method that is never executed Export [v3] In-Reply-To: References: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> Message-ID: <-utAokEy0vxcRYCzFmjTwN6D4ML9DlqJvEVz5trgo3w=.d8c24349-4f4d-4c92-980e-56e192924051@github.com> On Thu, 5 Jan 2023 18:29:31 GMT, Archie L. Cobbs wrote: >> test/langtools/tools/javac/4980495/static/Test.java line 14: >> >>> 12: public class Test { >>> 13: >>> 14: public static void meth() { >> >> not sure about this case, but if a method doesn't need to be `static` we should remove the modifier, consider removing `public` too if not needed > > Yes - in fact, at first I started doing that as well, but it turns out that doing this wholesale generates a bunch of test failures, and therefore requires a good bit more analysis to figure out which tests can handle it and which can't. The primary goal here is to remove misleading `public static void main(String[])` methods, not minimize in general. Perhaps more a general test minimization effort could be relegated to "phase 2", i.e., another bug? sure I'm OK with that ------------- PR: https://git.openjdk.org/jdk/pull/10992 From vromero at openjdk.org Thu Jan 5 20:05:58 2023 From: vromero at openjdk.org (Vicente Romero) Date: Thu, 5 Jan 2023 20:05:58 GMT Subject: RFR: 8163229: test test/tools/javac/CaptureInSubtype.java has a main method that is never executed Export [v3] In-Reply-To: References: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> Message-ID: On Mon, 19 Dec 2022 15:44:08 GMT, Archie L. Cobbs wrote: >> This PR deals with some housekeeping relating to compiler unit tests. >> >> JDK-8163229 points out that there are several tests that have a `public static void main(String[])` method, but because the test expects to fail during compilation, the test is never actually run, and so these `main` methods are just clutter that can be removed. >> >> However, there are also some tests where the test is never run, but the `main()` method generates one or more of the expected compilation errors. Obviously we need to keep those, but they don't need to be declared as `public static void main(String[])` which is misleading. So instead we rename these methods to `meth()`, and also we remove the `String[]` parameter when it's not needed by the test. > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains three commits: > > - Merge branch 'master' into JDK-8163229 > - Merge branch 'master' into JDK-8163229 > - Rename or remove "main()" methods in tests that never actually run. test/langtools/tools/javac/limits/ArrayDims2.java line 35: > 33: [][][][][][][][][][] > 34: [][][][][][][][][][] > 35: [][][][][][][][][][] given that you are in the neighborhood :), the main method at: ArrayDims3.java can also be removed. Or can be done in another phase as you please ------------- PR: https://git.openjdk.org/jdk/pull/10992 From vromero at openjdk.org Thu Jan 5 20:44:02 2023 From: vromero at openjdk.org (Vicente Romero) Date: Thu, 5 Jan 2023 20:44:02 GMT Subject: RFR: 8163229: test test/tools/javac/CaptureInSubtype.java has a main method that is never executed Export [v3] In-Reply-To: References: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> Message-ID: <6UNnOkymEQb-sDbwPW_U35IvecsSltCaKjhFvfCojEI=.58f7ad21-2cde-4460-b3ff-24a5f091c8ef@github.com> On Mon, 19 Dec 2022 15:44:08 GMT, Archie L. Cobbs wrote: >> This PR deals with some housekeeping relating to compiler unit tests. >> >> JDK-8163229 points out that there are several tests that have a `public static void main(String[])` method, but because the test expects to fail during compilation, the test is never actually run, and so these `main` methods are just clutter that can be removed. >> >> However, there are also some tests where the test is never run, but the `main()` method generates one or more of the expected compilation errors. Obviously we need to keep those, but they don't need to be declared as `public static void main(String[])` which is misleading. So instead we rename these methods to `meth()`, and also we remove the `String[]` parameter when it's not needed by the test. > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains three commits: > > - Merge branch 'master' into JDK-8163229 > - Merge branch 'master' into JDK-8163229 > - Rename or remove "main()" methods in tests that never actually run. just minor suggestions, for your consideration which can be addressed as part of a follow-up bug, lgtm ------------- Marked as reviewed by vromero (Reviewer). PR: https://git.openjdk.org/jdk/pull/10992 From duke at openjdk.org Thu Jan 5 21:24:09 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 5 Jan 2023 21:24:09 GMT Subject: RFR: 8163229: test test/tools/javac/CaptureInSubtype.java has a main method that is never executed Export [v4] In-Reply-To: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> References: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> Message-ID: > This PR deals with some housekeeping relating to compiler unit tests. > > JDK-8163229 points out that there are several tests that have a `public static void main(String[])` method, but because the test expects to fail during compilation, the test is never actually run, and so these `main` methods are just clutter that can be removed. > > However, there are also some tests where the test is never run, but the `main()` method generates one or more of the expected compilation errors. Obviously we need to keep those, but they don't need to be declared as `public static void main(String[])` which is misleading. So instead we rename these methods to `meth()`, and also we remove the `String[]` parameter when it's not needed by the test. Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Remove two more unnecessary main() methods. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/10992/files - new: https://git.openjdk.org/jdk/pull/10992/files/6987fbda..501289c4 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=10992&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=10992&range=02-03 Stats: 4 lines in 2 files changed: 0 ins; 4 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/10992.diff Fetch: git fetch https://git.openjdk.org/jdk pull/10992/head:pull/10992 PR: https://git.openjdk.org/jdk/pull/10992 From duke at openjdk.org Thu Jan 5 21:24:13 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 5 Jan 2023 21:24:13 GMT Subject: RFR: 8163229: test test/tools/javac/CaptureInSubtype.java has a main method that is never executed Export [v3] In-Reply-To: References: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> Message-ID: On Thu, 5 Jan 2023 20:02:47 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains three commits: >> >> - Merge branch 'master' into JDK-8163229 >> - Merge branch 'master' into JDK-8163229 >> - Rename or remove "main()" methods in tests that never actually run. > > test/langtools/tools/javac/limits/ArrayDims2.java line 35: > >> 33: [][][][][][][][][][] >> 34: [][][][][][][][][][] >> 35: [][][][][][][][][][] > > given that you are in the neighborhood :), the main method at: ArrayDims3.java can also be removed. Or can be done in another phase, as you please Sure, no problem... and same thing for `ArrayDims1.java` it looks like. ------------- PR: https://git.openjdk.org/jdk/pull/10992 From duke at openjdk.org Fri Jan 6 02:45:18 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 6 Jan 2023 02:45:18 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor Message-ID: This PR adds a new lint warning category `this-escape`. It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) * Some constructor `B()` of `B` invokes `A()` as its superclass constructor * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. **Patch Navigation Guide** * Non-trivial compiler changes: * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` * Javadoc additions of `@implNote`: * `src/java.base/share/classes/java/io/PipedReader.java` * `src/java.base/share/classes/java/io/PipedWriter.java` * `src/java.base/share/classes/java/lang/Throwable.java` * `src/java.base/share/classes/java/util/ArrayDeque.java` * `src/java.base/share/classes/java/util/EnumMap.java` * `src/java.base/share/classes/java/util/HashSet.java` * `src/java.base/share/classes/java/util/Hashtable.java` * `src/java.base/share/classes/java/util/LinkedList.java` * `src/java.base/share/classes/java/util/TreeMap.java` * `src/java.base/share/classes/java/util/TreeSet.java` * New unit tests * `test/langtools/tools/javac/warnings/ThisEscape/*.java` * **Everything else** is just adding `@SuppressWarnings("this-escape")` ------------- Commit messages: - Remove trailing whitespace. - Some documentation tweaks. - Treat method references like the equivalent lambda. - Fix bug where initializers could generate duplicate warnings. - Javadoc fix. - Add ThisEscape.html doc note and link the new @implNote's to it. - Add more @SuppressWarnings("this-escape") annotations. - Add more @SuppressWarnings("this-escape") annotations. - Add more @SuppressWarnings("this-escape") annotations. - Add more @SuppressWarnings("this-escape") annotations. - ... and 38 more: https://git.openjdk.org/jdk/compare/c6588d5b...9c162283 Changes: https://git.openjdk.org/jdk/pull/11874/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8015831 Stats: 4326 lines in 1285 files changed: 4259 ins; 3 del; 64 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 6 03:16:50 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 6 Jan 2023 03:16:50 GMT Subject: RFR: 8163229: test test/tools/javac/CaptureInSubtype.java has a main method that is never executed Export [v4] In-Reply-To: References: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> Message-ID: On Thu, 5 Jan 2023 21:24:09 GMT, Archie L. Cobbs wrote: >> This PR deals with some housekeeping relating to compiler unit tests. >> >> JDK-8163229 points out that there are several tests that have a `public static void main(String[])` method, but because the test expects to fail during compilation, the test is never actually run, and so these `main` methods are just clutter that can be removed. >> >> However, there are also some tests where the test is never run, but the `main()` method generates one or more of the expected compilation errors. Obviously we need to keep those, but they don't need to be declared as `public static void main(String[])` which is misleading. So instead we rename these methods to `meth()`, and also we remove the `String[]` parameter when it's not needed by the test. > > Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: > > Remove two more unnecessary main() methods. looks good thanks I have updated the bug title to a more general one, now the PR title need to be synced with it. ------------- Marked as reviewed by vromero (Reviewer). PR: https://git.openjdk.org/jdk/pull/10992 From vromero at openjdk.org Fri Jan 6 03:29:52 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 6 Jan 2023 03:29:52 GMT Subject: RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v4] In-Reply-To: References: Message-ID: On Mon, 19 Dec 2022 15:44:30 GMT, Archie L. Cobbs wrote: >> This patch is both a minor optimization and a fix for JDK-7176515. >> >> JDK-7176515 relates to how javac handles `switch` statements on `Enum` values, which are effectively "syntactic sugar". >> >> The simple approach would be to just get the enum's `ordinal()` value and then revert to a normal integer value switch on that. However, this snapshots the ordinal values at compile-time, and thus can fail if the `Enum` class is recompiled later. >> >> Presumably to avoid that possibility (are there any other reasons?) the compiler instead uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. This avoids the "stale ordinal" problem of the simple approach, but it also creates a potential class initialization loop if there happens to an `Enum` switch inside an `Enum` class constructor, as demonstrated by the bug. >> >> This patch makes the following change: If we are handling an `Enum` switch, and the `Enum` class we are switching on is also the class we are compiling, then just go with the simple approach, because the "stale ordinal" problem can't happen in this case so there's no need to build a runtime lookup table. >> >> This results in two improvements: >> * It avoids building the lookup table for switches on self >> * It fixes JDK-7176515 as stated >> >> Although the reproducing test case provided in JDK-7176515 gets fixed by this patch, the underlying issue is still there and can still be triggered with a slightly more complicated test case (included, but commented out). >> >> So JDK-7176515 could be left open (or a new bug created) and a separate discussion had about how to "really" fix it. >> >> Part of this discussion should be defining what that means, i.e., the boundaries of the bug. There are some scenarios that are basically impossible to fix, for example, two `Enum` classes whose constructors take as a parameter instances of the other `Enum` class and then switch on it. That cycle has nothing to do with how switches are handled. > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: > > - Merge branch 'master' into JDK-7176515 > - Merge branch 'master' into JDK-7176515 > - Give test a better name and don't rely on assertions being enabled. > - Skip enum switch lookup tables when compiling the enum switch class. lgtm ------------- Marked as reviewed by vromero (Reviewer). PR: https://git.openjdk.org/jdk/pull/10797 From vromero at openjdk.org Fri Jan 6 03:34:52 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 6 Jan 2023 03:34:52 GMT Subject: RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v4] In-Reply-To: References: Message-ID: On Mon, 19 Dec 2022 15:44:30 GMT, Archie L. Cobbs wrote: >> This patch is both a minor optimization and a fix for JDK-7176515. >> >> JDK-7176515 relates to how javac handles `switch` statements on `Enum` values, which are effectively "syntactic sugar". >> >> The simple approach would be to just get the enum's `ordinal()` value and then revert to a normal integer value switch on that. However, this snapshots the ordinal values at compile-time, and thus can fail if the `Enum` class is recompiled later. >> >> Presumably to avoid that possibility (are there any other reasons?) the compiler instead uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. This avoids the "stale ordinal" problem of the simple approach, but it also creates a potential class initialization loop if there happens to an `Enum` switch inside an `Enum` class constructor, as demonstrated by the bug. >> >> This patch makes the following change: If we are handling an `Enum` switch, and the `Enum` class we are switching on is also the class we are compiling, then just go with the simple approach, because the "stale ordinal" problem can't happen in this case so there's no need to build a runtime lookup table. >> >> This results in two improvements: >> * It avoids building the lookup table for switches on self >> * It fixes JDK-7176515 as stated >> >> Although the reproducing test case provided in JDK-7176515 gets fixed by this patch, the underlying issue is still there and can still be triggered with a slightly more complicated test case (included, but commented out). >> >> So JDK-7176515 could be left open (or a new bug created) and a separate discussion had about how to "really" fix it. >> >> Part of this discussion should be defining what that means, i.e., the boundaries of the bug. There are some scenarios that are basically impossible to fix, for example, two `Enum` classes whose constructors take as a parameter instances of the other `Enum` class and then switch on it. That cycle has nothing to do with how switches are handled. > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: > > - Merge branch 'master' into JDK-7176515 > - Merge branch 'master' into JDK-7176515 > - Give test a better name and don't rely on assertions being enabled. > - Skip enum switch lookup tables when compiling the enum switch class. I think that a follow-up JIRA issue should be filed to track the situation in which the bug can still occur ------------- PR: https://git.openjdk.org/jdk/pull/10797 From dholmes at openjdk.org Fri Jan 6 04:51:00 2023 From: dholmes at openjdk.org (David Holmes) Date: Fri, 6 Jan 2023 04:51:00 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 02:20:53 GMT, Archie L. Cobbs wrote: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Hi Archie, The associated JBS issue has been dormant for 6+ years and this is a very intrusive change affecting many, many files. Has the resurrection of this project previously been discussed somewhere? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From alanb at openjdk.org Fri Jan 6 07:53:54 2023 From: alanb at openjdk.org (Alan Bateman) Date: Fri, 6 Jan 2023 07:53:54 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 02:20:53 GMT, Archie L. Cobbs wrote: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` This looks like a very useful lint warning to have but this PR is unwieldy. If you haven't done so already then you probably should socialize on compiler-dev and get agreement on the semantics and other details. I think you will also need to separate the addition of the lint warning from the changes to the wider JDK. It might be okay to add the feature but have it disabled for the JDK build initially. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 6 14:51:54 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 6 Jan 2023 14:51:54 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 04:48:27 GMT, David Holmes wrote: > The associated JBS issue has been dormant for 6+ years and this is a very intrusive change affecting many, many files. Has the resurrection of this project previously been discussed somewhere? Hi @dholmes-ora, The work to add this warning has been guided by @briangoetz in discussions on the amber-dev mailing list. See that thread for how we came up with the current design, underlying motivation, etc. Regarding intrusiveness (assuming you're referring simply to the number of files touched), as mentioned this was one of two options. The other option would be to patch to about ~30 `Java.gmk` files in `make/modules` to exclude `this-escape` from `-Xlint` during the various module builds. Going this route is fine with me, but it has the downside that any new code being developed would not benefit from the new warning. This was in fact my original approach (and it was a lot easier :) but Brian rightly pointed out that adding `@SuppressWarnings` annotations was the the safer (i.e, more conservative) approach. > If you haven't done so already then you probably should socialize on compiler-dev and get agreement on the semantics and other details. Hi @AlanBateman, As mentioned this has been under discussion on amber-dev for a while. Happy to continue that discussion here as well. > I think you will also need to separate the addition of the lint warning from the changes to the wider JDK. It might be okay to add the feature but have it disabled for the JDK build initially. Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? If this is generally agreed as a better route then let me know and I'll update the patch. Thanks for both of your comments. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From alanb at openjdk.org Fri Jan 6 15:41:16 2023 From: alanb at openjdk.org (Alan Bateman) Date: Fri, 6 Jan 2023 15:41:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 14:49:16 GMT, Archie L. Cobbs wrote: > Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? > > If this is generally agreed as a better route then let me know and I'll update the patch. Yes, I think that would be better. It would remove most of the noise, 1200+ files, and 10+ mailing lists from this PR. I assume there will be at least some iteration on compiler-dev about the details and changes to javac. Once you get to the JDK changes then I suspect that some areas may want to fix issues rather than adding SW. Sadly, I see a few examples in your list where there have been attempts to avoid leaking "this" but where we backed away out of concern that 3rd party code was extending some class and overriding a method known to be invoked by the constructor. Also we have places that register themselves to cleaners. I suspect some of the suggestions to document leaking this in implNotes will need discussion too because they amount to documenting "hooks" that people will rely on, e.g. documenting in ArrayDeque that its constructor invokes addList could be read as an invite to override it. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Fri Jan 6 15:57:50 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 6 Jan 2023 15:57:50 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 15:38:31 GMT, Alan Bateman wrote: >>> The associated JBS issue has been dormant for 6+ years and this is a very intrusive change affecting many, many files. Has the resurrection of this project previously been discussed somewhere? >> >> Hi @dholmes-ora, >> >> The work to add this warning has been guided by @briangoetz in discussions on the amber-dev mailing list. See that thread for how we came up with the current design, underlying motivation, etc. >> >> Regarding intrusiveness (assuming you're referring simply to the number of files touched), as mentioned this was one of two options. The other option would be to patch to about ~30 `Java.gmk` files in `make/modules` to exclude `this-escape` from `-Xlint` during the various module builds. >> >> Going this route is fine with me, but it has the downside that any new code being developed would not benefit from the new warning. This was in fact my original approach (and it was a lot easier :) but Brian rightly pointed out that adding `@SuppressWarnings` annotations was the the safer (i.e, more conservative) approach. >> >>> If you haven't done so already then you probably should socialize on compiler-dev and get agreement on the semantics and other details. >> >> Hi @AlanBateman, >> >> As mentioned this has been under discussion on amber-dev for a while. Happy to continue that discussion here as well. >> >>> I think you will also need to separate the addition of the lint warning from the changes to the wider JDK. It might be okay to add the feature but have it disabled for the JDK build initially. >> >> Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? >> >> If this is generally agreed as a better route then let me know and I'll update the patch. >> >> Thanks for both of your comments. > >> Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? >> >> If this is generally agreed as a better route then let me know and I'll update the patch. > > Yes, I think that would be better. It would remove most of the noise, 1200+ files, and 10+ mailing lists from this PR. I assume there will be at least some iteration on compiler-dev about the details and changes to javac. Once you get to the JDK changes then I suspect that some areas may want to fix issues rather than adding SW. Sadly, I see a few examples in your list where there have been attempts to avoid leaking "this" but where we backed away out of concern that 3rd party code was extending some class and overriding a method known to be invoked by the constructor. Also we have places that register themselves to cleaners. I suspect some of the suggestions to document leaking this in implNotes will need discussion too because they amount to documenting "hooks" that people will rely on, e.g. documenting in ArrayDeque that its constructor invokes addList could be read as an invite to override it. I agree with @AlanBateman. When we introduced similar warnings in the past, we have enabled support in javac (with some test) in a separate PR, and then followed up with small dedicated PR for each of the various areas (enabling new warnings one by one). See this great umbrella JBS issue (created by @asotona) which has details on all the issues that were filed when we added an extra Lint warning for lossy conversions: https://bugs.openjdk.org/browse/JDK-8286374 They all refer to this: https://bugs.openjdk.org/browse/JDK-8244681 Which was submitted as a separate javac-only PR: https://github.com/openjdk/jdk/pull/8599 ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 6 17:42:57 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 6 Jan 2023 17:42:57 GMT Subject: RFR: 8043251: Bogus javac error: required: no arguments, found: no arguments [v3] In-Reply-To: References: Message-ID: On Mon, 19 Dec 2022 15:44:21 GMT, Archie L. Cobbs wrote: >> We have an error message `compiler.err.cant.apply.symbol` for cases where a method invocation doesn't resolve. It shows the "required" parameters and the "found" parameters, plus a further description of the problem. >> >> This message being used inappropriately when the problem is actually due to explicitly passed method type parameters instead of regular method parameters. >> >> For example, if you do this: >> >> Function f = Function.identity(); >> >> the error reported is this: >> >> error: method identity in interface Function cannot be applied to given types; >> Function f = Function.identity(); >> ^ >> required: no arguments >> found: no arguments >> reason: wrong number of type arguments; required 1 >> where T,R are type-variables: >> T extends Object declared in interface Function >> R extends Object declared in interface Function >> >> The real error here is `wrong number of type arguments; required 1`, but the `compiler.err.cant.apply.symbol` error message that assumes the problem is with the regular parameters, which it displays. The result is the appearance of the useless and confusing `required` and `found` lines. >> >> This patch creates an alternate version of that error message (`compiler.err.cant.apply.symbol.noargs`) that omits the `required` and `found` lines, and makes the compiler use this alternate message when the error is due to type parameters (specifically, when the underlying error is "wrong number of type arguments" or "explicit type argument X does not conform to declared bound(s)"). >> >> This improves the error for example above to this: >> >> error: method identity in interface Function cannot be applied to given types; >> Function f = Function.identity(); >> ^ >> reason: wrong number of type arguments; required 1 >> where T,R are type-variables: >> T extends Object declared in interface Function >> R extends Object declared in interface Function >> 1 error > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision: > > - Merge branch 'master' into JDK-8043251 > - Merge branch 'master' into JDK-8043251 > - Fix confusing error message regarding wrong number of type parameters. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java line 4180: > 4178: // so use the error message that omits them to avoid confusion. > 4179: switch (c.snd.getCode()) { > 4180: case "compiler.misc.wrong.number.type.args": minor indentation suggestion: I would move the statements inside of the `switch` block to the right ------------- PR: https://git.openjdk.org/jdk/pull/10799 From duke at openjdk.org Fri Jan 6 18:00:13 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 6 Jan 2023 18:00:13 GMT Subject: RFR: 8043251: Bogus javac error: required: no arguments, found: no arguments [v4] In-Reply-To: References: Message-ID: > We have an error message `compiler.err.cant.apply.symbol` for cases where a method invocation doesn't resolve. It shows the "required" parameters and the "found" parameters, plus a further description of the problem. > > This message being used inappropriately when the problem is actually due to explicitly passed method type parameters instead of regular method parameters. > > For example, if you do this: > > Function f = Function.identity(); > > the error reported is this: > > error: method identity in interface Function cannot be applied to given types; > Function f = Function.identity(); > ^ > required: no arguments > found: no arguments > reason: wrong number of type arguments; required 1 > where T,R are type-variables: > T extends Object declared in interface Function > R extends Object declared in interface Function > > The real error here is `wrong number of type arguments; required 1`, but the `compiler.err.cant.apply.symbol` error message that assumes the problem is with the regular parameters, which it displays. The result is the appearance of the useless and confusing `required` and `found` lines. > > This patch creates an alternate version of that error message (`compiler.err.cant.apply.symbol.noargs`) that omits the `required` and `found` lines, and makes the compiler use this alternate message when the error is due to type parameters (specifically, when the underlying error is "wrong number of type arguments" or "explicit type argument X does not conform to declared bound(s)"). > > This improves the error for example above to this: > > error: method identity in interface Function cannot be applied to given types; > Function f = Function.identity(); > ^ > reason: wrong number of type arguments; required 1 > where T,R are type-variables: > T extends Object declared in interface Function > R extends Object declared in interface Function > 1 error Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Fix missing indendation of switch statement. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/10799/files - new: https://git.openjdk.org/jdk/pull/10799/files/92338830..3f8c9509 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=10799&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=10799&range=02-03 Stats: 23 lines in 1 file changed: 0 ins; 0 del; 23 mod Patch: https://git.openjdk.org/jdk/pull/10799.diff Fetch: git fetch https://git.openjdk.org/jdk pull/10799/head:pull/10799 PR: https://git.openjdk.org/jdk/pull/10799 From duke at openjdk.org Fri Jan 6 18:00:47 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 6 Jan 2023 18:00:47 GMT Subject: RFR: 8043251: Bogus javac error: required: no arguments, found: no arguments [v3] In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 17:37:12 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision: >> >> - Merge branch 'master' into JDK-8043251 >> - Merge branch 'master' into JDK-8043251 >> - Fix confusing error message regarding wrong number of type parameters. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java line 4180: > >> 4178: // so use the error message that omits them to avoid confusion. >> 4179: switch (c.snd.getCode()) { >> 4180: case "compiler.misc.wrong.number.type.args": > > minor indentation suggestion: I would move the statements inside of the `switch` block to the right Thanks, it is inconsistent with the style in that file. Fixed in 3f8c9509861. ------------- PR: https://git.openjdk.org/jdk/pull/10799 From duke at openjdk.org Fri Jan 6 18:10:05 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 6 Jan 2023 18:10:05 GMT Subject: RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v4] In-Reply-To: References: Message-ID: <4CE_n2IeRda2BVQ51W3RmiuMEg2FjpfbEARAyej_7Ys=.8e4e6003-b429-462b-9e9a-f3590ae9d957@github.com> On Fri, 6 Jan 2023 03:32:19 GMT, Vicente Romero wrote: > I think that a follow-up JIRA issue should be filed to track the situation in which the bug can still occur Agreed (though it's not something I have permission to do). ------------- PR: https://git.openjdk.org/jdk/pull/10797 From vromero at openjdk.org Fri Jan 6 20:01:58 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 6 Jan 2023 20:01:58 GMT Subject: RFR: 8043251: Bogus javac error: required: no arguments, found: no arguments [v3] In-Reply-To: References: Message-ID: On Mon, 19 Dec 2022 15:44:21 GMT, Archie L. Cobbs wrote: >> We have an error message `compiler.err.cant.apply.symbol` for cases where a method invocation doesn't resolve. It shows the "required" parameters and the "found" parameters, plus a further description of the problem. >> >> This message being used inappropriately when the problem is actually due to explicitly passed method type parameters instead of regular method parameters. >> >> For example, if you do this: >> >> Function f = Function.identity(); >> >> the error reported is this: >> >> error: method identity in interface Function cannot be applied to given types; >> Function f = Function.identity(); >> ^ >> required: no arguments >> found: no arguments >> reason: wrong number of type arguments; required 1 >> where T,R are type-variables: >> T extends Object declared in interface Function >> R extends Object declared in interface Function >> >> The real error here is `wrong number of type arguments; required 1`, but the `compiler.err.cant.apply.symbol` error message that assumes the problem is with the regular parameters, which it displays. The result is the appearance of the useless and confusing `required` and `found` lines. >> >> This patch creates an alternate version of that error message (`compiler.err.cant.apply.symbol.noargs`) that omits the `required` and `found` lines, and makes the compiler use this alternate message when the error is due to type parameters (specifically, when the underlying error is "wrong number of type arguments" or "explicit type argument X does not conform to declared bound(s)"). >> >> This improves the error for example above to this: >> >> error: method identity in interface Function cannot be applied to given types; >> Function f = Function.identity(); >> ^ >> reason: wrong number of type arguments; required 1 >> where T,R are type-variables: >> T extends Object declared in interface Function >> R extends Object declared in interface Function >> 1 error > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision: > > - Merge branch 'master' into JDK-8043251 > - Merge branch 'master' into JDK-8043251 > - Fix confusing error message regarding wrong number of type parameters. looks sensible ------------- Marked as reviewed by vromero (Reviewer). PR: https://git.openjdk.org/jdk/pull/10799 From vromero at openjdk.org Fri Jan 6 20:26:51 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 6 Jan 2023 20:26:51 GMT Subject: RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v4] In-Reply-To: <4CE_n2IeRda2BVQ51W3RmiuMEg2FjpfbEARAyej_7Ys=.8e4e6003-b429-462b-9e9a-f3590ae9d957@github.com> References: <4CE_n2IeRda2BVQ51W3RmiuMEg2FjpfbEARAyej_7Ys=.8e4e6003-b429-462b-9e9a-f3590ae9d957@github.com> Message-ID: On Fri, 6 Jan 2023 18:05:34 GMT, Archie L. Cobbs wrote: > > I think that a follow-up JIRA issue should be filed to track the situation in which the bug can still occur > > Agreed (though it's not something I have permission to do). true, I have created: https://bugs.openjdk.org/browse/JDK-8299760 ------------- PR: https://git.openjdk.org/jdk/pull/10797 From duke at openjdk.org Fri Jan 6 23:13:09 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 6 Jan 2023 23:13:09 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v2] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: - Update copyright year for newly added files to 2023. - Suppress "this-escape" warnings using build flags instead of @SuppressAnnotations annotations. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/9c162283..f667cd56 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=00-01 Stats: 1935 lines in 1303 files changed: 60 ins; 1770 del; 105 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 6 23:13:09 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 6 Jan 2023 23:13:09 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 15:38:31 GMT, Alan Bateman wrote: >>> The associated JBS issue has been dormant for 6+ years and this is a very intrusive change affecting many, many files. Has the resurrection of this project previously been discussed somewhere? >> >> Hi @dholmes-ora, >> >> The work to add this warning has been guided by @briangoetz in discussions on the amber-dev mailing list. See that thread for how we came up with the current design, underlying motivation, etc. >> >> Regarding intrusiveness (assuming you're referring simply to the number of files touched), as mentioned this was one of two options. The other option would be to patch to about ~30 `Java.gmk` files in `make/modules` to exclude `this-escape` from `-Xlint` during the various module builds. >> >> Going this route is fine with me, but it has the downside that any new code being developed would not benefit from the new warning. This was in fact my original approach (and it was a lot easier :) but Brian rightly pointed out that adding `@SuppressWarnings` annotations was the the safer (i.e, more conservative) approach. >> >>> If you haven't done so already then you probably should socialize on compiler-dev and get agreement on the semantics and other details. >> >> Hi @AlanBateman, >> >> As mentioned this has been under discussion on amber-dev for a while. Happy to continue that discussion here as well. >> >>> I think you will also need to separate the addition of the lint warning from the changes to the wider JDK. It might be okay to add the feature but have it disabled for the JDK build initially. >> >> Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? >> >> If this is generally agreed as a better route then let me know and I'll update the patch. >> >> Thanks for both of your comments. > >> Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? >> >> If this is generally agreed as a better route then let me know and I'll update the patch. > > Yes, I think that would be better. It would remove most of the noise, 1200+ files, and 10+ mailing lists from this PR. I assume there will be at least some iteration on compiler-dev about the details and changes to javac. Once you get to the JDK changes then I suspect that some areas may want to fix issues rather than adding SW. Sadly, I see a few examples in your list where there have been attempts to avoid leaking "this" but where we backed away out of concern that 3rd party code was extending some class and overriding a method known to be invoked by the constructor. Also we have places that register themselves to cleaners. I suspect some of the suggestions to document leaking this in implNotes will need discussion too because they amount to documenting "hooks" that people will rely on, e.g. documenting in ArrayDeque that its constructor invokes addList could be read as an invite to override it. Hi @AlanBateman, OK that sounds like a plan. I've pushed a new commit to the `ThisEscape` branch that removes all the`@SuppressWarnings` annotations and replaces them with adjustments to build flags. I've moved the `@SuppressWarnings` annotations onto a new branch `ThisEscapeAnnotations`. This is just for future reference in case somebody wants to add them back someday and doesn't want to start from scratch. > I suspect some of the suggestions to document leaking this in implNotes will need discussion too because they amount to documenting "hooks" that people will rely on, e.g. documenting in ArrayDeque that its constructor invokes addList could be read as an invite to override it. Hmm. Hasn't that horse already left the barn? You kind of implied that when you said: > I see a few examples in your list where there have been attempts to avoid leaking "this" but where we backed away out of concern that 3rd party code was extending some class and overriding a method known to be invoked by the constructor. In other words, it doesn't sound like changing the behavior of these constructors is viable option at this point. And if that's the case, we might as well document and warn about the current behavior. Of course I'd love to be wrong... in which case, we can fix these constructors. Or, the third option - just do nothing yet. That would mean removing the warnings, which is fine. But then the `ThisEscape.html` document is orphaned. What should we do with it? I can remove it, just leave it there, or put it somewhere else (where?). It seems like having some documentation of the meaning of "this escape" would be helpful, because it's a subtle concept and there are multiple ways to define "escape". Thanks. @mcimadamore thanks for the bugs suggestion, I'll put that on the to-do list. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jjg at openjdk.org Sat Jan 7 00:38:51 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Sat, 7 Jan 2023 00:38:51 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet In-Reply-To: References: Message-ID: <9ozt9VIu8YvEdHtCfDR7NXcGNgUPI85mmzkW28wgo4U=.5ba7ec1a-737f-457e-a35f-14cc9c59c96d@github.com> On Wed, 4 Jan 2023 18:38:23 GMT, Pavel Rappo wrote: >> src/jdk.compiler/share/classes/com/sun/source/doctree/InheritDocTree.java line 31: >> >>> 29: * A tree node for an {@code @inheritDoc} inline tag. >>> 30: * >>> 31: * @apiNote >> >> 1. Consider wrapping that long line. >> 2. While it's good to have that fact noted here, it's more important to note it in "Documentation Comment Specification for the Standard Doclet". > > Ah, I can see that you added such a note before in CSR (sorry for the noise): > > +_Note:_ When using [Markdown comments](#markdown-content), there is no requirement > +that the comment containing the tag and the comment containing the inherited documentation > +should either be both Markdown comments or both normal (not Markdown) comments. Line wrapped. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Sat Jan 7 00:55:57 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Sat, 7 Jan 2023 00:55:57 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet In-Reply-To: References: Message-ID: On Tue, 3 Jan 2023 20:09:27 GMT, Pavel Rappo wrote: >> Support for Markdown comments in the standard doclet. >> >> To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. >> >> The work is in 3 parts: >> >> 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. >> 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. >> 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. >> >> There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. > > src/jdk.compiler/share/classes/com/sun/source/doctree/MarkdownTree.java line 2: > >> 1: /* >> 2: * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. > > 2011? fixed, 2022, 2023 > src/jdk.compiler/share/classes/com/sun/source/doctree/package-info.java line 30: > >> 28: * trees (AST). >> 29: * >> 30: *

Markdown

> > Consider updating the copyright years in this file. done > src/jdk.javadoc/share/classes/jdk/internal/org/commonmark/internal/util/Html5Entities.java line 15: > >> 13: >> 14: private static final Map NAMED_CHARACTER_REFERENCES = readEntities(); >> 15: private static final String ENTITY_PATH = "/org/commonmark/internal/util/entities.properties"; > > This properties file is missing from this PR. If you add a test with an md- doc comment that has entities (e.g. `&`), the test will crash. fixed. Actually, the `.properties` file is not a Properties file as defined in `java.util.Properties` and is read line-at-a-time with custom code. To avoid automated compilation of the file by the JDK build system, the file needs to avoid the `.properties` extension. Currently, using plain old `.txt`. > src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java line 1248: > >> 1246: } >> 1247: >> 1248: private class MarkdownHandler { > > Changes in this file seem to be the meat of the mechanism whereby Markdown-JavaDoc-HTML soup is handled. The mechanics looks good. Thanks for checking. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Sat Jan 7 00:55:57 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Sat, 7 Jan 2023 00:55:57 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet In-Reply-To: References: Message-ID: On Wed, 4 Jan 2023 20:06:51 GMT, Pavel Rappo wrote: >> In general, no, because of the possibility of `new Boolean` so it will depend on the code in `scan`. I'll investigate. > > You are correct. I keep forgetting about those now-deprecated-for-removal constructors for `java.lang.Boolean`. > > What you have now is good. Alternatively, you could use `Boolean.TRUE.equals(b)`, a Yoda condition, which you might or might not find aesthetically pleasing. Like you I believe, Yoda conditions confusing I find. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Sat Jan 7 00:55:58 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Sat, 7 Jan 2023 00:55:58 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet In-Reply-To: References: Message-ID: On Sat, 7 Jan 2023 00:42:05 GMT, Jonathan Gibbons wrote: >> You are correct. I keep forgetting about those now-deprecated-for-removal constructors for `java.lang.Boolean`. >> >> What you have now is good. Alternatively, you could use `Boolean.TRUE.equals(b)`, a Yoda condition, which you might or might not find aesthetically pleasing. > > Like you I believe, Yoda conditions confusing I find. There are no uses of the now-deprecated-for-removal constructors within this visitor, so the only values will be `null`, `Boolean.TRUE`, and boxed booleans. In addition, the `reduce` method on line 229 already uses `== Boolean.TRUE`. I'll update the expression. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Sat Jan 7 01:00:54 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Sat, 7 Jan 2023 01:00:54 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet In-Reply-To: References: Message-ID: On Wed, 4 Jan 2023 18:44:17 GMT, Jonathan Gibbons wrote: >> src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java line 1249: >> >>> 1247: >>> 1248: private class MarkdownHandler { >>> 1249: private static final char FFFC = '\uFFFC'; // Unicode Object Replacement Character >> >> Can we use a better name for the FFFC constant? PLACEHOLDER or some such. > > Sure. At least I took the first step and avoided repeated use of the character constant ;-) done >> src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java line 1281: >> >>> 1279: Node document = parser.parse(markdownInput.toString()); >>> 1280: HtmlRenderer renderer = HtmlRenderer.builder().build(); >>> 1281: String markdownOutput = renderer.render(document); >> >> Curious how heavyweight the parser and renderer are; should we cache them for reuse? > > Seems like a good idea if all works as might be expected. There was no perception that the Markdown machinery was particularly onerous, even in play scenarios in which all comments were treated as Markdown. Nevertheless, it seems reasonable to cache them within `MarkdownHandler`; less so in the enclosing `HtmlDocletWriter`. It may be the case down the road that we want to configure the builders with settings that may vary between comments, so `MarkdownHandler` seems a good choice, ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Sat Jan 7 01:10:52 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Sat, 7 Jan 2023 01:10:52 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet In-Reply-To: References: Message-ID: On Wed, 4 Jan 2023 22:05:10 GMT, Pavel Rappo wrote: > In case you've missed test failures in your GitHub Actions (GHA): `test/langtools/tools/javac/lib/DPrinter.java`. A trivial fix, really. Fixed. > src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java line 218: > >> 216: * @since 21 >> 217: */ >> 218: R visitMarkdown(MarkdownTree node, P p); > > This is supposed to be a `default` method, right? Yes. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From duke at openjdk.org Sat Jan 7 16:24:56 2023 From: duke at openjdk.org (ExE Boss) Date: Sat, 7 Jan 2023 16:24:56 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v2] In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 23:13:09 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Update copyright year for newly added files to 2023. > - Suppress "this-escape" warnings using build flags instead of @SuppressAnnotations annotations. src/java.base/share/classes/java/lang/AssertionError.java line 75: > 73: */ > 74: @SuppressWarnings("this-escape") > 75: public AssertionError(Object detailMessage) { The?Javadoc of?this?constructor should?probably?mention that?it?calls `initCause(?)` when?`detailMessage` is?a?`Throwable`. src/java.base/share/classes/java/lang/BootstrapMethodError.java line 77: > 75: * Constructs a {@code BootstrapMethodError} with the specified > 76: * cause. > 77: * Suggestion: * * @implNote This constructor invokes {@link #initCause initCause()}; see * This Escape. * src/java.base/share/classes/java/lang/ExceptionInInitializerError.java line 54: > 52: * throwable object. > 53: * A detail message is a String that describes this particular exception. > 54: */ Suggestion: * * @implNote This constructor invokes {@link #initCause initCause()}; see * This Escape. */ ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Sat Jan 7 16:58:58 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Sat, 7 Jan 2023 16:58:58 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v3] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Add a few more Javadoc warnings for 'this' escape via initCause(). ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/f667cd56..398737fa Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=01-02 Stats: 9 lines in 3 files changed: 9 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From alanb at openjdk.org Sat Jan 7 18:05:50 2023 From: alanb at openjdk.org (Alan Bateman) Date: Sat, 7 Jan 2023 18:05:50 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 23:08:27 GMT, Archie L. Cobbs wrote: > I've moved the `@SuppressWarnings` annotations onto a new branch `ThisEscapeAnnotations`. This is just for future reference in case somebody wants to add them back someday and doesn't want to start from scratch. > > > I suspect some of the suggestions to document leaking this in implNotes will need discussion too because they amount to documenting "hooks" that people will rely on, e.g. documenting in ArrayDeque that its constructor invokes addList could be read as an invite to override it. > > Hmm. Hasn't that horse already left the barn? You kind of implied that when you said: > > > I see a few examples in your list where there have been attempts to avoid leaking "this" but where we backed away out of concern that 3rd party code was extending some class and overriding a method known to be invoked by the constructor. > > In other words, it doesn't sound like changing the behavior of these constructors is viable option at this point. And if that's the case, we might as well document and warn about the current behavior. > > Of course I'd love to be wrong... in which case, we can fix these constructors. I hope at least some of these can be fixed as leaking a part initialized object to an untrusted subclass or some other code is problematic in many ways. Skimming through the original list, then some of these may be accidental and some may be fixable without any compatibility concerns, esp. in the JDK internal classes. Yes, some horses have left the barn. A horse that got out a long time ago is j.net.ServerSocket where 3 of its constructors call an overridable bind method. Recent re-implementation would have fixed this but there were concerns that subclasses may be relying on this long standing undocumented behavior. There are other cases in the list where the leaking may be necessary part of the contract for subclasses. So it will probably require working through them on a case by case basis. I don't think the implementation notes should be included as part of the adding the lint warning as I think it creates an attractive nuisance. Developers reading these implementation notes may c reate code that depends on these "hooks" and it will make it very hard for the JDK to ever change the behavior. Where the leaking is a necessary part of the contract for subclassing then it may be that it has to be documented as normative text rather than an implementation note. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Sat Jan 7 19:52:49 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Sat, 7 Jan 2023 19:52:49 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Sat, 7 Jan 2023 18:03:04 GMT, Alan Bateman wrote: > I don't think the implementation notes should be included as part of the adding the lint warning as I think it creates an attractive nuisance. I agree with you - not only for that reason, but also because as others have pointed out the addition of the warning is really a separate task from the evaluation and triage of any existing leaks. Moreover, this latter task is really multiple separate tasks that belong to the various module/functional groups. I'll remove all the Javadoc `@implNote`'s from the patch, and `src/java.base/share/classes/java/lang/doc-files/ThisEscape.html` as well - it will still be available in the git history if someone comes up with a better home for it. This will also further reduce the number of labels and therefore required reviewers. Thanks. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Sat Jan 7 19:59:59 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Sat, 7 Jan 2023 19:59:59 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v4] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Remove Javadoc @implNotes; plan to triage the various existing leaks separately. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/398737fa..537b3e3c Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=02-03 Stats: 255 lines in 29 files changed: 0 ins; 251 del; 4 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Sat Jan 7 21:08:07 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Sat, 7 Jan 2023 21:08:07 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: Message-ID: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Fix incorrect @bug numbers in unit tests. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/537b3e3c..7e2fdb07 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=03-04 Stats: 15 lines in 15 files changed: 0 ins; 0 del; 15 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Mon Jan 9 04:23:17 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 9 Jan 2023 04:23:17 GMT Subject: RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v5] In-Reply-To: References: Message-ID: > This patch is both a minor optimization and a fix for JDK-7176515. > > JDK-7176515 relates to how javac handles `switch` statements on `Enum` values, which are effectively "syntactic sugar". > > The simple approach would be to just get the enum's `ordinal()` value and then revert to a normal integer value switch on that. However, this snapshots the ordinal values at compile-time, and thus can fail if the `Enum` class is recompiled later. > > Presumably to avoid that possibility (are there any other reasons?) the compiler instead uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. This avoids the "stale ordinal" problem of the simple approach, but it also creates a potential class initialization loop if there happens to an `Enum` switch inside an `Enum` class constructor, as demonstrated by the bug. > > This patch makes the following change: If we are handling an `Enum` switch, and the `Enum` class we are switching on is also the class we are compiling, then just go with the simple approach, because the "stale ordinal" problem can't happen in this case so there's no need to build a runtime lookup table. > > This results in two improvements: > * It avoids building the lookup table for switches on self > * It fixes JDK-7176515 as stated > > Although the reproducing test case provided in JDK-7176515 gets fixed by this patch, the underlying issue is still there and can still be triggered with a slightly more complicated test case (included, but commented out). > > So JDK-7176515 could be left open (or a new bug created) and a separate discussion had about how to "really" fix it. > > Part of this discussion should be defining what that means, i.e., the boundaries of the bug. There are some scenarios that are basically impossible to fix, for example, two `Enum` classes whose constructors take as a parameter instances of the other `Enum` class and then switch on it. That cycle has nothing to do with how switches are handled. Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Further refinements to compiler-generated mappings tables for switched-on enums. - No mapping table needed for any Enum class within the same top level class. - Put mapping tables for different enum types into separate synthetic classes. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/10797/files - new: https://git.openjdk.org/jdk/pull/10797/files/05fb5e76..153ef39e Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=03-04 Stats: 137 lines in 3 files changed: 99 ins; 28 del; 10 mod Patch: https://git.openjdk.org/jdk/pull/10797.diff Fetch: git fetch https://git.openjdk.org/jdk pull/10797/head:pull/10797 PR: https://git.openjdk.org/jdk/pull/10797 From duke at openjdk.org Mon Jan 9 04:23:21 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 9 Jan 2023 04:23:21 GMT Subject: RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v4] In-Reply-To: References: Message-ID: On Mon, 19 Dec 2022 15:44:30 GMT, Archie L. Cobbs wrote: >> This patch is both a minor optimization and a fix for JDK-7176515. >> >> JDK-7176515 relates to how javac handles `switch` statements on `Enum` values, which are effectively "syntactic sugar". >> >> The simple approach would be to just get the enum's `ordinal()` value and then revert to a normal integer value switch on that. However, this snapshots the ordinal values at compile-time, and thus can fail if the `Enum` class is recompiled later. >> >> Presumably to avoid that possibility (are there any other reasons?) the compiler instead uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. This avoids the "stale ordinal" problem of the simple approach, but it also creates a potential class initialization loop if there happens to an `Enum` switch inside an `Enum` class constructor, as demonstrated by the bug. >> >> This patch makes the following change: If we are handling an `Enum` switch, and the `Enum` class we are switching on is also the class we are compiling, then just go with the simple approach, because the "stale ordinal" problem can't happen in this case so there's no need to build a runtime lookup table. >> >> This results in two improvements: >> * It avoids building the lookup table for switches on self >> * It fixes JDK-7176515 as stated >> >> Although the reproducing test case provided in JDK-7176515 gets fixed by this patch, the underlying issue is still there and can still be triggered with a slightly more complicated test case (included, but commented out). >> >> So JDK-7176515 could be left open (or a new bug created) and a separate discussion had about how to "really" fix it. >> >> Part of this discussion should be defining what that means, i.e., the boundaries of the bug. There are some scenarios that are basically impossible to fix, for example, two `Enum` classes whose constructors take as a parameter instances of the other `Enum` class and then switch on it. That cycle has nothing to do with how switches are handled. > > Archie L. Cobbs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: > > - Merge branch 'master' into JDK-7176515 > - Merge branch 'master' into JDK-7176515 > - Give test a better name and don't rely on assertions being enabled. > - Skip enum switch lookup tables when compiling the enum switch class. I've made a couple of improvements to this patch. As a result the follow-up bug [8299760](https://bugs.openjdk.org/browse/JDK-8299760), and also [8219412 - Eager enum class initialization with enum switch](https://bugs.openjdk.org/browse/JDK-8219412) are now fixed. Improvement 1 The previous patch avoided generating a mapping table when the `enum` being switched on was the same class as the class currently being compiled. This is because there is no possibility of the ordinal values changing at runtime due to a recompilation. But this is too conservative - the same thing is true for any `enum` type defined in the same top-level class. So we generalize the test from "same class" as "in the same top-level class compilation". This change fixes the follow-up bug [8299760](https://bugs.openjdk.org/browse/JDK-8299760). Improvement 2 All of the mapping tables for any `enum` type switched were being jammed into the same compiler-generated class. This meant that all of these `enum` types were initialized at the same time, regardless of which one actually experiences a 'first use'. This is what causes [8219412](https://bugs.openjdk.org/browse/JDK-8219412). The fix here is simple - put each mapping table into its own compiler-generated class. ------------- PR: https://git.openjdk.org/jdk/pull/10797 From dholmes at openjdk.org Mon Jan 9 06:39:52 2023 From: dholmes at openjdk.org (David Holmes) Date: Mon, 9 Jan 2023 06:39:52 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Sat, 7 Jan 2023 21:08:07 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: > > Fix incorrect @bug numbers in unit tests. All your new files need a copyright and GPL header. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Mon Jan 9 07:34:41 2023 From: duke at openjdk.org (Hannes Greule) Date: Mon, 9 Jan 2023 07:34:41 GMT Subject: RFR: 8292275: javac does not emit SYNTHETIC and MANDATED flags for parameters by default [v6] In-Reply-To: References: Message-ID: > With this change, javac emits the MethodParameters attribute in cases where the JLS requires the information about synthetic and mandated parameters to be stored (see issue). > Parameter names are *not* emitted unless the `-parameter` flag is set. > > The relevant changes are in `ClassWriter`, where we go through the params to see if we need the attribute if the `-parameter` flag is not set (if it is set, both names and flags will be emitted). > For records, the mandated flag wasn't set at all, this is solved by the one line fix in `JavacParser`. > > The changes to `CreateSymbols` and `ClassReader` are needed as they weren't able to deal with missing names in the attribute. > I also had to update some tests as they got a new constant pool entry. > > Only the mandated flag is covered by tests at the moment, as the occurrences are well-specified in the JLS. > Please let me know if you want tests for specific appearances of synthetic parameters. Hannes Greule has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 21 additional commits since the last revision: - Update copyright year - Merge remote-tracking branch 'upstream/master' into fix/enforce-methodparam_attr-if-mandated - address comments - cleanup - add annotation processing test - fix line breaks - add access flag based test - remove spaces from empty lines in text block - add bug number to test - copyright - ... and 11 more: https://git.openjdk.org/jdk/compare/a59fcad8...43780935 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/9862/files - new: https://git.openjdk.org/jdk/pull/9862/files/883a2dc1..43780935 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=9862&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=9862&range=04-05 Stats: 575335 lines in 7590 files changed: 286756 ins; 207614 del; 80965 mod Patch: https://git.openjdk.org/jdk/pull/9862.diff Fetch: git fetch https://git.openjdk.org/jdk pull/9862/head:pull/9862 PR: https://git.openjdk.org/jdk/pull/9862 From duke at openjdk.org Mon Jan 9 07:34:57 2023 From: duke at openjdk.org (Hannes Greule) Date: Mon, 9 Jan 2023 07:34:57 GMT Subject: RFR: 8292275: javac does not emit SYNTHETIC and MANDATED flags for parameters by default [v5] In-Reply-To: <6e64srLbjHyJ8Ub60mBRjPJzPaNNYcWm-MI5ETketgo=.68200038-aaa7-4a91-b023-3526e1449cca@github.com> References: <6e64srLbjHyJ8Ub60mBRjPJzPaNNYcWm-MI5ETketgo=.68200038-aaa7-4a91-b023-3526e1449cca@github.com> Message-ID: <3pWdjpejxHPcT1LjK0B0Z0CS9d1qFu64Gd4iJa2McUY=.0640e51f-1cad-4730-b6e9-3613620b873e@github.com> On Tue, 23 Aug 2022 19:39:48 GMT, Hannes Greule wrote: >> With this change, javac emits the MethodParameters attribute in cases where the JLS requires the information about synthetic and mandated parameters to be stored (see issue). >> Parameter names are *not* emitted unless the `-parameter` flag is set. >> >> The relevant changes are in `ClassWriter`, where we go through the params to see if we need the attribute if the `-parameter` flag is not set (if it is set, both names and flags will be emitted). >> For records, the mandated flag wasn't set at all, this is solved by the one line fix in `JavacParser`. >> >> The changes to `CreateSymbols` and `ClassReader` are needed as they weren't able to deal with missing names in the attribute. >> I also had to update some tests as they got a new constant pool entry. >> >> Only the mandated flag is covered by tests at the moment, as the occurrences are well-specified in the JLS. >> Please let me know if you want tests for specific appearances of synthetic parameters. > > Hannes Greule has updated the pull request incrementally with one additional commit since the last revision: > > address comments Hi, I merged master recently and updated the copyright year. Is there anything else I can do to get the CSR approved and my changes integrated? ------------- PR: https://git.openjdk.org/jdk/pull/9862 From aturbanov at openjdk.org Mon Jan 9 09:48:54 2023 From: aturbanov at openjdk.org (Andrey Turbanov) Date: Mon, 9 Jan 2023 09:48:54 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet In-Reply-To: References: Message-ID: On Thu, 15 Dec 2022 23:47:45 GMT, Jonathan Gibbons wrote: > Support for Markdown comments in the standard doclet. > > To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. > > The work is in 3 parts: > > 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. > 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. > 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. > > There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. src/jdk.javadoc/share/classes/jdk/internal/org/commonmark/internal/Bracket.java line 48: > 46: public boolean bracketAfter = false; > 47: > 48: static public Bracket link(Text node, Position markerPosition, Position contentPosition, Bracket previous, Delimiter previousDelimiter) { Let's use blessed modifiers order Suggestion: public static Bracket link(Text node, Position markerPosition, Position contentPosition, Bracket previous, Delimiter previousDelimiter) { ------------- PR: https://git.openjdk.org/jdk/pull/11701 From prappo at openjdk.org Mon Jan 9 10:16:58 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Mon, 9 Jan 2023 10:16:58 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet In-Reply-To: References: Message-ID: <2JaZ7lH4ec9vTf8OB54FHpvwpCv2m77kxpxq219ga6s=.8da94e1e-af32-418f-8abd-54edc83e98f7@github.com> On Mon, 9 Jan 2023 09:46:14 GMT, Andrey Turbanov wrote: >> Support for Markdown comments in the standard doclet. >> >> To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. >> >> The work is in 3 parts: >> >> 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. >> 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. >> 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. >> >> There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. > > src/jdk.javadoc/share/classes/jdk/internal/org/commonmark/internal/Bracket.java line 48: > >> 46: public boolean bracketAfter = false; >> 47: >> 48: static public Bracket link(Text node, Position markerPosition, Position contentPosition, Bracket previous, Delimiter previousDelimiter) { > > Let's use blessed modifiers order > Suggestion: > > public static Bracket link(Text node, Position markerPosition, Position contentPosition, Bracket previous, Delimiter previousDelimiter) { This class belongs to a 3rd party library, CommonMark. Changes that aren't necessary for the library to work in the JDK or not related to security might not be worth it. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From duke at openjdk.org Mon Jan 9 13:48:24 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 9 Jan 2023 13:48:24 GMT Subject: RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v6] In-Reply-To: References: Message-ID: > This patch is both a minor optimization and a fix for JDK-7176515. > > JDK-7176515 relates to how javac handles `switch` statements on `Enum` values, which are effectively "syntactic sugar". > > The simple approach would be to just get the enum's `ordinal()` value and then revert to a normal integer value switch on that. However, this snapshots the ordinal values at compile-time, and thus can fail if the `Enum` class is recompiled later. > > Presumably to avoid that possibility (are there any other reasons?) the compiler instead uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. This avoids the "stale ordinal" problem of the simple approach, but it also creates a potential class initialization loop if there happens to an `Enum` switch inside an `Enum` class constructor, as demonstrated by the bug. > > This patch makes the following change: If we are handling an `Enum` switch, and the `Enum` class we are switching on is also the class we are compiling, then just go with the simple approach, because the "stale ordinal" problem can't happen in this case so there's no need to build a runtime lookup table. > > This results in two improvements: > * It avoids building the lookup table for switches on self > * It fixes JDK-7176515 as stated > > Although the reproducing test case provided in JDK-7176515 gets fixed by this patch, the underlying issue is still there and can still be triggered with a slightly more complicated test case (included, but commented out). > > So JDK-7176515 could be left open (or a new bug created) and a separate discussion had about how to "really" fix it. > > Part of this discussion should be defining what that means, i.e., the boundaries of the bug. There are some scenarios that are basically impossible to fix, for example, two `Enum` classes whose constructors take as a parameter instances of the other `Enum` class and then switch on it. That cycle has nothing to do with how switches are handled. Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Revert 2nd part of previous commit ("Put mapping tables for different..."). This should go into a separate branch. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/10797/files - new: https://git.openjdk.org/jdk/pull/10797/files/153ef39e..f8b189ec Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=04-05 Stats: 84 lines in 2 files changed: 17 ins; 64 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/10797.diff Fetch: git fetch https://git.openjdk.org/jdk pull/10797/head:pull/10797 PR: https://git.openjdk.org/jdk/pull/10797 From duke at openjdk.org Mon Jan 9 13:54:30 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 9 Jan 2023 13:54:30 GMT Subject: RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v7] In-Reply-To: References: Message-ID: > This patch is both a minor optimization and a fix for JDK-7176515. > > JDK-7176515 relates to how javac handles `switch` statements on `Enum` values, which are effectively "syntactic sugar". > > The simple approach would be to just get the enum's `ordinal()` value and then revert to a normal integer value switch on that. However, this snapshots the ordinal values at compile-time, and thus can fail if the `Enum` class is recompiled later. > > Presumably to avoid that possibility (are there any other reasons?) the compiler instead uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. This avoids the "stale ordinal" problem of the simple approach, but it also creates a potential class initialization loop if there happens to an `Enum` switch inside an `Enum` class constructor, as demonstrated by the bug. > > This patch makes the following change: If we are handling an `Enum` switch, and the `Enum` class we are switching on is also the class we are compiling, then just go with the simple approach, because the "stale ordinal" problem can't happen in this case so there's no need to build a runtime lookup table. > > This results in two improvements: > * It avoids building the lookup table for switches on self > * It fixes JDK-7176515 as stated > > Although the reproducing test case provided in JDK-7176515 gets fixed by this patch, the underlying issue is still there and can still be triggered with a slightly more complicated test case (included, but commented out). > > So JDK-7176515 could be left open (or a new bug created) and a separate discussion had about how to "really" fix it. > > Part of this discussion should be defining what that means, i.e., the boundaries of the bug. There are some scenarios that are basically impossible to fix, for example, two `Enum` classes whose constructors take as a parameter instances of the other `Enum` class and then switch on it. That cycle has nothing to do with how switches are handled. Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Update unit test after fixing 8299760. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/10797/files - new: https://git.openjdk.org/jdk/pull/10797/files/f8b189ec..6f7f30f7 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=06 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=05-06 Stats: 3 lines in 1 file changed: 0 ins; 1 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/10797.diff Fetch: git fetch https://git.openjdk.org/jdk pull/10797/head:pull/10797 PR: https://git.openjdk.org/jdk/pull/10797 From duke at openjdk.org Mon Jan 9 13:48:24 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 9 Jan 2023 13:48:24 GMT Subject: RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v5] In-Reply-To: References: Message-ID: On Mon, 9 Jan 2023 04:23:17 GMT, Archie L. Cobbs wrote: >> This patch is both a minor optimization and a fix for JDK-7176515. >> >> JDK-7176515 relates to how javac handles `switch` statements on `Enum` values, which are effectively "syntactic sugar". >> >> The simple approach would be to just get the enum's `ordinal()` value and then revert to a normal integer value switch on that. However, this snapshots the ordinal values at compile-time, and thus can fail if the `Enum` class is recompiled later. >> >> Presumably to avoid that possibility (are there any other reasons?) the compiler instead uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. This avoids the "stale ordinal" problem of the simple approach, but it also creates a potential class initialization loop if there happens to an `Enum` switch inside an `Enum` class constructor, as demonstrated by the bug. >> >> This patch makes the following change: If we are handling an `Enum` switch, and the `Enum` class we are switching on is also the class we are compiling, then just go with the simple approach, because the "stale ordinal" problem can't happen in this case so there's no need to build a runtime lookup table. >> >> This results in two improvements: >> * It avoids building the lookup table for switches on self >> * It fixes JDK-7176515 as stated >> >> Although the reproducing test case provided in JDK-7176515 gets fixed by this patch, the underlying issue is still there and can still be triggered with a slightly more complicated test case (included, but commented out). >> >> So JDK-7176515 could be left open (or a new bug created) and a separate discussion had about how to "really" fix it. >> >> Part of this discussion should be defining what that means, i.e., the boundaries of the bug. There are some scenarios that are basically impossible to fix, for example, two `Enum` classes whose constructors take as a parameter instances of the other `Enum` class and then switch on it. That cycle has nothing to do with how switches are handled. > > Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: > > Further refinements to compiler-generated mappings tables for switched-on enums. > > - No mapping table needed for any Enum class within the same top level class. > - Put mapping tables for different enum types into separate synthetic classes. On second thought, the 2nd improvement belongs in a separate PR, as there probably is more discussion required. Reverting that part of the change from this PR. ------------- PR: https://git.openjdk.org/jdk/pull/10797 From duke at openjdk.org Mon Jan 9 14:03:54 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 9 Jan 2023 14:03:54 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Mon, 9 Jan 2023 06:37:22 GMT, David Holmes wrote: > All your new files need a copyright and GPL header. Sorry if I'm being blind but I'm not seeing it. Which file(s) are you referring to? The `@test /nodynamiccopyright/` files don't get one per [this](https://openjdk.org/groups/compiler/tests.html#gold). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From archie.cobbs at gmail.com Mon Jan 9 15:02:33 2023 From: archie.cobbs at gmail.com (Archie Cobbs) Date: Mon, 9 Jan 2023 09:02:33 -0600 Subject: Soliciting opinions on JDK-8219412 Message-ID: I'm looking for advice/opinions on the best way to address JDK-8219412 - Eager enum class initialization with enum switch . The problem stems from how the compiler implements switches on enum. The obvious simple approach is to get the enum's ordinal() value and then revert to a normal integer value switch. However, this snapshots the ordinal values at compile-time, and thus can fail if the Enum class is recompiled later. Instead the compiler uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. When compiling Foo.java, a separate lookup table is created for each enum type that is switched on anywhere in Foo.java. These lookup tables are all put into a single synthetic class Foo$1 and are all initialized at the same time, in a single static initializer. Now suppose Foo contains switches on enum types E1, E2, and E3 and a switch on E1 is encountered. This will cause classes E2 and E3 to be initialized, even though there is no 'first use' of either class. This is the bug. *Strategy #1 - Put each lookup table into a separate synthetic class.* You can see *the reverse* of this fix in this diff . The upside of this approach is that it fixes the bug without changing the approach and therefore presumably minimally affecting performance. The downside is an increase in the number of synthetic classes created: for every enum type switched on in Foo.java but declared in some other source file, there is a synthetic class created: Foo$1, Foo$2, etc. Is that a show-stopper?? The total amount of code generated is basically the same, it's just spread over multiple class files instead of one. *Strategy #2 - Switch on String identifiers instead of ordinal values* This approach is straightforward, however the performance suffers a good bit in my tests. Probably not an option. *Strategy #3 - Don't rely on a static initializer to build the mapping tables* This approach would mean not relying on class initialization to trigger building the mapping tables, so we could build each table separately on demand. The synthetic class would look something like this: synthetic /* volatile ? */ int[] $EnumMap$E1; synthetic /* volatile ? */ int[] $EnumMap$E2; synthetic /* volatile ? */ int[] $EnumMap$E3; static int[] getEnumMap$E1() { if ($EnumMap$E1 == null) { /* build map here */ } return $EnumMap$E1; } static int[] getEnumMap$E2() { if ($EnumMap$E2 == null) { /* build map here */ } return $EnumMap$E2; } static int[] getEnumMap$E3() { if ($EnumMap$E3 == null) { /* build map here */ } return $EnumMap$E3; } *Strategy #4 - Other ideas?* Thanks, -Archie -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Mon Jan 9 15:35:42 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 9 Jan 2023 15:35:42 +0000 Subject: Soliciting opinions on JDK-8219412 In-Reply-To: References: Message-ID: Another strategy is to use an `invokedynamic` as a switch classifier. (I believe there is even a bootstrap for this implemented somewhere.) The idea is that we lower a switch switch (e) [ case A: ? case B: ? ? } Into a compact switch on int, and use an indy to map the target to a case number: switch (indy [BSM=EnumClassifier, type=(E)I, args = [ E.class, ?A?, ?B?, ? ]) { case 1: ? Case 2: ? } The indy bootstrap takes as a dynamic argument the switch operand (enum value), and returns an int corresponding the case number. The static argument list identifies the enum constants (by string) corresponding to the case numbers. The bootstrap builds the array that we would have built at compile time, curries it onto a method handle, and wraps the method handle in a ConstantCallSite. Then the array is only built the first time we invoke the switch. Thereafter we get similar behavior to the current scheme, but without static initializers. On Jan 9, 2023, at 10:02 AM, Archie Cobbs > wrote: I'm looking for advice/opinions on the best way to address JDK-8219412 - Eager enum class initialization with enum switch. The problem stems from how the compiler implements switches on enum. The obvious simple approach is to get the enum's ordinal() value and then revert to a normal integer value switch. However, this snapshots the ordinal values at compile-time, and thus can fail if the Enum class is recompiled later. Instead the compiler uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. When compiling Foo.java, a separate lookup table is created for each enum type that is switched on anywhere in Foo.java. These lookup tables are all put into a single synthetic class Foo$1 and are all initialized at the same time, in a single static initializer. Now suppose Foo contains switches on enum types E1, E2, and E3 and a switch on E1 is encountered. This will cause classes E2 and E3 to be initialized, even though there is no 'first use' of either class. This is the bug. Strategy #1 - Put each lookup table into a separate synthetic class. You can see the reverse of this fix in this diff. The upside of this approach is that it fixes the bug without changing the approach and therefore presumably minimally affecting performance. The downside is an increase in the number of synthetic classes created: for every enum type switched on in Foo.java but declared in some other source file, there is a synthetic class created: Foo$1, Foo$2, etc. Is that a show-stopper?? The total amount of code generated is basically the same, it's just spread over multiple class files instead of one. Strategy #2 - Switch on String identifiers instead of ordinal values This approach is straightforward, however the performance suffers a good bit in my tests. Probably not an option. Strategy #3 - Don't rely on a static initializer to build the mapping tables This approach would mean not relying on class initialization to trigger building the mapping tables, so we could build each table separately on demand. The synthetic class would look something like this: synthetic /* volatile ? */ int[] $EnumMap$E1; synthetic /* volatile ? */ int[] $EnumMap$E2; synthetic /* volatile ? */ int[] $EnumMap$E3; static int[] getEnumMap$E1() { if ($EnumMap$E1 == null) { /* build map here */ } return $EnumMap$E1; } static int[] getEnumMap$E2() { if ($EnumMap$E2 == null) { /* build map here */ } return $EnumMap$E2; } static int[] getEnumMap$E3() { if ($EnumMap$E3 == null) { /* build map here */ } return $EnumMap$E3; } Strategy #4 - Other ideas? Thanks, -Archie -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Mon Jan 9 15:54:41 2023 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 9 Jan 2023 15:54:41 +0000 Subject: Soliciting opinions on JDK-8219412 In-Reply-To: References: Message-ID: I agree with Brian. If we want to fix this and put our hands in the enum switch classification, I think the best use of our time would be to tweak enum switches to adopt the superior indy-based classification approach, which should be immune to the issue you present. Thanks Maurizio On 09/01/2023 15:35, Brian Goetz wrote: > Another strategy is to use an `invokedynamic` as a switch classifier. > ?(I believe there is even a bootstrap for this implemented somewhere.) > > The idea is that we lower a switch > > ? ? switch (e) [ > ? ? ? ? case A: ? > ? ? ? ? case B: ? > ? ? ? ? ? > ? ? } > > Into a compact switch on int, and use an indy to map the target to a > case number: > > ? ? switch (indy [BSM=EnumClassifier, type=(E)I, args = [ E.class, > ?A?, ?B?, ? ]) { > ? ? ? ? case 1: ? > ? ? ? ? Case 2: ? > ? ? } > > ?The indy bootstrap takes as a dynamic argument the switch operand > (enum value), and returns an int corresponding the case number. > ?The?static argument list identifies the enum constants (by string) > corresponding to the case numbers. ?The bootstrap builds the array > that we would?have built at compile time, curries it onto a method > handle, and wraps the method handle in a ConstantCallSite. ?Then the > array is only built the?first time we invoke the switch. ?Thereafter > we get similar behavior to the current scheme, but without static > initializers. > > > > > >> On Jan 9, 2023, at 10:02 AM, Archie Cobbs wrote: >> >> I'm looking for advice/opinions on the best way to >> address?JDK-8219412 - Eager enum class initialization with enum switch. >> >> The problem stems from how the compiler implements switches on enum. >> The obvious simple approach is to get the enum's?ordinal()?value?and >> then revert to a normal integer value switch.?However, this snapshots >> the ordinal values at compile-time, and thus can?fail if >> the?Enum?class?is recompiled later. >> Instead the compiler uses a lookup table. This table is?dynamically >> constructed at runtime by a static initializer in a?synthetic class. >> When?compiling?Foo.java, a separate lookup table is created for each >> enum type that is switched on anywhere in?Foo.java. These lookup >> tables?are all put into a single synthetic class?Foo$1?and are all >> initialized at the same time, in a single static initializer. >> >> Now suppose Foo contains switches on enum types E1, E2, and E3 and a >> switch on E1 is encountered. This will cause classes E2 and E3 to?be >> initialized, even though there is no 'first use' of either class. >> This is the bug. >> >> Strategy #1 - Put each lookup table into a separate synthetic class. >> >> You can see?the reverse?of this fix?in this diff. >> >> The upside of this approach is that it fixes the bug without changing >> the approach and therefore presumably minimally affecting performance. >> >> The downside is an increase in the number of synthetic classes >> created: for every enum type switched on in Foo.java but declared in >> some?other source file, there is a synthetic class >> created:?Foo$1,?Foo$2, etc. Is that a show-stopper?? >> >> The total amount of code generated is basically the same, it's just >> spread over multiple class files instead of one. >> >> Strategy #2 - Switch on String identifiers instead of ordinal values >> >> This approach is straightforward, however the performance suffers a >> good bit in my tests. Probably not an option. >> >> Strategy #3 - Don't rely on a static initializer to build the mapping >> tables >> >> This approach would mean not relying on class initialization to >> trigger building the mapping tables, so we could build each table >> separately on?demand. The synthetic class would look something like this: >> >> synthetic /*?volatile?? */ int[] $EnumMap$E1; >> synthetic?/*?volatile?? */?int[] $EnumMap$E2; >> synthetic?/*?volatile?? */?int[] $EnumMap$E3; >> >> static int[] getEnumMap$E1() { >> ? ? if ($EnumMap$E1 == null) { >> ? ? ? ? /* build map here */ >> ? ? } >> ? ? return $EnumMap$E1; >> } >> >> static int[] getEnumMap$E2() { >> ? ? if ($EnumMap$E2 == null) { >> ? ? ? ? /* build map here */ >> ? ? } >> ? ? return $EnumMap$E2; >> } >> >> static int[] getEnumMap$E3() { >> ? ? if ($EnumMap$E3 == null) { >> ? ? ? ? /* build map here */ >> ? ? } >> ? ? return $EnumMap$E3; >> } >> >> Strategy #4 - Other ideas? >> >> Thanks, >> -Archie >> >> -- >> Archie L. Cobbs > -------------- next part -------------- An HTML attachment was scrubbed... URL: From archie.cobbs at gmail.com Mon Jan 9 16:20:06 2023 From: archie.cobbs at gmail.com (Archie Cobbs) Date: Mon, 9 Jan 2023 10:20:06 -0600 Subject: Soliciting opinions on JDK-8219412 In-Reply-To: References: Message-ID: Thanks for the comments. Using invokedynamic makes perfect sense! (and I'm disappointed I didn't think of it :) I'll take a look into it and report back. -Archie On Mon, Jan 9, 2023 at 9:54 AM Maurizio Cimadamore < maurizio.cimadamore at oracle.com> wrote: > I agree with Brian. If we want to fix this and put our hands in the enum > switch classification, I think the best use of our time would be to tweak > enum switches to adopt the superior indy-based classification approach, > which should be immune to the issue you present. > > Thanks > Maurizio > On 09/01/2023 15:35, Brian Goetz wrote: > > Another strategy is to use an `invokedynamic` as a switch classifier. (I > believe there is even a bootstrap for this implemented somewhere.) > > -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From jjg at openjdk.org Mon Jan 9 15:52:59 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Mon, 9 Jan 2023 15:52:59 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet In-Reply-To: <2JaZ7lH4ec9vTf8OB54FHpvwpCv2m77kxpxq219ga6s=.8da94e1e-af32-418f-8abd-54edc83e98f7@github.com> References: <2JaZ7lH4ec9vTf8OB54FHpvwpCv2m77kxpxq219ga6s=.8da94e1e-af32-418f-8abd-54edc83e98f7@github.com> Message-ID: On Mon, 9 Jan 2023 10:13:54 GMT, Pavel Rappo wrote: >> src/jdk.javadoc/share/classes/jdk/internal/org/commonmark/internal/Bracket.java line 48: >> >>> 46: public boolean bracketAfter = false; >>> 47: >>> 48: static public Bracket link(Text node, Position markerPosition, Position contentPosition, Bracket previous, Delimiter previousDelimiter) { >> >> Let's use blessed modifiers order >> Suggestion: >> >> public static Bracket link(Text node, Position markerPosition, Position contentPosition, Bracket previous, Delimiter previousDelimiter) { > > This class belongs to a 3rd party library, CommonMark. Changes that aren't necessary for the library to work in the JDK or not related to security might not be worth it. Agreed that we should not do "cosmetic" changes on imported code. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Mon Jan 9 17:44:35 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Mon, 9 Jan 2023 17:44:35 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet [v2] In-Reply-To: References: Message-ID: <2bFoIv0Kj1LGy3YGyZGQNQVJ0Ue8Y-26B7oyZoqnjH8=.4e68efb1-f6d8-42c3-abf0-881b872886e2@github.com> > Support for Markdown comments in the standard doclet. > > To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. > > The work is in 3 parts: > > 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. > 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. > 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. > > There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. Jonathan Gibbons has updated the pull request incrementally with five additional commits since the last revision: - Update copyright years - Rename FFFC variable Share Markdown parser and renderer in instance of MarkdownHandler - Move CommonMark to new internal module. Add legal header to imported CommonMark source files Always use Text nodes inside AttributeTree values Unwrap

from "simple" paragraphs - Always use Text nodes inside AttributeTree values - Update to CommonMark 0.21. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11701/files - new: https://git.openjdk.org/jdk/pull/11701/files/f9e24538..82e363ad Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11701&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11701&range=00-01 Stats: 19920 lines in 262 files changed: 12929 ins; 6918 del; 73 mod Patch: https://git.openjdk.org/jdk/pull/11701.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11701/head:pull/11701 PR: https://git.openjdk.org/jdk/pull/11701 From prappo at openjdk.org Mon Jan 9 18:00:00 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Mon, 9 Jan 2023 18:00:00 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet [v2] In-Reply-To: <2bFoIv0Kj1LGy3YGyZGQNQVJ0Ue8Y-26B7oyZoqnjH8=.4e68efb1-f6d8-42c3-abf0-881b872886e2@github.com> References: <2bFoIv0Kj1LGy3YGyZGQNQVJ0Ue8Y-26B7oyZoqnjH8=.4e68efb1-f6d8-42c3-abf0-881b872886e2@github.com> Message-ID: On Mon, 9 Jan 2023 17:44:35 GMT, Jonathan Gibbons wrote: >> Support for Markdown comments in the standard doclet. >> >> To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. >> >> The work is in 3 parts: >> >> 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. >> 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. >> 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. >> >> There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. > > Jonathan Gibbons has updated the pull request incrementally with five additional commits since the last revision: > > - Update copyright years > - Rename FFFC variable > Share Markdown parser and renderer in instance of MarkdownHandler > - Move CommonMark to new internal module. > Add legal header to imported CommonMark source files > Always use Text nodes inside AttributeTree values > Unwrap

from "simple" paragraphs > - Always use Text nodes inside AttributeTree values > - Update to CommonMark 0.21. src/jdk.internal.md/share/classes/jdk/internal/org/commonmark/internal/util/Html5Entities.java line 47: > 45: > 46: private static final Map NAMED_CHARACTER_REFERENCES = readEntities(); > 47: private static final String ENTITY_PATH = "/org/commonmark/internal/util/entities.txt"; I see that you've added the missing `entities.properties` file, but renamed it to `entities.txt`. IIRC from our offline chat, it's due to how JDK build treats `.properties` files. I wonder what would be better: (a) to keep the original extension, but amend the build to ignore this file, or (b) to do what you've done and possibly suggest a PR for CommonMark to do the same. On the one hand, it's not a true Java `.properties` file as one might've though from its extension. On the other hand, this change of yours diverge us from the original snapshot of CommonMark. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jjg at openjdk.org Mon Jan 9 18:07:56 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Mon, 9 Jan 2023 18:07:56 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet [v2] In-Reply-To: References: <2bFoIv0Kj1LGy3YGyZGQNQVJ0Ue8Y-26B7oyZoqnjH8=.4e68efb1-f6d8-42c3-abf0-881b872886e2@github.com> Message-ID: On Mon, 9 Jan 2023 17:55:05 GMT, Pavel Rappo wrote: >> Jonathan Gibbons has updated the pull request incrementally with five additional commits since the last revision: >> >> - Update copyright years >> - Rename FFFC variable >> Share Markdown parser and renderer in instance of MarkdownHandler >> - Move CommonMark to new internal module. >> Add legal header to imported CommonMark source files >> Always use Text nodes inside AttributeTree values >> Unwrap

from "simple" paragraphs >> - Always use Text nodes inside AttributeTree values >> - Update to CommonMark 0.21. > > src/jdk.internal.md/share/classes/jdk/internal/org/commonmark/internal/util/Html5Entities.java line 47: > >> 45: >> 46: private static final Map NAMED_CHARACTER_REFERENCES = readEntities(); >> 47: private static final String ENTITY_PATH = "/org/commonmark/internal/util/entities.txt"; > > I see that you've added the missing `entities.properties` file, but renamed it to `entities.txt`. IIRC from our offline chat, it's due to how JDK build treats `.properties` files. > > I wonder what would be better: (a) to keep the original extension, but amend the build to ignore this file, or (b) to do what you've done and possibly suggest a PR for CommonMark to do the same. > > On the one hand, it's not a true Java `.properties` file as one might've though from its extension. On the other hand, this change of yours diverge us from the original snapshot of CommonMark. I like your option *(b)* * retain the change to use `entities.txt` * report the issue to CommonMark, if not actually suggest a PR. FWIW, the rename is handled automatically by the process I use to import the source code. I think that automated fix-up is acceptable; manual fix-up that would be needed every time we update the source would not be acceptable. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From duke at openjdk.org Mon Jan 9 18:42:02 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 9 Jan 2023 18:42:02 GMT Subject: Integrated: 8043251: Bogus javac error: required: no arguments, found: no arguments In-Reply-To: References: Message-ID: On Thu, 20 Oct 2022 19:20:07 GMT, Archie L. Cobbs wrote: > We have an error message `compiler.err.cant.apply.symbol` for cases where a method invocation doesn't resolve. It shows the "required" parameters and the "found" parameters, plus a further description of the problem. > > This message being used inappropriately when the problem is actually due to explicitly passed method type parameters instead of regular method parameters. > > For example, if you do this: > > Function f = Function.identity(); > > the error reported is this: > > error: method identity in interface Function cannot be applied to given types; > Function f = Function.identity(); > ^ > required: no arguments > found: no arguments > reason: wrong number of type arguments; required 1 > where T,R are type-variables: > T extends Object declared in interface Function > R extends Object declared in interface Function > > The real error here is `wrong number of type arguments; required 1`, but the `compiler.err.cant.apply.symbol` error message that assumes the problem is with the regular parameters, which it displays. The result is the appearance of the useless and confusing `required` and `found` lines. > > This patch creates an alternate version of that error message (`compiler.err.cant.apply.symbol.noargs`) that omits the `required` and `found` lines, and makes the compiler use this alternate message when the error is due to type parameters (specifically, when the underlying error is "wrong number of type arguments" or "explicit type argument X does not conform to declared bound(s)"). > > This improves the error for example above to this: > > error: method identity in interface Function cannot be applied to given types; > Function f = Function.identity(); > ^ > reason: wrong number of type arguments; required 1 > where T,R are type-variables: > T extends Object declared in interface Function > R extends Object declared in interface Function > 1 error This pull request has now been integrated. Changeset: 679e4858 Author: Archie L. Cobbs Committer: Vicente Romero URL: https://git.openjdk.org/jdk/commit/679e485838881c1364845072af305fb60d95e60a Stats: 47 lines in 6 files changed: 34 ins; 0 del; 13 mod 8043251: Bogus javac error: required: no arguments, found: no arguments Reviewed-by: vromero ------------- PR: https://git.openjdk.org/jdk/pull/10799 From jlahoda at openjdk.org Tue Jan 10 15:58:07 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Tue, 10 Jan 2023 15:58:07 GMT Subject: [jdk20] RFR: 8299849: Revert JDK-8294461: wrong effectively final determination by javac Message-ID: <2qhb3vv_49qFqtNJvEz6FJypnpCgJhatrbppLBWQudk=.b01ce62a-814e-4f57-b253-201702e14f69@github.com> The fix for JDK-8294461 lead to https://bugs.openjdk.org/browse/JDK-8299416, and investigating that, it seems effectively final handling in JLS may need some more analysis. The proposal here is therefore to revert JDK-8294461 (commit b8ad6cd98a7e4b577b888dc5f9d93c2e4d3bf177), and re-apply once it is determined if or what needs to be adjusted in the specification. ------------- Commit messages: - 8299849: Revert JDK-8294461: wrong effectively final determination by javac Changes: https://git.openjdk.org/jdk20/pull/93/files Webrev: https://webrevs.openjdk.org/?repo=jdk20&pr=93&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8299849 Stats: 23 lines in 3 files changed: 2 ins; 17 del; 4 mod Patch: https://git.openjdk.org/jdk20/pull/93.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/93/head:pull/93 PR: https://git.openjdk.org/jdk20/pull/93 From vromero at openjdk.org Tue Jan 10 16:31:52 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 10 Jan 2023 16:31:52 GMT Subject: [jdk20] RFR: 8299849: Revert JDK-8294461: wrong effectively final determination by javac In-Reply-To: <2qhb3vv_49qFqtNJvEz6FJypnpCgJhatrbppLBWQudk=.b01ce62a-814e-4f57-b253-201702e14f69@github.com> References: <2qhb3vv_49qFqtNJvEz6FJypnpCgJhatrbppLBWQudk=.b01ce62a-814e-4f57-b253-201702e14f69@github.com> Message-ID: <5_Iqix3wGQJEPjrVoFPUnw4au7HX34338v7qb1mHiP8=.ee6171d9-d1fa-4edd-935f-40108f336b97@github.com> On Tue, 10 Jan 2023 15:49:36 GMT, Jan Lahoda wrote: > The fix for JDK-8294461 lead to https://bugs.openjdk.org/browse/JDK-8299416, and investigating that, it seems effectively final handling in JLS may need some more analysis. > > The proposal here is therefore to revert JDK-8294461 (commit b8ad6cd98a7e4b577b888dc5f9d93c2e4d3bf177), and re-apply once it is determined if or what needs to be adjusted in the specification. looks good ------------- Marked as reviewed by vromero (Reviewer). PR: https://git.openjdk.org/jdk20/pull/93 From archie.cobbs at gmail.com Tue Jan 10 18:44:26 2023 From: archie.cobbs at gmail.com (Archie Cobbs) Date: Tue, 10 Jan 2023 12:44:26 -0600 Subject: Soliciting opinions on JDK-8219412 In-Reply-To: References: Message-ID: Following up on this... It looks to me like this is pretty much implemented already as part of the JEP 433 "Pattern Matching for switch" preview feature. It appears that TransPatterns.handleSwitch() would DTRT. Currently it's only used if the switch has one or more patterns, but since it's written to handle switches with a combination of patterns and constants, simply feeding it a "traditional" enum switch should accomplish what we want. So that makes this primarily a refactoring task, but one that should probably wait until JEP 433 is out of preview. -Archie On Mon, Jan 9, 2023 at 10:20 AM Archie Cobbs wrote: > Thanks for the comments. Using invokedynamic makes perfect sense! (and I'm > disappointed I didn't think of it :) > > I'll take a look into it and report back. > > -Archie > > On Mon, Jan 9, 2023 at 9:54 AM Maurizio Cimadamore < > maurizio.cimadamore at oracle.com> wrote: > >> I agree with Brian. If we want to fix this and put our hands in the enum >> switch classification, I think the best use of our time would be to tweak >> enum switches to adopt the superior indy-based classification approach, >> which should be immune to the issue you present. >> >> Thanks >> Maurizio >> On 09/01/2023 15:35, Brian Goetz wrote: >> >> Another strategy is to use an `invokedynamic` as a switch classifier. (I >> believe there is even a bootstrap for this implemented somewhere.) >> >> > -- > Archie L. Cobbs > -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Tue Jan 10 18:49:31 2023 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 10 Jan 2023 18:49:31 +0000 Subject: Soliciting opinions on JDK-8219412 In-Reply-To: References: Message-ID: <84e2472e-ce1f-0a1a-1861-f3534b3262f8@oracle.com> Yes, you are correct. The underlying bootstrap is already capable to handle enum constants: https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/lang/runtime/SwitchBootstraps.html#enumSwitch(java.lang.invoke.MethodHandles.Lookup,java.lang.String,java.lang.invoke.MethodType,java.lang.Object...) I also agree that the right time to make the refactoring is when patterns in switch is finalized (as SwitchBootstraps is a preview class). Cheers Maurizio On 10/01/2023 18:44, Archie Cobbs wrote: > Following up on this... > > It looks to me like this is pretty much implemented already as part of > the JEP 433 "Pattern Matching for switch" preview feature. > > It appears that TransPatterns.handleSwitch() would DTRT. Currently > it's only used if the switch has one or more patterns, but since it's > written to handle switches with a combination of patterns and > constants, simply feeding it a "traditional" enum switch should > accomplish what we want. > > So that makes this primarily a refactoring task, but one that should > probably wait until JEP 433 is out of preview. > > -Archie > > On Mon, Jan 9, 2023 at 10:20 AM Archie Cobbs > wrote: > > Thanks for the comments. Using invokedynamic makes perfect sense! > (and I'm disappointed I didn't think of it :) > > I'll take a look into it and report back. > > -Archie > > On Mon, Jan 9, 2023 at 9:54 AM Maurizio Cimadamore > wrote: > > I agree with Brian. If we want to fix this and put our hands > in the enum switch classification, I think the best use of our > time would be to tweak enum switches to adopt the superior > indy-based classification approach, which should be immune to > the issue you present. > > Thanks > Maurizio > > On 09/01/2023 15:35, Brian Goetz wrote: >> Another strategy is to use an `invokedynamic` as a switch >> classifier. ?(I believe there is even a bootstrap for this >> implemented somewhere.) > > > -- > Archie L. Cobbs > > > > -- > Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From mcimadamore at openjdk.org Tue Jan 10 18:52:56 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 10 Jan 2023 18:52:56 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Sat, 7 Jan 2023 21:08:07 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: > > Fix incorrect @bug numbers in unit tests. src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java line 2345: > 2343: if (!innerType.hasTag(CLASS) || !outerType.hasTag(CLASS)) > 2344: return false; > 2345: innerType = erasure(innerType); The javac way to write this would be either to compare types using `Types.isSameType` or to compare the underlying class symbols with == (as class symbols are shared across multiple type instances). src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 85: > 83: * > 84: *

> 85: * When tracking references, we distinguish between direct references and indirect references, I'm trying to understand the code and it's not obvious to me as to where this difference comes into play. I believe (but I'm not sure) the spirit is to treat reference to `this` in the original constructor as "direct" while treat a reference to a parameter "a" in a method called from the constructor, where "a" is assigned "this", as indirect? src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1098: > 1096: private void visitLooped(T tree, Consumer visitor) { > 1097: this.visitScoped(tree, false, t -> { > 1098: while (true) { Why is this needed? Can the tracking state of `this` change after multiple "execution" of the same code? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 10 19:22:58 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 10 Jan 2023 19:22:58 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Mon, 9 Jan 2023 15:03:10 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix incorrect @bug numbers in unit tests. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 85: > >> 83: * >> 84: *

>> 85: * When tracking references, we distinguish between direct references and indirect references, > > I'm trying to understand the code and it's not obvious to me as to where this difference comes into play. I believe (but I'm not sure) the spirit is to treat reference to `this` in the original constructor as "direct" while treat a reference to a parameter "a" in a method called from the constructor, where "a" is assigned "this", as indirect? It's slightly different from that. Considering any of the various things in scope that can point to an object (these are: the current 'this' instance, the current outer 'this' instance, method parameter/variable, method return value, top of Java stack), such a thing has a "direct" reference if it might possibly _directly_ point to the 'this' we're tracking, while a thing has an "indirect" reference if it might possibly point to the 'this' we're tracking through _at least one level of indirection_. This is just an attempt to eliminate some false positives by distinguishing between those two cases. Originally I was going to try to track fields (in a very limited way), and so this distinction was going to be more important, but even without tracking fields it's still useful. For example, if some method invokes `x.y.foo()` and `x` represents a direct but not an indirect 'this' reference, then there is no leak declared. Considering the other options... (a) if you only track direct references, then you suffer from more false negatives (how many? unclear); (b) if you lump direct and indirect references into one bucket, then you suffer from more false positives (as in previous example `x.y.foo()`). You can see an example of an indirect reference being tracked and exposed in the unit test `ThisEscapeArrayElement.java`. Another motivating example is lambdas. The act of simply _creating_ a lambda never creates a leak, and a lambda never represents a _direct_ reference. But it might represent an _indirect_ reference. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1098: > >> 1096: private void visitLooped(T tree, Consumer visitor) { >> 1097: this.visitScoped(tree, false, t -> { >> 1098: while (true) { > > Why is this needed? Can the tracking state of `this` change after multiple "execution" of the same code? Yes, because the 'this' reference can bounce around through different variables in scope each time around the loop. So we have to repeat the loop until all 'this' references have "flooded" into all the nooks and crannies. The `ThisEscapeLoop.java` unit test demonstrates: public class ThisEscapeLoop { public ThisEscapeLoop() { ThisEscapeLoop ref1 = this; ThisEscapeLoop ref2 = null; ThisEscapeLoop ref3 = null; ThisEscapeLoop ref4 = null; for (int i = 0; i < 100; i++) { ref4 = ref3; ref3 = ref2; ref2 = ref1; if (ref4 != null) ref4.mightLeak(); } } public void mightLeak() { } } ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 10 19:44:56 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 10 Jan 2023 19:44:56 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Mon, 9 Jan 2023 14:23:47 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix incorrect @bug numbers in unit tests. > > src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java line 2345: > >> 2343: if (!innerType.hasTag(CLASS) || !outerType.hasTag(CLASS)) >> 2344: return false; >> 2345: innerType = erasure(innerType); > > The javac way to write this would be either to compare types using `Types.isSameType` or to compare the underlying class symbols with == (as class symbols are shared across multiple type instances). OK I'm glad you pointed that out because I'm a little unclear on the best way to do this bit. Just to confirm, you are saying that this: `if (erasure(type).equalsIgnoreMetadata(outerType)) {` should be replaced with this? `if (isSameType(type, outerType)) {` ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 10 20:22:16 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 10 Jan 2023 20:22:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v6] In-Reply-To: References: Message-ID: <-cVR0e9azbb3U9vWObNm1dBbUGIDuI7T6bAOpuPSG8I=.a55f2d47-00ae-471c-a51c-df638c104487@github.com> > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Add this-escape to the Javadoc list of strings supported by @SuppressWarnings. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/7e2fdb07..d70d12f4 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=04-05 Stats: 1 line in 1 file changed: 1 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Tue Jan 10 23:41:19 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 10 Jan 2023 23:41:19 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: <0Hksmg2eLQg0c9W5CB6y6dXw2vaEXxy-UY9_D0DtLQY=.351da0ec-208c-4f8d-bf16-318de07ca63e@github.com> On Tue, 10 Jan 2023 19:42:06 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java line 2345: >> >>> 2343: if (!innerType.hasTag(CLASS) || !outerType.hasTag(CLASS)) >>> 2344: return false; >>> 2345: innerType = erasure(innerType); >> >> The javac way to write this would be either to compare types using `Types.isSameType` or to compare the underlying class symbols with == (as class symbols are shared across multiple type instances). > > OK I'm glad you pointed that out because I'm a little unclear on the best way to do this bit. > > Just to confirm, you are saying that this: > > `if (erasure(type).equalsIgnoreMetadata(outerType)) {` > > should be replaced with this? > > `if (isSameType(type, outerType)) {` yes ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Tue Jan 10 23:49:12 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 10 Jan 2023 23:49:12 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: <8PxlV-Syo2Y48TBgSQupSjArfJxMqnA8BZQIYTfYGPA=.057f204c-330b-4fb9-96e5-f8dc8fe348aa@github.com> On Tue, 10 Jan 2023 19:18:04 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 85: >> >>> 83: * >>> 84: *

>>> 85: * When tracking references, we distinguish between direct references and indirect references, >> >> I'm trying to understand the code and it's not obvious to me as to where this difference comes into play. I believe (but I'm not sure) the spirit is to treat reference to `this` in the original constructor as "direct" while treat a reference to a parameter "a" in a method called from the constructor, where "a" is assigned "this", as indirect? > > It's slightly different from that. > > Considering any of the various things in scope that can point to an object (these are: the current 'this' instance, the current outer 'this' instance, method parameter/variable, method return value, top of Java stack), such a thing has a "direct" reference if it might possibly _directly_ point to the 'this' we're tracking, while a thing has an "indirect" reference if it might possibly point to the 'this' we're tracking through _at least one level of indirection_. > > This is just an attempt to eliminate some false positives by distinguishing between those two cases. Originally I was going to try to track fields (in a very limited way), and so this distinction was going to be more important, but even without tracking fields it's still useful. For example, if some method invokes `x.y.foo()` and `x` represents a direct but not an indirect 'this' reference, then there is no leak declared. > > Considering the other options... (a) if you only track direct references, then you suffer from more false negatives (how many? unclear); (b) if you lump direct and indirect references into one bucket, then you suffer from more false positives (as in previous example `x.y.foo()`). > > You can see an example of an indirect reference being tracked and exposed in the unit test `ThisEscapeArrayElement.java`. > > Another motivating example is lambdas. The act of simply _creating_ a lambda never creates a leak, and a lambda never represents a _direct_ reference. But it might represent an _indirect_ reference. So, if I understand correctly your array element test, when we have `new Object[][] { { this } }` the analysis is able to detect that there might be some direct reference nested inside the array. So the outer array is an indirect reference. The inner array is also an indirect reference - but any element accessed on the inner array are direct reference - and so you detect a leak there. Correct? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 00:07:14 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 00:07:14 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <8PxlV-Syo2Y48TBgSQupSjArfJxMqnA8BZQIYTfYGPA=.057f204c-330b-4fb9-96e5-f8dc8fe348aa@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <8PxlV-Syo2Y48TBgSQupSjArfJxMqnA8BZQIYTfYGPA=.057f204c-330b-4fb9-96e5-f8dc8fe348aa@github.com> Message-ID: On Tue, 10 Jan 2023 23:45:59 GMT, Maurizio Cimadamore wrote: >> It's slightly different from that. >> >> Considering any of the various things in scope that can point to an object (these are: the current 'this' instance, the current outer 'this' instance, method parameter/variable, method return value, top of Java stack), such a thing has a "direct" reference if it might possibly _directly_ point to the 'this' we're tracking, while a thing has an "indirect" reference if it might possibly point to the 'this' we're tracking through _at least one level of indirection_. >> >> This is just an attempt to eliminate some false positives by distinguishing between those two cases. Originally I was going to try to track fields (in a very limited way), and so this distinction was going to be more important, but even without tracking fields it's still useful. For example, if some method invokes `x.y.foo()` and `x` represents a direct but not an indirect 'this' reference, then there is no leak declared. >> >> Considering the other options... (a) if you only track direct references, then you suffer from more false negatives (how many? unclear); (b) if you lump direct and indirect references into one bucket, then you suffer from more false positives (as in previous example `x.y.foo()`). >> >> You can see an example of an indirect reference being tracked and exposed in the unit test `ThisEscapeArrayElement.java`. >> >> Another motivating example is lambdas. The act of simply _creating_ a lambda never creates a leak, and a lambda never represents a _direct_ reference. But it might represent an _indirect_ reference. > > So, if I understand correctly your array element test, when we have `new Object[][] { { this } }` the analysis is able to detect that there might be some direct reference nested inside the array. So the outer array is an indirect reference. The inner array is also an indirect reference - but any element accessed on the inner array are direct reference - and so you detect a leak there. Correct? Yes - although it's not tracked being tracked any more precisely than "one or more levels of indirection". And of course by "reference" we only mean "the possibility of a reference" - in general we don't know for sure. Here's the logic: * The analysis knows `this` is a direct reference * Therefore the array expression `{ this }` has an indirect reference (but no direct reference) * The outer array expression `{ { this } }` therefore _also_ has an indirect reference (but no direct reference) At this point, we don't know how many levels of indirection there are in `array` though.... only that its ? 1. * There expression `array[0]` therefore is determined to have both direct and indirect references (they are both _possible_ because we've dereferenced something with an indirect reference) * As does `array[0][0]` for the same reason So invoking `array[0][0].hashCode()` means invoking `hashCode()` on something that has a possible direct reference, and is therefore a leak. Note that because of the imprecision in the number of levels of indirection, invoking `array[0].hashCode()` would also have generated a warning - but in that case, a false positive. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Wed Jan 11 00:07:15 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 00:07:15 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Tue, 10 Jan 2023 19:20:35 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1098: >> >>> 1096: private void visitLooped(T tree, Consumer visitor) { >>> 1097: this.visitScoped(tree, false, t -> { >>> 1098: while (true) { >> >> Why is this needed? Can the tracking state of `this` change after multiple "execution" of the same code? > > Yes, because the 'this' reference can bounce around through different variables in scope each time around the loop. So we have to repeat the loop until all 'this' references have "flooded" into all the nooks and crannies. > > The `ThisEscapeLoop.java` unit test demonstrates: > > public class ThisEscapeLoop { > > public ThisEscapeLoop() { > ThisEscapeLoop ref1 = this; > ThisEscapeLoop ref2 = null; > ThisEscapeLoop ref3 = null; > ThisEscapeLoop ref4 = null; > for (int i = 0; i < 100; i++) { > ref4 = ref3; > ref3 = ref2; > ref2 = ref1; > if (ref4 != null) > ref4.mightLeak(); > } > } > > public void mightLeak() { > } > } So, if the code was be like this: ThisEscapeLoop ref11 = this; ThisEscapeLoop ref12 = null; ThisEscapeLoop ref13 = null; ThisEscapeLoop ref14 = null; for (int i = 0; i < 100; i++) { ref14 = ref13; ref13 = ref12; ref12 = ref11; ThisEscapeLoop ref21 = ref14; ThisEscapeLoop ref22 = null; ThisEscapeLoop ref23 = null; ThisEscapeLoop ref24 = null; for (int i = 0; i < 100; i++) { ref24 = ref23; ref23 = ref22; ref22 = ref21; if (ref24 != null) ref24.mightLeak(); } } Then it would take not 3 iterations but 3 * 3 to figure out that it is a potential leak? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 00:25:10 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 00:25:10 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Wed, 11 Jan 2023 00:04:14 GMT, Maurizio Cimadamore wrote: >> Yes, because the 'this' reference can bounce around through different variables in scope each time around the loop. So we have to repeat the loop until all 'this' references have "flooded" into all the nooks and crannies. >> >> The `ThisEscapeLoop.java` unit test demonstrates: >> >> public class ThisEscapeLoop { >> >> public ThisEscapeLoop() { >> ThisEscapeLoop ref1 = this; >> ThisEscapeLoop ref2 = null; >> ThisEscapeLoop ref3 = null; >> ThisEscapeLoop ref4 = null; >> for (int i = 0; i < 100; i++) { >> ref4 = ref3; >> ref3 = ref2; >> ref2 = ref1; >> if (ref4 != null) >> ref4.mightLeak(); >> } >> } >> >> public void mightLeak() { >> } >> } > > So, if the code was be like this: > > > ThisEscapeLoop ref11 = this; > ThisEscapeLoop ref12 = null; > ThisEscapeLoop ref13 = null; > ThisEscapeLoop ref14 = null; > for (int i = 0; i < 100; i++) { > ref14 = ref13; > ref13 = ref12; > ref12 = ref11; > ThisEscapeLoop ref21 = ref14; > ThisEscapeLoop ref22 = null; > ThisEscapeLoop ref23 = null; > ThisEscapeLoop ref24 = null; > for (int i = 0; i < 100; i++) { > ref24 = ref23; > ref23 = ref22; > ref22 = ref21; > if (ref24 != null) > ref24.mightLeak(); > } > } > > > Then it would take not 3 iterations but 3 * 3 to figure out that it is a potential leak? Actually I think it would take 1 + 1 + 3 iterations. During the first two iterations of the outer loop, nothing changes after the first go round of the inner loop - i.e., the total set of possible references in existence does not change, because all of the assignments in the inner loop won't involve any 'this' references. It's only the during the third iteration of the outer loop that any 'this' references seep into any of the variables seen by the inner loop. Then it will take 3 cycles for the reference set to converge again. However, this is not to say that there aren't some pathological examples out there. I guess the question is could they exist in "normal" code. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 03:30:03 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 03:30:03 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: - Use the more appropriate Type comparison method Types.isSameType(). - Add some more comments to clarify how the analysis works. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/d70d12f4..6e96a7d7 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=06 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=05-06 Stats: 31 lines in 2 files changed: 16 ins; 10 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 03:30:05 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 03:30:05 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <0Hksmg2eLQg0c9W5CB6y6dXw2vaEXxy-UY9_D0DtLQY=.351da0ec-208c-4f8d-bf16-318de07ca63e@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0Hksmg2eLQg0c9W5CB6y6dXw2vaEXxy-UY9_D0DtLQY=.351da0ec-208c-4f8d-bf16-318de07ca63e@github.com> Message-ID: <7jUSzUYT_eWYGbHkDes10f2-1i5DNdmDGDACe8qsXU4=.5bca0f1b-e004-48bc-87e0-48d6fb9deb96@github.com> On Tue, 10 Jan 2023 23:38:14 GMT, Maurizio Cimadamore wrote: >> OK I'm glad you pointed that out because I'm a little unclear on the best way to do this bit. >> >> Just to confirm, you are saying that this: >> >> `if (erasure(type).equalsIgnoreMetadata(outerType)) {` >> >> should be replaced with this? >> >> `if (isSameType(type, outerType)) {` > > yes Thanks... updated in `6e96a7d76f8`. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jlahoda at openjdk.org Wed Jan 11 07:25:23 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Wed, 11 Jan 2023 07:25:23 GMT Subject: RFR: 8299902: Support for MarkDown javadoc in JShell Message-ID: Adding support for MarkDown javadoc in the JShell ------------- Depends on: https://git.openjdk.org/jdk/pull/11701 Commit messages: - Cleanup. - Post-merge updates. - Merge branch '8298405.doclet-markdown' into markdown-in-jshell - Improving handling of new trees. - Prototype of MarkDown javadoc support for JShell. Changes: https://git.openjdk.org/jdk/pull/11936/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11936&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8299902 Stats: 1705 lines in 9 files changed: 947 ins; 752 del; 6 mod Patch: https://git.openjdk.org/jdk/pull/11936.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11936/head:pull/11936 PR: https://git.openjdk.org/jdk/pull/11936 From jlahoda at openjdk.org Wed Jan 11 07:55:22 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Wed, 11 Jan 2023 07:55:22 GMT Subject: [jdk20] Integrated: 8299849: Revert JDK-8294461: wrong effectively final determination by javac In-Reply-To: <2qhb3vv_49qFqtNJvEz6FJypnpCgJhatrbppLBWQudk=.b01ce62a-814e-4f57-b253-201702e14f69@github.com> References: <2qhb3vv_49qFqtNJvEz6FJypnpCgJhatrbppLBWQudk=.b01ce62a-814e-4f57-b253-201702e14f69@github.com> Message-ID: On Tue, 10 Jan 2023 15:49:36 GMT, Jan Lahoda wrote: > The fix for JDK-8294461 lead to https://bugs.openjdk.org/browse/JDK-8299416, and investigating that, it seems effectively final handling in JLS may need some more analysis. > > The proposal here is therefore to revert JDK-8294461 (commit b8ad6cd98a7e4b577b888dc5f9d93c2e4d3bf177), and re-apply once it is determined if or what needs to be adjusted in the specification. This pull request has now been integrated. Changeset: 636976ad Author: Jan Lahoda URL: https://git.openjdk.org/jdk20/commit/636976ada8773474a5540234a38667668349b30b Stats: 23 lines in 3 files changed: 2 ins; 17 del; 4 mod 8299849: Revert JDK-8294461: wrong effectively final determination by javac Reviewed-by: vromero ------------- PR: https://git.openjdk.org/jdk20/pull/93 From jlaskey at openjdk.org Wed Jan 11 13:57:29 2023 From: jlaskey at openjdk.org (Jim Laskey) Date: Wed, 11 Jan 2023 13:57:29 GMT Subject: RFR: JDK-8285932 Implementation of JEP 430 String Templates (Preview) [v33] In-Reply-To: References: Message-ID: > Enhance the Java programming language with string templates, which are similar to string literals but contain embedded expressions. A string template is interpreted at run time by replacing each expression with the result of evaluating that expression, possibly after further validation and transformation. This is a [preview language feature and API](http://openjdk.java.net/jeps/12). Jim Laskey has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 48 commits: - Merge branch 'master' into 8285932 - Merge branch 'master' into 8285932 - FormatProcessor changes - Update @since - Requested changes #12 - Seal Digits - Requested changes #11 - Typo - Requested changes #10 - Requested changes #9 - ... and 38 more: https://git.openjdk.org/jdk/compare/87238470...098467f0 ------------- Changes: https://git.openjdk.org/jdk/pull/10889/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=10889&range=32 Stats: 9519 lines in 81 files changed: 9356 ins; 28 del; 135 mod Patch: https://git.openjdk.org/jdk/pull/10889.diff Fetch: git fetch https://git.openjdk.org/jdk pull/10889/head:pull/10889 PR: https://git.openjdk.org/jdk/pull/10889 From jlaskey at openjdk.org Wed Jan 11 14:07:53 2023 From: jlaskey at openjdk.org (Jim Laskey) Date: Wed, 11 Jan 2023 14:07:53 GMT Subject: RFR: JDK-8285932 Implementation of JEP 430 String Templates (Preview) [v34] In-Reply-To: References: Message-ID: > Enhance the Java programming language with string templates, which are similar to string literals but contain embedded expressions. A string template is interpreted at run time by replacing each expression with the result of evaluating that expression, possibly after further validation and transformation. This is a [preview language feature and API](http://openjdk.java.net/jeps/12). Jim Laskey has updated the pull request incrementally with one additional commit since the last revision: Update to JDK 21 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/10889/files - new: https://git.openjdk.org/jdk/pull/10889/files/098467f0..57638f97 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=10889&range=33 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=10889&range=32-33 Stats: 7 lines in 7 files changed: 0 ins; 0 del; 7 mod Patch: https://git.openjdk.org/jdk/pull/10889.diff Fetch: git fetch https://git.openjdk.org/jdk pull/10889/head:pull/10889 PR: https://git.openjdk.org/jdk/pull/10889 From mcimadamore at openjdk.org Wed Jan 11 14:15:18 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 14:15:18 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Wed, 11 Jan 2023 00:22:03 GMT, Archie L. Cobbs wrote: >> So, if the code was be like this: >> >> >> ThisEscapeLoop ref11 = this; >> ThisEscapeLoop ref12 = null; >> ThisEscapeLoop ref13 = null; >> ThisEscapeLoop ref14 = null; >> for (int i = 0; i < 100; i++) { >> ref14 = ref13; >> ref13 = ref12; >> ref12 = ref11; >> ThisEscapeLoop ref21 = ref14; >> ThisEscapeLoop ref22 = null; >> ThisEscapeLoop ref23 = null; >> ThisEscapeLoop ref24 = null; >> for (int i = 0; i < 100; i++) { >> ref24 = ref23; >> ref23 = ref22; >> ref22 = ref21; >> if (ref24 != null) >> ref24.mightLeak(); >> } >> } >> >> >> Then it would take not 3 iterations but 3 * 3 to figure out that it is a potential leak? > > Actually I think it would take 1 + 1 + 3 iterations. > > During the first two iterations of the outer loop, nothing changes after the first go round of the inner loop - i.e., the total set of possible references in existence does not change, because all of the assignments in the inner loop won't involve any 'this' references. > > It's only the during the third iteration of the outer loop that any 'this' references seep into any of the variables seen by the inner loop. Then it will take 3 cycles for the reference set to converge again. > > However, this is not to say that there aren't some pathological examples out there. I guess the question is could they exist in "normal" code. True - probably 3 * 3 can be achieved if this: ThisEscapeLoop ref21 = ref14; Is replaced with ThisEscapeLoop ref21 = this; In which case the inner loop won't converge immediately (as it will have to propagate from ref21 to ref22 to ref23 to ref24). I guess what I'm uncomfortable with is that we have effectively unbounded computation here (especially when we also consider the fact that the analysis "follows" method bodies as well, if they are found in the same compilation unit). I suggest one experiment where you: 1. downgrade the warnings to notes (so that they won't make the JDK build fail) 2. enable this Lint everywhere 3. compare JDK `clean images` time w/ and w/o the Lint ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Wed Jan 11 16:02:16 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 16:02:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. More questions. Let's say that we only tracked escaping of direct references to `this`. Do you have any sense of how many "less" warnings would be reported in real code (e.g. JDK) ? What I mean by this - let's say that we don't care about tracking _where_ `this` ends up going exactly (e.g. if it's aliased by another variable) - and perhaps also let's say we don't care about inspecting the method to which `this` is leaked too closely - e.g. we treat any early escape of `this` as a possible issue. Of course you could construct examples (like your tests) in which such a simplistic analysis would be defeated. What I'm interested in though is what incremental improvement is brought by the more complex analysis you have in this PR? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Wed Jan 11 16:17:16 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 16:17:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Wed, 11 Jan 2023 14:12:46 GMT, Maurizio Cimadamore wrote: >> Actually I think it would take 1 + 1 + 3 iterations. >> >> During the first two iterations of the outer loop, nothing changes after the first go round of the inner loop - i.e., the total set of possible references in existence does not change, because all of the assignments in the inner loop won't involve any 'this' references. >> >> It's only the during the third iteration of the outer loop that any 'this' references seep into any of the variables seen by the inner loop. Then it will take 3 cycles for the reference set to converge again. >> >> However, this is not to say that there aren't some pathological examples out there. I guess the question is could they exist in "normal" code. > > True - probably 3 * 3 can be achieved if this: > > > ThisEscapeLoop ref21 = ref14; > > Is replaced with > > > ThisEscapeLoop ref21 = this; > > > In which case the inner loop won't converge immediately (as it will have to propagate from ref21 to ref22 to ref23 to ref24). > > I guess what I'm uncomfortable with is that we have effectively unbounded computation here (especially when we also consider the fact that the analysis "follows" method bodies as well, if they are found in the same compilation unit). > > I suggest one experiment where you: > 1. downgrade the warnings to notes (so that they won't make the JDK build fail) > 2. enable this Lint everywhere > 3. compare JDK `clean images` time w/ and w/o the Lint Also, looking at the loop test more closely, it seems to me that what the compiler needs to do is to prove that there can be possible paths by which a `this` can land into ref4. If we build a graph of all the assignments, we get: ref4 <- ref3 <- ref2 <- ref1 <- this So, if we ask "can ref4 possibly contain `this`?" we could "walk" the variable dependencies backwards and discover that, yes, there exist a possible path in which `this` would get there. Now, of course without a loop this can never be a real issue (since you can never send a `this` fully down the chain) - but again, this is a question of how much effort should be spend to handle false negatives in what look like a pathological case. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jwilhelm at openjdk.org Wed Jan 11 17:56:07 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Wed, 11 Jan 2023 17:56:07 GMT Subject: RFR: Merge jdk20 Message-ID: Forwardport JDK 20 -> JDK 21 ------------- Commit messages: - Merge remote-tracking branch 'jdk20/master' into Merge_jdk20 - 8299862: OfAddress setter should disallow heap segments - 8299849: Revert JDK-8294461: wrong effectively final determination by javac - 8299227: host `exif.org` not found in link in doc comment - 8299715: IR test: VectorGatherScatterTest.java fails with SVE randomly - 8294744: AArch64: applications/kitchensink/Kitchensink.java crashed: assert(oopDesc::is_oop(obj)) failed: not an oop - 8299733: AArch64: "unexpected literal addressing mode" assertion failure with -XX:+PrintC1Statistics - 8299693: Change to Xcode12.4+1.1 devkit for building on macOS at Oracle The webrevs contain the adjustments done while merging with regards to each parent branch: - master: https://webrevs.openjdk.org/?repo=jdk&pr=11952&range=00.0 - jdk20: https://webrevs.openjdk.org/?repo=jdk&pr=11952&range=00.1 Changes: https://git.openjdk.org/jdk/pull/11952/files Stats: 98 lines in 16 files changed: 53 ins; 19 del; 26 mod Patch: https://git.openjdk.org/jdk/pull/11952.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11952/head:pull/11952 PR: https://git.openjdk.org/jdk/pull/11952 From duke at openjdk.org Wed Jan 11 18:47:14 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 18:47:14 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> On Wed, 11 Jan 2023 16:14:24 GMT, Maurizio Cimadamore wrote: >> True - probably 3 * 3 can be achieved if this: >> >> >> ThisEscapeLoop ref21 = ref14; >> >> Is replaced with >> >> >> ThisEscapeLoop ref21 = this; >> >> >> In which case the inner loop won't converge immediately (as it will have to propagate from ref21 to ref22 to ref23 to ref24). >> >> I guess what I'm uncomfortable with is that we have effectively unbounded computation here (especially when we also consider the fact that the analysis "follows" method bodies as well, if they are found in the same compilation unit). >> >> I suggest one experiment where you: >> 1. downgrade the warnings to notes (so that they won't make the JDK build fail) >> 2. enable this Lint everywhere >> 3. compare JDK `clean images` time w/ and w/o the Lint > > Also, looking at the loop test more closely, it seems to me that what the compiler needs to do is to prove that there can be possible paths by which a `this` can land into ref4. > > If we build a graph of all the assignments, we get: > > ref4 <- ref3 <- ref2 <- ref1 <- this > > So, if we ask "can ref4 possibly contain `this`?" we could "walk" the variable dependencies backwards and discover that, yes, there exist a possible path in which `this` would get there. > > Now, of course without a loop this can never be a real issue (since you can never send a `this` fully down the chain) - but again, this is a question of how much effort should be spend to handle false negatives in what look like a pathological case. Good idea. Looks like the difference is in the noise, at least on my Macbook: Builds of master (jdk-21+3-69-gc6588d5bb3f) ================================== Build times: real 2m24.650s user 13m46.727s sys 2m33.554s real 2m27.224s user 13m43.464s sys 2m37.251s real 2m26.658s user 13m42.578s sys 2m36.133s Builds of ThisEscape (jdk-21+3-125-g6e96a7d76f8) ================================== Modifications: - Reverted files in the make/ subdirectory to enable warning - Commented out lines 363-382 in ThisEscapeAnalyzer.java so no warnings are actually reported Build times: real 2m25.912s user 13m45.860s sys 2m32.741s real 2m27.213s user 13m44.830s sys 2m36.596s real 2m25.756s user 13m42.889s sys 2m35.659s ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 19:13:16 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 19:13:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> Message-ID: On Wed, 11 Jan 2023 18:44:20 GMT, Archie L. Cobbs wrote: >> Also, looking at the loop test more closely, it seems to me that what the compiler needs to do is to prove that there can be possible paths by which a `this` can land into ref4. >> >> If we build a graph of all the assignments, we get: >> >> ref4 <- ref3 <- ref2 <- ref1 <- this >> >> So, if we ask "can ref4 possibly contain `this`?" we could "walk" the variable dependencies backwards and discover that, yes, there exist a possible path in which `this` would get there. >> >> Now, of course without a loop this can never be a real issue (since you can never send a `this` fully down the chain) - but again, this is a question of how much effort should be spend to handle false negatives in what look like a pathological case. > > Good idea. Looks like the difference is in the noise, at least on my Macbook: > > Builds of master (jdk-21+3-69-gc6588d5bb3f) > ================================== > > Build times: > > real 2m24.650s > user 13m46.727s > sys 2m33.554s > > real 2m27.224s > user 13m43.464s > sys 2m37.251s > > real 2m26.658s > user 13m42.578s > sys 2m36.133s > > Builds of ThisEscape (jdk-21+3-125-g6e96a7d76f8) > ================================== > > Modifications: > > - Reverted files in the make/ subdirectory to enable warning > - Commented out lines 363-382 in ThisEscapeAnalyzer.java > so no warnings are actually reported > > Build times: > > real 2m25.912s > user 13m45.860s > sys 2m32.741s > > real 2m27.213s > user 13m44.830s > sys 2m36.596s > > real 2m25.756s > user 13m42.889s > sys 2m35.659s Regarding the assignment graph approach, I think that would work if the references are bouncing around strictly between variables, but what if the chain includes any of the more complicated stuff that is currently being tracked, such as various Java expressions, method invocations, conditionals, etc.? Consider this example: public class ThisEscapeLoop { public ThisEscapeLoop() { ThisEscapeLoop ref1 = this; ThisEscapeLoop ref2 = null; ThisEscapeLoop ref3 = null; ThisEscapeLoop ref4 = null; for (int i = 0; i < 100; i++) { ref4 = this.returnMe(ref3); ref3 = ref2; ref2 = ref1; if (ref4 != null) ref4.mightLeak(); } } public T returnMe(T x) { return x; } public void mightLeak() { } } If you are only looking at variable assignments with values that are other variables, then the chain "breaks" when `ref4` is assigned indirectly via `returnMe()`, and you miss the leak. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 19:47:16 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 19:47:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 15:59:29 GMT, Maurizio Cimadamore wrote: > What I'm interested in though is what incremental improvement is brought by the more complex analysis you have in this PR? It's a good question. Here are some thoughts... One meta-goal is that this analysis be conservative. In other words, if your code does NOT generate any warnings, then you should feel confident that there is a high probability that there are no leaks. This is analogous to how you can be confident that you won't get any `ClassCastExceptions` at runtime if your code doesn't generate any `unchecked` warnings at compile time. I think this point is generally agreed upon. If so, then we would want?any simpler analysis to err on the side of generating more false positives rather than more false negatives. Assuming that, then the question comes down to a trade-off between code complexity vs. rate of false positives. >From my casual looking over the JDK, the current algorithm generates very few false positives - almost all of the warnings represent actual leaks (I'd be interested in any false positives you do see). (Of course, an irony is that most of these leaks have no real-world effect. For example package-private classes in the JDK (a) have already been debugged long ago, so any intra-package bugs due to 'this' escapes have already been fixed; and (b) are unlikely to be subclassed by anyone. And the ones that have a real-world effect (e.g., `HashSet(Collection)`) can't be fixed because of backward compatibility concerns. So this warning is most useful when writing new code.) So the current code is clearly "complex enough" already. FWIW that's ~975 lines of code excluding blank lines and comments. Now to answer your question about a theoretical simpler analysis: > let's say that we don't care about tracking where `this` ends up going exactly (e.g. if it's aliased by another variable) - and perhaps also let's say we don't care about inspecting the method to which `this` is leaked too closely - e.g. we treat any early escape of this as a possible issue. I'm not sure I completely understand the semantics. But are you saying that if a constructor invokes a private or static method, then this simpler analysis would always declare a leak? If that's the case then I think there are a lot of new false positives, because this is common in constructors. I would then worry that if we dilute the warnings with a bunch of new false positives people are just going to get discouraged and turn the warning off completely. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From darcy at openjdk.org Wed Jan 11 20:51:17 2023 From: darcy at openjdk.org (Joe Darcy) Date: Wed, 11 Jan 2023 20:51:17 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. Per the discussion in "Effective Java" on calling overridable methods in a constructor, future refinements of the check under review here could be extended to examine the bodies of clone and readObject methods. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 21:40:59 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 21:40:59 GMT Subject: RFR: 8291154: Create a non static nested class without enclosing class throws VerifyError Message-ID: <6pcn3LwvxoB4pShWt0LB2ZMTGIhubUVChSmA_26dnYE=.e6d99613-9f14-42ff-ac86-c77d8f119277@github.com> The fix for [JDK-8254321](https://bugs.openjdk.org/browse/JDK-8254321) opened a loophole where a Java source file that defines a static nested class `B` that extends a non-static nested class `A` no longer generates an error if `B` is nested within `A`. Here's an example: class StaticNestedNonStaticSuper { public abstract class NonStaticNested { public static class StaticNested extends NonStaticNested { public StaticNested() { // where is StaticNestedNonStaticSuper.this for super() going to come from?? } } } } Of course this is illegal because the non-static nested superclass requires an outer 'this' instance to be passed as the first argument to all of its constructors, but the static nested subclass has no such outer 'this' to provide. The compiler was proceeding anyway, resulting in unverifiable bytecode. This PR adds a check for this situation. The check is added at the point in `Lower.java` where superclass constructor invocations in subclasses of non-static nested classes add the outer 'this' instance as a first parameter to `super()`. I'm not sure if this is the most appropriate location for this additional check, but at least it is in an optimal place to observe the problem when it happens. ------------- Commit messages: - Disallow static nested subclasses of non-static nested classes. Changes: https://git.openjdk.org/jdk/pull/11954/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11954&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8291154 Stats: 28 lines in 3 files changed: 27 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/11954.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11954/head:pull/11954 PR: https://git.openjdk.org/jdk/pull/11954 From mcimadamore at openjdk.org Wed Jan 11 21:48:18 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 21:48:18 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> Message-ID: <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboIFFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> On Wed, 11 Jan 2023 19:10:04 GMT, Archie L. Cobbs wrote: >> Good idea. Looks like the difference is in the noise, at least on my Macbook: >> >> Builds of master (jdk-21+3-69-gc6588d5bb3f) >> ================================== >> >> Build times: >> >> real 2m24.650s >> user 13m46.727s >> sys 2m33.554s >> >> real 2m27.224s >> user 13m43.464s >> sys 2m37.251s >> >> real 2m26.658s >> user 13m42.578s >> sys 2m36.133s >> >> Builds of ThisEscape (jdk-21+3-125-g6e96a7d76f8) >> ================================== >> >> Modifications: >> >> - Reverted files in the make/ subdirectory to enable warning >> - Commented out lines 363-382 in ThisEscapeAnalyzer.java >> so no warnings are actually reported >> >> Build times: >> >> real 2m25.912s >> user 13m45.860s >> sys 2m32.741s >> >> real 2m27.213s >> user 13m44.830s >> sys 2m36.596s >> >> real 2m25.756s >> user 13m42.889s >> sys 2m35.659s > > Regarding the assignment graph approach, I think that would work if the references are bouncing around strictly between variables, but what if the chain includes any of the more complicated stuff that is currently being tracked, such as various Java expressions, method invocations, conditionals, etc.? > > Consider this example: > > public class ThisEscapeLoop { > > public ThisEscapeLoop() { > ThisEscapeLoop ref1 = this; > ThisEscapeLoop ref2 = null; > ThisEscapeLoop ref3 = null; > ThisEscapeLoop ref4 = null; > for (int i = 0; i < 100; i++) { > ref4 = this.returnMe(ref3); > ref3 = ref2; > ref2 = ref1; > if (ref4 != null) > ref4.mightLeak(); > } > } > > public T returnMe(T x) { > return x; > } > > public void mightLeak() { > } > } > > If you are only looking at variable assignments with values that are other variables, then the chain "breaks" when `ref4` is assigned indirectly via `returnMe()`, and you miss the leak. > Good idea. Looks like the difference is in the noise, at least on my Macbook: > > ``` > Builds of master (jdk-21+3-69-gc6588d5bb3f) > ================================== > > Build times: > > real 2m24.650s > user 13m46.727s > sys 2m33.554s > > real 2m27.224s > user 13m43.464s > sys 2m37.251s > > real 2m26.658s > user 13m42.578s > sys 2m36.133s > > Builds of ThisEscape (jdk-21+3-125-g6e96a7d76f8) > ================================== > > Modifications: > > - Reverted files in the make/ subdirectory to enable warning > - Commented out lines 363-382 in ThisEscapeAnalyzer.java > so no warnings are actually reported > > Build times: > > real 2m25.912s > user 13m45.860s > sys 2m32.741s > > real 2m27.213s > user 13m44.830s > sys 2m36.596s > > real 2m25.756s > user 13m42.889s > sys 2m35.659s > ``` Thanks for trying it out - good to know that build time isn't affected. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 21:49:39 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 21:49:39 GMT Subject: RFR: 8291154: Create a non static nested class without enclosing class throws VerifyError [v2] In-Reply-To: <6pcn3LwvxoB4pShWt0LB2ZMTGIhubUVChSmA_26dnYE=.e6d99613-9f14-42ff-ac86-c77d8f119277@github.com> References: <6pcn3LwvxoB4pShWt0LB2ZMTGIhubUVChSmA_26dnYE=.e6d99613-9f14-42ff-ac86-c77d8f119277@github.com> Message-ID: > The fix for [JDK-8254321](https://bugs.openjdk.org/browse/JDK-8254321) opened a loophole where a Java source file that defines a static nested class `B` that extends a non-static nested class `A` no longer generates an error if `B` is nested within `A`. > > Here's an example: > > class StaticNestedNonStaticSuper { > public abstract class NonStaticNested { > public static class StaticNested extends NonStaticNested { > public StaticNested() { > // where is StaticNestedNonStaticSuper.this for super() going to come from?? > } > } > } > } > > > Of course this is illegal because the non-static nested superclass requires an outer 'this' instance to be passed as the first argument to all of its constructors, but the static nested subclass has no such outer 'this' to provide. The compiler was proceeding anyway, resulting in unverifiable bytecode. > > This PR adds a check for this situation. The check is added at the point in `Lower.java` where superclass constructor invocations in subclasses of non-static nested classes add the outer 'this' instance as a first parameter to `super()`. > > I'm not sure if this is the most appropriate location for this additional check, but at least it is in an optimal place to observe the problem when it happens. Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Simplify unit test. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11954/files - new: https://git.openjdk.org/jdk/pull/11954/files/aa380fc4..fc8db589 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11954&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11954&range=00-01 Stats: 6 lines in 1 file changed: 0 ins; 6 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/11954.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11954/head:pull/11954 PR: https://git.openjdk.org/jdk/pull/11954 From mcimadamore at openjdk.org Wed Jan 11 21:54:17 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 21:54:17 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboIFFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Wed, 11 Jan 2023 21:45:20 GMT, Maurizio Cimadamore wrote: >> Regarding the assignment graph approach, I think that would work if the references are bouncing around strictly between variables, but what if the chain includes any of the more complicated stuff that is currently being tracked, such as various Java expressions, method invocations, conditionals, etc.? >> >> Consider this example: >> >> public class ThisEscapeLoop { >> >> public ThisEscapeLoop() { >> ThisEscapeLoop ref1 = this; >> ThisEscapeLoop ref2 = null; >> ThisEscapeLoop ref3 = null; >> ThisEscapeLoop ref4 = null; >> for (int i = 0; i < 100; i++) { >> ref4 = this.returnMe(ref3); >> ref3 = ref2; >> ref2 = ref1; >> if (ref4 != null) >> ref4.mightLeak(); >> } >> } >> >> public T returnMe(T x) { >> return x; >> } >> >> public void mightLeak() { >> } >> } >> >> If you are only looking at variable assignments with values that are other variables, then the chain "breaks" when `ref4` is assigned indirectly via `returnMe()`, and you miss the leak. > >> Good idea. Looks like the difference is in the noise, at least on my Macbook: >> >> ``` >> Builds of master (jdk-21+3-69-gc6588d5bb3f) >> ================================== >> >> Build times: >> >> real 2m24.650s >> user 13m46.727s >> sys 2m33.554s >> >> real 2m27.224s >> user 13m43.464s >> sys 2m37.251s >> >> real 2m26.658s >> user 13m42.578s >> sys 2m36.133s >> >> Builds of ThisEscape (jdk-21+3-125-g6e96a7d76f8) >> ================================== >> >> Modifications: >> >> - Reverted files in the make/ subdirectory to enable warning >> - Commented out lines 363-382 in ThisEscapeAnalyzer.java >> so no warnings are actually reported >> >> Build times: >> >> real 2m25.912s >> user 13m45.860s >> sys 2m32.741s >> >> real 2m27.213s >> user 13m44.830s >> sys 2m36.596s >> >> real 2m25.756s >> user 13m42.889s >> sys 2m35.659s >> ``` > > Thanks for trying it out - good to know that build time isn't affected. > Regarding the assignment graph approach, I think that would work if the references are bouncing around strictly between variables, but what if the chain includes any of the more complicated stuff that is currently being tracked, such as various Java expressions, method invocations, conditionals, etc.? > > Consider this example: > > ```java > public class ThisEscapeLoop { > > public ThisEscapeLoop() { > ThisEscapeLoop ref1 = this; > ThisEscapeLoop ref2 = null; > ThisEscapeLoop ref3 = null; > ThisEscapeLoop ref4 = null; > for (int i = 0; i < 100; i++) { > ref4 = this.returnMe(ref3); > ref3 = ref2; > ref2 = ref1; > if (ref4 != null) > ref4.mightLeak(); > } > } > > public T returnMe(T x) { > return x; > } > > public void mightLeak() { > } > } > ``` > > If you are only looking at variable assignments with values that are other variables, then the chain "breaks" when `ref4` is assigned indirectly via `returnMe()`, and you miss the leak. So, in this example though you are calling an instance method before the object is initialized, which would seem to me like a leak (leaving aside heroics to try and chase the method body and see what the body of the method actually does). And, if the method is static, same story - you are passing `ref3` somewhere else, and `ref3` potentially contains `this`. While I know that this is not perfect, and bound to generate false positives, I get the spirit of my question is, really: is there a (much) simpler scheme we can get away with, which has bounded complexity, and which has the property we care about (which seems to be no false negative). I'm less worried about contrived cases emitting false positives, as it's an optional warning that can be shut down - but I'd like perhaps to move the discussion from trying to detect _precisely_ if the leak happens to try to detect if _potentially_ a leak can happen, and see if there's some simpler analysis that can be used to get there (e.g. one which doesn't require flooding). It's possible that you have already considered all these options and the analysis you have here is the best trade off between complexity and precision - but I'd like to have a better understanding of what the trade offs are, and, more importantly, what happens to real code when we tweak the analysis this or that way (as this is a problem where I feel it's easy to get in the land of diminishing returns). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jwilhelm at openjdk.org Wed Jan 11 21:54:24 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Wed, 11 Jan 2023 21:54:24 GMT Subject: Integrated: Merge jdk20 In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 17:47:27 GMT, Jesper Wilhelmsson wrote: > Forwardport JDK 20 -> JDK 21 This pull request has now been integrated. Changeset: 33f3bd8f Author: Jesper Wilhelmsson URL: https://git.openjdk.org/jdk/commit/33f3bd8fadb26a0f99c6a13474f8676639f91c0c Stats: 98 lines in 16 files changed: 53 ins; 19 del; 26 mod Merge ------------- PR: https://git.openjdk.org/jdk/pull/11952 From duke at openjdk.org Wed Jan 11 22:43:16 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 22:43:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Wed, 11 Jan 2023 21:51:45 GMT, Maurizio Cimadamore wrote: > So, in this example though you are calling an instance method before the object is initialized, which would seem to me like a leak D'oh, you're right. But if you made `returnMe()` static or private then the argument would still hold. > And, if the method is static, same story - you are passing ref3 somewhere else, and ref3 potentially contains this. Not true... static methods are safe to "invoke" because they can't be overridden. When the analyzer "invokes" the method, it will see that all it does with its parameter is return it. In other words, any method (or constructor) in the current compilation unit that can't be overridden is never considered "somewhere else". > While I know that this is not perfect, and bound to generate false positives, I get the spirit of my question is, really: is there a (much) simpler scheme we can get away with, which has bounded complexity, and which has the property we care about (which seems to be no false negative). I'm less worried about contrived cases emitting false positives, as it's an optional warning that can be shut down - but I'd like perhaps to move the discussion from trying to detect precisely if the leak happens to try to detect if potentially a leak can happen, and see if there's some simpler analysis that can be used to get there (e.g. one which doesn't require flooding). It's possible that you have already considered all these options and the analysis you have here is the best trade off between complexity and precision - but I'd like to have a better understanding of what the trade offs are, and, more importantly, what happens to real code when we tweak the analysis this or that way (as this is a problem where I feel it's easy to get in the land of diminishing returns). I can only report from my own experience. I thought about this a bit and tried a few different things and what I ended up was the best I could come up with in terms of that trade-off. Of course there was a good bit of intuition and SWAG'ing in that and also a lot of thought experiments. Of course if you have a clever idea for how to do this in a simpler way that achieves basically the same result, I'm all ears :) But I don't really have an analysis of all the trade-offs. Really, at a certain point I stumbled on what I thought was a fairly straightforward way to achieve a good false negative rate and a very low false positive rate, without a lot of work. And frankly at that point I stopped caring about the question you're asking, although I agree it's certainly interesting from an academic point of view (I'm a practical person). A lot of my initial ideas were too simple for my taste, because I could easily find real-world false negatives. An example of "too simple": at first I was not trying to track an outer 'this'. But I found a lot of constructors out there that instantiate nested classes and then do things with them. Without tracking outer 'this' these would all be missed. To take a random example of that: public class FileChooserDemo extends JPanel implements ActionListener { ... public FileChooserDemo() { ... // create a radio listener to listen to option changes OptionListener optionListener = new OptionListener(); // Create options openRadioButton = new JRadioButton("Open"); openRadioButton.setSelected(true); openRadioButton.addActionListener(optionListener); // <- LEAK HERE ... } private class OptionListener implements ActionListener { ... } } That particular leak is (probably) innocuous, but it still qualifies as a leak and should be reported. Note that failing to track an outer 'this' causes false negatives, which are a bigger problem than false positives. On the flip side, I started out trying to explicitly track field references, but that seemed like more complexity than needed, at least for phase 1, so that was left out. The "flooding" aspect didn't really worry me because the reference set is "append only" and there is small, finite set of possible references at each scope, so it can't really get that out of hand. Testing indeed shows it's not a problem. By the way recursion also "floods" until convergence, just like looping. I would have been pleased to find "a much simpler scheme". But the more I thought about those options, the more I came up with easy misses. And after a certain point, it actually became easier to simply "execute" the code by scanning the AST while carrying around a `Set` to track possible references. It's really that simple. Instead of trying to be "smart" we just let the code tell us what happens. Apologies if this is not a very good answer to your question. In the big picture, the false positive rate is traded-off against code complexity, and we want the best possible trade-off, right? But how are you defining "complexity"? If you really mean performance, then I don't see a problem... the JDK build times are essentially unchanged. If you mean lines of code or whatever, then it doesn't seem inordinate. And the algorithm is more or less just an AST scan, like lots of other examples in the compiler code. So I don't see a problem there either. Yes, there may be a much simpler way that's just as good, but if I could have thought of it I would have already. Perhaps you or someone else has better insight. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 00:18:11 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 00:18:11 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Wed, 11 Jan 2023 22:40:43 GMT, Archie L. Cobbs wrote: > > D'oh, you're right. But if you made `returnMe()` static or private then the argument would still hold. > > > And, if the method is static, same story - you are passing ref3 somewhere else, and ref3 potentially contains this. > > Not true... static methods are safe to "invoke" because they can't be overridden. When the analyzer "invokes" the method, it will see that all it does with its parameter is return it. > So, for static methods, it could go down two ways: either we don't even look at referenced method bodies, give up and just declare "sorry, escaping". Or, if we look into method bodies, and see that the relationship between inner and outer parameter is as simple, it's just like assignment again: ref1 -> ref2 -> ref3 -> x -> ref4 > But I don't really have an analysis of all the trade-offs. Really, at a certain point I stumbled on what I thought was a fairly straightforward way to achieve a good false negative rate and a very low false positive rate, without a lot of work. And frankly at that point I stopped caring about the question you're asking, although I agree it's certainly interesting from an academic point of view (I'm a practical person). The reason I'm asking these questions is that I'm trying to understand which ingredients went into the analysis and why, in order to try and build a mental problem of what the problem that needs to be solved is, what are the constraints, etc. I'm also a practical person :-) and I often find it easier to understand a piece of code if I know some of the reasoning that went behind it, or what's the behavior supposed to be. I do not know, off-hands, whether there is a simpler solution - I was mostly probing for war stories of the kind "I tried X and I got Y", and I apologize if that came off the wrong way. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 02:17:16 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 02:17:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Thu, 12 Jan 2023 00:15:08 GMT, Maurizio Cimadamore wrote: > So, for static methods, it could go down two ways: either we don't even look at referenced method bodies, give up and just declare "sorry, escaping". Or, if we look into method bodies, and see that the relationship between inner and outer parameter is as simple, it's just like assignment again: Right - and just to reconfirm, it's only the non-overridable methods in the same compilation unit that are "invoked" (i.e., analyzed & tracked). Any method that (might) exist in another compilation unit is off limits, so we have to assume the worst case and declare a leak if we are passing it any 'this' references. > in order to try and build a mental problem of what the problem that needs to be solved is Gotcha. Let's be clear about what exactly we're worrying about. It's this situation: You have a class `B extends A`, where `B` and `A` are in different compilation units, and during the `super()` call that constructor `B()` makes to its superclass constructor `A()`, some code in class `B` gets executed (really, it's some field in `B` getting accessed that actually matters) prior to `A()` returning. So the basic goal is to analyze `A` constructors and watch 'this' references until if/when they go to someplace where we can no longer watch them. At that point we have to assume that some code in `B` might get invoked and so we generate a warning. OK, so where can a 'this' reference go? Well, here are all of the possible places a Java reference can exist: 1. On the Java stack (a) The current 'this' instance (b) A method parameter (c) A local variable (d) A temporary value that is part of the current expression being evaluated (e) The return value from a method that just returned (f) A caught exception 1. In a field of some object... (a) A normal field (b) An outer 'this' instance (c) Other synthetic field (e.g., captured free variable) 1. As an element in a reference array 1. In native code as a native reference Those are the only possibilities AFAIK. So one way to locate yourself on the spectrum from "simple" to "complex" is to answer this question: Which of those are you going to try to keep track of, and for each one, how hard are you going to try? The `this-escape` analysis being proposed tracks 1(a-e) and 2(b) pretty closely (it tries hard), and it adds a very course tracking of 2(a-c), and 3 using the notion of indirect references (it doesn't try very hard). We do not track 1(f) or 4. So to think about the overall problem, imagine how you might or might not address all of those cases. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 10:00:21 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 10:00:21 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Thu, 12 Jan 2023 02:14:10 GMT, Archie L. Cobbs wrote: >>> >>> D'oh, you're right. But if you made `returnMe()` static or private then the argument would still hold. >>> >>> > And, if the method is static, same story - you are passing ref3 somewhere else, and ref3 potentially contains this. >>> >>> Not true... static methods are safe to "invoke" because they can't be overridden. When the analyzer "invokes" the method, it will see that all it does with its parameter is return it. >>> >> >> So, for static methods, it could go down two ways: either we don't even look at referenced method bodies, give up and just declare "sorry, escaping". Or, if we look into method bodies, and see that the relationship between inner and outer parameter is as simple, it's just like assignment again: >> >> ref1 -> ref2 -> ref3 -> x -> ref4 >> >>> But I don't really have an analysis of all the trade-offs. Really, at a certain point I stumbled on what I thought was a fairly straightforward way to achieve a good false negative rate and a very low false positive rate, without a lot of work. And frankly at that point I stopped caring about the question you're asking, although I agree it's certainly interesting from an academic point of view (I'm a practical person). >> >> The reason I'm asking these questions is that I'm trying to understand which ingredients went into the analysis and why, in order to try and build a mental problem of what the problem that needs to be solved is, what are the constraints, etc. I'm also a practical person :-) and I often find it easier to understand a piece of code if I know some of the reasoning that went behind it, or what's the behavior supposed to be. >> >> I do not know, off-hands, whether there is a simpler solution - I was mostly probing for war stories of the kind "I tried X and I got Y", and I apologize if that came off the wrong way. > >> So, for static methods, it could go down two ways: either we don't even look at referenced method bodies, give up and just declare "sorry, escaping". Or, if we look into method bodies, and see that the relationship between inner and outer parameter is as simple, it's just like assignment again: > > Right - and just to reconfirm, it's only the non-overridable methods in the same compilation unit that are "invoked" (i.e., analyzed & tracked). Any method that (might) exist in another compilation unit is off limits, so we have to assume the worst case and declare a leak if we are passing it any 'this' references. > >> in order to try and build a mental problem of what the problem that needs to be solved is > > Gotcha. > > Let's be clear about what exactly we're worrying about. It's this situation: You have a class `B extends A`, where `B` and `A` are in different compilation units, and during the `super()` call that constructor `B()` makes to its superclass constructor `A()`, some code in class `B` gets executed (really, it's some field in `B` getting accessed that actually matters) prior to `A()` returning. > > So the basic goal is to analyze `A` constructors and watch 'this' references until if/when they go to someplace where we can no longer watch them. At that point we have to assume that some code in `B` might get invoked and so we generate a warning. > > OK, so where can a 'this' reference go? > > Well, here are all of the possible places a Java reference can exist: > 1. On the Java stack > (a) The current 'this' instance > (b) A method parameter > (c) A local variable > (d) A temporary value that is part of the current expression being evaluated > (e) The return value from a method that just returned > (f) A caught exception > 1. In a field of some object... > (a) A normal field > (b) An outer 'this' instance > (c) Other synthetic field (e.g., captured free variable) > 1. As an element in a reference array > 1. In native code as a native reference > > Those are the only possibilities AFAIK. > > So one way to locate yourself on the spectrum from "simple" to "complex" is to answer this question: Which of those are you going to try to keep track of, and for each one, how hard are you going to try? > > The `this-escape` analysis being proposed tracks 1(a-e) and 2(b) pretty closely (it tries hard), and it adds a very course tracking of 2(a-c), and 3 using the notion of indirect references (it doesn't try very hard). We do not track 1(f) or 4. > > So to think about the overall problem, imagine how you might or might not address all of those cases. > * On the Java stack > (a) The current 'this' instance > (b) A method parameter > (c) A local variable > (d) A temporary value that is part of the current expression being evaluated > (e) The return value from a method that just returned > (f) A caught exception > > * In a field of some object... > (a) A normal field > (b) An outer 'this' instance > (c) Other synthetic field (e.g., captured free variable) > > * As an element in a reference array > > * In native code as a native reference Thanks for the classification. This is helpful. I'm not sure what you mean by (1f). You mean `this` can be embedded in an exception being thrown? Is that different from (2)? Also, it seems to me that (3) is a special case of (2) - in the sense that you can imagine a reference array as a big object that has many fields as there are elements - so the same reasoning applies. When looking at (2d) and (2e) the fact that Javac's AST is not in SSA form means that, yes, we need to track _expressions_ not just variables (e.g. for chains of methods calls, ternary operators and such). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From ihse at openjdk.org Thu Jan 12 12:16:18 2023 From: ihse at openjdk.org (Magnus Ihse Bursie) Date: Thu, 12 Jan 2023 12:16:18 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. FWIW, the make changes look good. I have nothing to say about the actual lint code itself. ------------- Marked as reviewed by ihse (Reviewer). PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 12:31:39 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 12:31:39 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 163: > 161: * invoked from the target constructor; if empty, we're still in the constructor. > 162: */ > 163: private final ArrayDeque callStack = new ArrayDeque<>(); There is a concept of push/popScope and then there's a separate concept of call stack (which is just a list of diagnostic position up to the point). I wonder if this could be better modeled by using a single class e.g. Scope/Frame which has a diagnostic position, plus other useful things. Perhaps it might even be helpful to have a ref set on each scope, so that you don't have to attach a "depth" to each ref - the depth of the ref would be determined by the "scope" in which it appears. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 175: > 173: private DiagnosticPosition[] pendingWarning; > 174: > 175: // These fields are scoped to the CONSTRUCTOR OR INVOKED METHOD BEING ANALYZED Watch out for "all caps" src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 218: > 216: new TreeScanner() { > 217: > 218: private Lint lint = ThisEscapeAnalyzer.this.lint; On a first look I'm not sure about the granularity of suppression here. I believe that suppressing at the class level, or at the constructor level is enough. Allowing to further annotate var declarations and non-constructor methods, while doable, might actually be counter productive - in the sense that the annotation does not occur in the constructor (where you'd want to see it) but in some other method. I think the fact that a constructor is escaping (willingly) should be a visible thing. Something to consider. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 220: > 218: private Lint lint = ThisEscapeAnalyzer.this.lint; > 219: private JCClassDecl currentClass; > 220: private boolean privateOuter; I don't think this is needed - see below src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 227: > 225: final boolean privateOuterPrev = this.privateOuter; > 226: final Lint lintPrev = this.lint; > 227: this.lint = this.lint.augment(tree.sym); general stylistic comment - I see here and everywhere in this class `this.xyz` - this is not the norm in the rest of the javac codebase, and it would be better to replace it with just `xyz` src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 230: > 228: try { > 229: this.currentClass = tree; > 230: this.privateOuter |= tree.sym.isAnonymous(); These can be inlined in the check below src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 270: > 268: final boolean analyzable = this.currentClassIsExternallyExtendable() && > 269: TreeInfo.isConstructor(tree) && > 270: !tree.sym.isPrivate() && Why aren't private constructors analyzed? If we have a class with a private constructor and public static factory invoking said constructor, and the constructor makes `this` escape, isn't that an issue we should detect? src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 294: > 292: !(this.currentClass.sym.isSealed() && this.currentClass.permitting.isEmpty()) && > 293: !(this.currentClass.sym.owner.kind == MTH) && > 294: !this.privateOuter; Here, note that is the owner of the current class symbol is a method, that covers anonymous classes too, which is a part of `privateOuter`. So the only think we need to check here is whether "currentClass" is private, which is a simple predicate. No need to carry `privateOuter` I believe src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 304: > 302: > 303: // We are looking for analyzable constructors only > 304: final Symbol sym = entry.getKey(); This seems unused. And, if so, perhaps we only need a `Set`, not a map. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 348: > 346: final Comparator ordering = (warning1, warning2) -> { > 347: for (int index1 = 0, index2 = 0; true; index1++, index2++) { > 348: final boolean end1 = index1 >= warning1.length; Another stylistic comment - the `final` here is not super helpful. The compiler performs effectively final analysis, so if your locals are only written once, you are good to go - and can even use them inside lambdas. From a documentation perspective it might carry a bit of value, but again, the rest of the javac code generally doesn't do that. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 411: > 409: final boolean referenceExpressionNode; > 410: switch (tree.getTag()) { > 411: case CASE: surprised to see `CASE` here - as that's not an expression src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 444: > 442: if (referenceExpressionNode) { > 443: > 444: // We treat instance methods as having a "value" equal to their instance The comment is slightly misleading - e.g. I'd suggest clarifying "having a "value" whose type is the same as that of the class in which the method is defined" src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 454: > 452: > 453: // If the expression type is incompatible with 'this', discard it > 454: if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) Instead of adding the direct reference, and then having to check if the reference needs to be removed, would it be possible not to add the reference in the first place if the types mismatch? src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 504: > 502: // Recurse on method expression > 503: this.scan(invoke.meth); > 504: final boolean direct = this.refs.remove(ExprRef.direct(this.depth)); Understanding checkpoint. Considering this code: rec.m() There are two cases: * `rec` might be a direct reference to this (e.g. a local) * `rec` might be an indirect reference to this (a lambda containing `this`) So the receiver of the method might be direct or indirect. This will then determine how to interpret `this` in the context of that method analysis - e.g. when we see a `JCIdent` for `this`, we create a direct/indirect `ExprRef` based on what the receiver kind was. Correct? src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 817: > 815: // Methods - the "value" of a non-static method is a reference to its instance > 816: final Symbol sym = tree.sym; > 817: if (sym.kind == MTH) { This is perhaps where filtering based on the declaring class could make sense (to avoid having to filter later) ? Perhaps this could also be centralized - e.g. whenever you create an ExprRef you also pass the type for it, and if the type matches that for the current class you create it and add to the list, otherwise you skip it. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 875: > 873: // Reference to this? > 874: if (tree.name == names._this || tree.name == names._super) { > 875: if (this.refs.contains(ThisRef.direct())) This idiom occurs quite a lot. If I'm correct, this basically amounts at asking as to whether the receiver of the method we're currently evaluating is direct or not (which is an invariant, given a method body - e.g. for a given method this "fact" should stay the same). If that's the case, perhaps capturing this in a flag could be better - then you could have just have a single method e.g. `XYZRef.create(boolean direct)`, and remove the branching (here and elsewhere). src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 900: > 898: final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; > 899: final Type methodOwnerType = sym.owner.type; > 900: if (this.isSubtype(currentClassType, methodOwnerType)) { I believe what you need here is not subtyping but subclassing - see `Symbol.isSubclass` src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 909: > 907: > 908: // Check for implicit outer 'this' reference > 909: if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { Similarly here - look for `Symbol.isEnclosedBy` src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1302: > 1300: * In other words, a reference that's sitting on top of the stack. > 1301: */ > 1302: private static class ExprRef extends Ref { Maybe I'm wrong - but it seems that the only thing we need to track is whether the top of stack (e.g. last evaluated expression) has a direct reference or indirect reference (or none). Do we really need a set for this? (this seems the same as for ThisRef which is used inside method, which can be one of the same three options). While I do see value for tracking which variables are aliases for this (either direct or indirect), it seems like (at least on a superficial look) that expression refs might be replaced by a visitor field/parameter. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1319: > 1317: /** A reference from the return value of the current method being "invoked". > 1318: */ > 1319: private static class ReturnRef extends Ref { Isn't this just an ExprRef? This might also be related with the fact that we deal with return values in different ways than with e.g. values returned from a nested scope (where we just pop, and then copy all pending expression to the outer depth). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 13:04:18 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 13:04:18 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 334: > 332: // of the stack trace of B. For example, if constructor Foo(int x) has a leak, and constructor > 333: // Foo() invokes this(0), then emitting a warning for Foo() would be redundant. > 334: final BiPredicate extendsAsPrefix = (warning1, warning2) -> { Another strategy would be to give a single warning per leaking constructor. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mdegtyarev at gmail.com Thu Jan 12 13:17:06 2023 From: mdegtyarev at gmail.com (Maxim Degtyarev) Date: Thu, 12 Jan 2023 16:17:06 +0300 Subject: Soliciting opinions on JDK-8219412 In-Reply-To: References: Message-ID: > The static argument list identifies the enum constants (by string) corresponding to the case numbers. This will decrease theoretical maximum of switch blocks in enum switch statement due to constant pool size limitations. So it may affect some code with huge switches over enum. On Mon, Jan 9, 2023, 18:35 Brian Goetz wrote: > Another strategy is to use an `invokedynamic` as a switch classifier. (I > believe there is even a bootstrap for this implemented somewhere.) > > The idea is that we lower a switch > > switch (e) [ > case A: ? > case B: ? > ? > } > > Into a compact switch on int, and use an indy to map the target to a case > number: > > switch (indy [BSM=EnumClassifier, type=(E)I, args = [ E.class, ?A?, > ?B?, ? ]) { > case 1: ? > Case 2: ? > } > > The indy bootstrap takes as a dynamic argument the switch operand (enum > value), and returns an int corresponding the case number. The static > argument list identifies the enum constants (by string) corresponding to > the case numbers. The bootstrap builds the array that we would have built > at compile time, curries it onto a method handle, and wraps the method > handle in a ConstantCallSite. Then the array is only built the first time > we invoke the switch. Thereafter we get similar behavior to the current > scheme, but without static initializers. > > > > > > On Jan 9, 2023, at 10:02 AM, Archie Cobbs wrote: > > I'm looking for advice/opinions on the best way to address JDK-8219412 - > Eager enum class initialization with enum switch. > > The problem stems from how the compiler implements switches on enum. The > obvious simple approach is to get the enum's ordinal() value and then > revert to a normal integer value switch. However, this snapshots the > ordinal values at compile-time, and thus can fail if the Enum class is > recompiled later. > Instead the compiler uses a lookup table. This table is dynamically > constructed at runtime by a static initializer in a synthetic class. > When compiling Foo.java, a separate lookup table is created for each enum > type that is switched on anywhere in Foo.java. These lookup tables are all > put into a single synthetic class Foo$1 and are all initialized at the same > time, in a single static initializer. > > Now suppose Foo contains switches on enum types E1, E2, and E3 and a > switch on E1 is encountered. This will cause classes E2 and E3 to be > initialized, even though there is no 'first use' of either class. This is > the bug. > > Strategy #1 - Put each lookup table into a separate synthetic class. > > You can see the reverse of this fix in this diff. > > The upside of this approach is that it fixes the bug without changing the > approach and therefore presumably minimally affecting performance. > > The downside is an increase in the number of synthetic classes created: > for every enum type switched on in Foo.java but declared in some other > source file, there is a synthetic class created: Foo$1, Foo$2, etc. Is that > a show-stopper?? > > The total amount of code generated is basically the same, it's just spread > over multiple class files instead of one. > > Strategy #2 - Switch on String identifiers instead of ordinal values > > This approach is straightforward, however the performance suffers a good > bit in my tests. Probably not an option. > > Strategy #3 - Don't rely on a static initializer to build the mapping > tables > > This approach would mean not relying on class initialization to trigger > building the mapping tables, so we could build each table separately > on demand. The synthetic class would look something like this: > > synthetic /* volatile ? */ int[] $EnumMap$E1; > synthetic /* volatile ? */ int[] $EnumMap$E2; > synthetic /* volatile ? */ int[] $EnumMap$E3; > > static int[] getEnumMap$E1() { > if ($EnumMap$E1 == null) { > /* build map here */ > } > return $EnumMap$E1; > } > > static int[] getEnumMap$E2() { > if ($EnumMap$E2 == null) { > /* build map here */ > } > return $EnumMap$E2; > } > > static int[] getEnumMap$E3() { > if ($EnumMap$E3 == null) { > /* build map here */ > } > return $EnumMap$E3; > } > > Strategy #4 - Other ideas? > > Thanks, > -Archie > > -- > Archie L. Cobbs > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From duke at openjdk.org Thu Jan 12 15:02:22 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 15:02:22 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Thu, 12 Jan 2023 09:57:00 GMT, Maurizio Cimadamore wrote: > I'm not sure what you mean by (1f). You mean this can be embedded in an exception being thrown? Is that different from (2)? Yes, this would be a different case from any other that you'd have to handle in the code if you wanted to deal with it. An example of how this could happen would be: public class ThrownThis extends RuntimeException { public ThrownThis(Object obj) { try { this.validate(obj); } catch (RuntimeException e) { e.mightLeak(); // LEAK HERE } } private void validate(Object obj) { if (obj.hashCode() != 123) throw this; } public void mightLeak() { } } Of course, that's an absurd example and the likelihood that any random piece of actually code does that is negligible. Regardless, I did briefly consider including handling for thrown exceptions but quickly decided it couldn't possibly be worth the trouble. As a result, if you compile that example with `-Xlint:this-escape` you don't get a warning. No major loss! > Also, it seems to me that (3) is a special case of (2) - in the sense that you can imagine a reference array as a big object that has many fields as there are elements - so the same reasoning applies. Yes it's effectively the same thing, but fields and array elements are accessed by different mechanisms in Java, so from the point of the analyzer they have to be handled separately for that reason, which is why I broke them out. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 15:12:56 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 15:12:56 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Thu, 12 Jan 2023 14:59:12 GMT, Archie L. Cobbs wrote: >>> * On the Java stack >>> (a) The current 'this' instance >>> (b) A method parameter >>> (c) A local variable >>> (d) A temporary value that is part of the current expression being evaluated >>> (e) The return value from a method that just returned >>> (f) A caught exception >>> >>> * In a field of some object... >>> (a) A normal field >>> (b) An outer 'this' instance >>> (c) Other synthetic field (e.g., captured free variable) >>> >>> * As an element in a reference array >>> >>> * In native code as a native reference >> >> Thanks for the classification. This is helpful. >> >> I'm not sure what you mean by (1f). You mean `this` can be embedded in an exception being thrown? Is that different from (2)? >> >> Also, it seems to me that (3) is a special case of (2) - in the sense that you can imagine a reference array as a big object that has many fields as there are elements - so the same reasoning applies. >> >> When looking at (2d) and (2e) the fact that Javac's AST is not in SSA form means that, yes, we need to track _expressions_ not just variables (e.g. for chains of methods calls, ternary operators and such). > >> I'm not sure what you mean by (1f). You mean this can be embedded in an exception being thrown? Is that different from (2)? > > Yes, this would be a different case from any other that you'd have to handle in the code if you wanted to deal with it. > > An example of how this could happen would be: > > public class ThrownThis extends RuntimeException { > > public ThrownThis(Object obj) { > try { > this.validate(obj); > } catch (RuntimeException e) { > e.mightLeak(); // LEAK HERE > } > } > > private void validate(Object obj) { > if (obj.hashCode() != 123) > throw this; > } > > public void mightLeak() { > } > } > > Of course, that's an absurd example and the likelihood that any random piece of actually code does that is negligible. > > Regardless, I did briefly consider including handling for thrown exceptions but quickly decided it couldn't possibly be worth the trouble. > > As a result, if you compile that example with `-Xlint:this-escape` you don't get a warning. No major loss! > >> Also, it seems to me that (3) is a special case of (2) - in the sense that you can imagine a reference array as a big object that has many fields as there are elements - so the same reasoning applies. > > Yes it's effectively the same thing, but fields and array elements are accessed by different mechanisms in Java, so from the point of the analyzer they have to be handled separately for that reason, which is why I broke them out. > Yes, this would be a different case from any other that you'd have to handle in the code if you wanted to deal with it. > > An example of how this could happen would be: > > ```java > public class ThrownThis extends RuntimeException { > > public ThrownThis(Object obj) { > try { > this.validate(obj); > } catch (RuntimeException e) { > e.mightLeak(); // LEAK HERE > } > } > > private void validate(Object obj) { > if (obj.hashCode() != 123) > throw this; > } > > public void mightLeak() { > } > } > ``` > Interesting example - I thought you might have been referring to a case where the class being analyzed was itself an exception. Question - shouldn't we conclude that `this` leak when we see `throw this` ? E.g. what if the constructor did not have a `catch` (or if the catch was of a different type) ? > Of course, that's an absurd example and the likelihood that any random piece of actually code does that is negligible. > > Regardless, I did briefly consider including handling for thrown exceptions but quickly decided it couldn't possibly be worth the trouble. > > As a result, if you compile that example with `-Xlint:this-escape` you don't get a warning. No major loss! > > > Also, it seems to me that (3) is a special case of (2) - in the sense that you can imagine a reference array as a big object that has many fields as there are elements - so the same reasoning applies. > > Yes it's effectively the same thing, but fields and array elements are accessed by different mechanisms in Java, so from the point of the analyzer they have to be handled separately for that reason, which is why I broke them out. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 15:19:44 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 15:19:44 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Thu, 12 Jan 2023 13:01:44 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 334: > >> 332: // of the stack trace of B. For example, if constructor Foo(int x) has a leak, and constructor >> 333: // Foo() invokes this(0), then emitting a warning for Foo() would be redundant. >> 334: final BiPredicate extendsAsPrefix = (warning1, warning2) -> { > > Another strategy would be to give a single warning per leaking constructor. We already impose a limit of at most one warning per constructor. But for this limit what is technically meant by "per constructor" is "At most one warning per constructor, assuming that constructor is the one being analyzed (i.e., the one invoked by the subclass and not via `this()`)." So that limitation doesn't stop a constructor from generating the same warning multiple times due to it being invoked indirectly by other constructors via `this()`. Those duplicate warnings are what the code above eliminates. So this code only generates one warning, and it's reported for the second constructor: public class DupWarn1 { public DupWarn1() { this(0); } public DupWarn1(int x) { this.mightLeak(); } public void mightLeak() { } } DupWarn1.java:8: warning: [this-escape] possible 'this' escape before subclass is fully initialized this.mightLeak(); ^ This is appropriate. The leak is really in the second constructor; the first constructor has nothing to do with it. Reporting a leak for both constructors would be redundant. An interesting side question: Is it possible to come up with an example where constructor A has a 'this' leak, and some other constructor B invokes `this()` to delegate to A, but when B delegates to A the leak occurs differently, or not at all? Because of the "flood" analysis, and the fact that you can't pass 'this' references to `this()` or `super()` (these are static contexts), I don't think it's possible. So in fact the deduplication will always apply whenever `this()` is involved. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 15:29:30 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 15:29:30 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Thu, 12 Jan 2023 15:10:19 GMT, Maurizio Cimadamore wrote: > Interesting example - I thought you might have been referring to a case where the class being analyzed was itself an exception. Yes - although that example doesn't compile (oops!). Just replace `catch (RuntimeException e)` with `catch (ThrownThis e)` and it should. > Question - shouldn't we conclude that this leak when we see throw this ? E.g. what if the constructor did not have a catch (or if the catch was of a different type) ? A thorough analysis would evaluate whether the exception was caught or not. But you're right - since we're not doing a thorough analysis, we should immediately declare a leak anytime we see `throw x` where `x` is a possible direct or indirect reference. Of course, this scenario should be unlikely in normal code. I will add a check for that. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 16:06:28 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 16:06:28 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 10:18:27 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 294: > >> 292: !(this.currentClass.sym.isSealed() && this.currentClass.permitting.isEmpty()) && >> 293: !(this.currentClass.sym.owner.kind == MTH) && >> 294: !this.privateOuter; > > Here, note that is the owner of the current class symbol is a method, that covers anonymous classes too, which is a part of `privateOuter`. So the only think we need to check here is whether "currentClass" is private, which is a simple predicate. No need to carry `privateOuter` I believe Unless you explicitly declare a nested class `private`, it won't have the `ACC_PRIVATE` flag, even though it is "implicitly private" because it has a `private` enclosing class. Example: $ cat PrivateOuter.java public class PrivateOuter { private static class Inner1 { static class Inner2 { } } } $ javap -v PrivateOuter$Inner1$Inner2 Classfile /Users/archie/proj/jdk/flex-test/classes/PrivateOuter$Inner1$Inner2.class Last modified Jan 12, 2023; size 408 bytes SHA-256 checksum 51ba6d39a5e66df2a078761d6424acbea7a8e32b8451f6ca7d2af49889673b2c Compiled from "PrivateOuter.java" class PrivateOuter$Inner1$Inner2 minor version: 0 major version: 63 flags: (0x0020) ACC_SUPER this_class: #7 // PrivateOuter$Inner1$Inner2 super_class: #2 // java/lang/Object ... So we have to keep track of this "implicit privateness" manually, which is what the `privateOuter` flag is for. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 16:24:37 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 16:24:37 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> On Thu, 12 Jan 2023 10:25:27 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 218: > >> 216: new TreeScanner() { >> 217: >> 218: private Lint lint = ThisEscapeAnalyzer.this.lint; > > On a first look I'm not sure about the granularity of suppression here. I believe that suppressing at the class level, or at the constructor level is enough. Allowing to further annotate var declarations and non-constructor methods, while doable, might actually be counter productive - in the sense that the annotation does not occur in the constructor (where you'd want to see it) but in some other method. I think the fact that a constructor is escaping (willingly) should be a visible thing. Something to consider. Two things... We need to support annotations on field declarations because their initializers are effectively mini-constructors. But we don't need it on local variables, parameters, etc. - too confusing. For annotations on methods, yes it's debatable. It can be handy if you have e.g. an `init()` method that all of your constructors invoke. However, I agree it's also confusing, so I will remove. But we should keep the notion that if a constructor invokes `this()`, and the invoked constructor has annotations suppressed, then we skip over the constructor invocation. I will make these updates. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 304: > >> 302: >> 303: // We are looking for analyzable constructors only >> 304: final Symbol sym = entry.getKey(); > > This seems unused. And, if so, perhaps we only need a `Set`, not a map. Thanks, you're right, the map keys are not used here. I'll clean up the loop. But we still need a map, not a set, because the map is used elsewhere. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 16:31:21 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 16:31:21 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 10:32:19 GMT, Maurizio Cimadamore wrote: > If we have a class with a private constructor and public static factory invoking said constructor, and the constructor makes this escape, isn't that an issue we should detect? A static factory method will not create a subclassed instance, so there's no 'this' escape problem. But I admit I completely missed factory methods as a potential thing to worry about. Is it possible for a leak to be missed due to the use of a factory method? Hmm. I can't immediately think of how, but if you can come up with an example please share. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 16:46:31 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 16:46:31 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Thu, 12 Jan 2023 16:20:12 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 218: >> >>> 216: new TreeScanner() { >>> 217: >>> 218: private Lint lint = ThisEscapeAnalyzer.this.lint; >> >> On a first look I'm not sure about the granularity of suppression here. I believe that suppressing at the class level, or at the constructor level is enough. Allowing to further annotate var declarations and non-constructor methods, while doable, might actually be counter productive - in the sense that the annotation does not occur in the constructor (where you'd want to see it) but in some other method. I think the fact that a constructor is escaping (willingly) should be a visible thing. Something to consider. > > Two things... > > We need to support annotations on field declarations because their initializers are effectively mini-constructors. But we don't need it on local variables, parameters, etc. - too confusing. > > For annotations on methods, yes it's debatable. It can be handy if you have e.g. an `init()` method that all of your constructors invoke. However, I agree it's also confusing, so I will remove. > > But we should keep the notion that if a constructor invokes `this()`, and the invoked constructor has annotations suppressed, then we skip over the constructor invocation. > > I will make these updates. Yep - I guess there's a general theme of "where do we want the warnings to be reported". My general feeling is that reporting a warning on the constructor might be enough - but I see that you try to generate a warning in the exact spot where the leakage happens - which I'm not sure if it's ok, or too clever. >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 270: >> >>> 268: final boolean analyzable = this.currentClassIsExternallyExtendable() && >>> 269: TreeInfo.isConstructor(tree) && >>> 270: !tree.sym.isPrivate() && >> >> Why aren't private constructors analyzed? If we have a class with a private constructor and public static factory invoking said constructor, and the constructor makes `this` escape, isn't that an issue we should detect? > >> If we have a class with a private constructor and public static factory invoking said constructor, and the constructor makes this escape, isn't that an issue we should detect? > > A static factory method will not create a subclassed instance, so there's no 'this' escape problem. > > But I admit I completely missed factory methods as a potential thing to worry about. > > Is it possible for a leak to be missed due to the use of a factory method? > > Hmm. I can't immediately think of how, but if you can come up with an example please share. I guess what I'm thinking about: class Foo { private Foo() { m(this); } public void m() { ... } // overridable static Foo makeFoo() { return new Foo(); } } >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 294: >> >>> 292: !(this.currentClass.sym.isSealed() && this.currentClass.permitting.isEmpty()) && >>> 293: !(this.currentClass.sym.owner.kind == MTH) && >>> 294: !this.privateOuter; >> >> Here, note that is the owner of the current class symbol is a method, that covers anonymous classes too, which is a part of `privateOuter`. So the only think we need to check here is whether "currentClass" is private, which is a simple predicate. No need to carry `privateOuter` I believe > > Unless you explicitly declare a nested class `private`, it won't have the `ACC_PRIVATE` flag, even though it is "implicitly private" because it has a `private` enclosing class. > > Example: > > $ cat PrivateOuter.java > public class PrivateOuter { > private static class Inner1 { > static class Inner2 { > } > } > } > $ javap -v PrivateOuter$Inner1$Inner2 > Classfile /Users/archie/proj/jdk/flex-test/classes/PrivateOuter$Inner1$Inner2.class > Last modified Jan 12, 2023; size 408 bytes > SHA-256 checksum 51ba6d39a5e66df2a078761d6424acbea7a8e32b8451f6ca7d2af49889673b2c > Compiled from "PrivateOuter.java" > class PrivateOuter$Inner1$Inner2 > minor version: 0 > major version: 63 > flags: (0x0020) ACC_SUPER > this_class: #7 // PrivateOuter$Inner1$Inner2 > super_class: #2 // java/lang/Object > ... > > > So we have to keep track of this "implicit privateness" manually, which is what the `privateOuter` flag is for. D'oh - missed the `|=` - so this keeps updating... ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 16:55:39 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 16:55:39 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 10:48:49 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 227: > >> 225: final boolean privateOuterPrev = this.privateOuter; >> 226: final Lint lintPrev = this.lint; >> 227: this.lint = this.lint.augment(tree.sym); > > general stylistic comment - I see here and everywhere in this class `this.xyz` - this is not the norm in the rest of the javac codebase, and it would be better to replace it with just `xyz` OK. I will reluctantly remove... `` > Why on earth wouldn't you want to make it clear which one of N outer classes a field comes from, and that it's a field, and not a variable declared somewhere off screen?? > > IMHO omitting 'this' qualifiers is effectively accepting the grave offense of code obfuscation in exchange for a tiny smidgen of brevity. > > It's definitely made it harder for me to read and understand the compiler, with all the levels of nesting it has. > `` I readily admit I'm probably in the minority on this and anyway it's a bikeshed thing so there's no point in debating it. I will go with the flow :) though I feel a little sorry for the next person who has to read this code. > From a documentation perspective it might carry a bit of value Yes, that's the purpose - the `final` is for the human viewer, not the compiler. Just trying to be helpful to the next person. But you're right it's inconsistent so I'll remove. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 17:16:34 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 17:16:34 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 10:56:53 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 411: > >> 409: final boolean referenceExpressionNode; >> 410: switch (tree.getTag()) { >> 411: case CASE: > > surprised to see `CASE` here - as that's not an expression I put it there because of switch expressions and `yeild`... ? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Thu Jan 12 17:43:26 2023 From: vromero at openjdk.org (Vicente Romero) Date: Thu, 12 Jan 2023 17:43:26 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 200: > 198: // > 199: > 200: public void analyzeTree(Env env) { nit: this method could be removed in favor of the overloaded version below src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 204: > 202: } > 203: > 204: public void analyzeTree(Env env, JCTree tree) { nit: `env` parameter doesn't seem to be used could be dropped I think ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 17:43:30 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 17:43:30 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 17:13:55 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 411: >> >>> 409: final boolean referenceExpressionNode; >>> 410: switch (tree.getTag()) { >>> 411: case CASE: >> >> surprised to see `CASE` here - as that's not an expression > > I put it there because of switch expressions and `yeild`... ? Well, yield can... yield a value - `case` doesn't. So I'm confused. Also because the variable is called `referenceExpressionNode` and `CASE` is not an expression. Can `CASE` leave anything on the stack? YIELD does, but CASE? >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 454: >> >>> 452: >>> 453: // If the expression type is incompatible with 'this', discard it >>> 454: if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) >> >> Instead of adding the direct reference, and then having to check if the reference needs to be removed, would it be possible not to add the reference in the first place if the types mismatch? > > No because (for example) what if you cast? > > The thing you're casting might be compatible, but after the cast it might become incompatible. Uhm. Turns out I probably did not understand the filter correctly, and now I'm more dubious about what it actually does. Say you have this hierarchy: interface A { } class B { B() { A a = (A)this; ... } } class C extends B implements A { } ``` Pathological case, I know. But the filtering will end up dropping the expression Ref on the floor, right? (because B and A are unrelated). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 17:43:36 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 17:43:36 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 11:09:35 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 444: > >> 442: if (referenceExpressionNode) { >> 443: >> 444: // We treat instance methods as having a "value" equal to their instance > > The comment is slightly misleading - e.g. I'd suggest clarifying "having a "value" whose type is the same as that of the class in which the method is defined" Agreed - will fix. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 454: > >> 452: >> 453: // If the expression type is incompatible with 'this', discard it >> 454: if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) > > Instead of adding the direct reference, and then having to check if the reference needs to be removed, would it be possible not to add the reference in the first place if the types mismatch? No because (for example) what if you cast? The thing you're casting might be compatible, but after the cast it might become incompatible. > This will then determine how to interpret this in the context of that method analysis - e.g. when we see a JCIdent for this, we create a direct/indirect ExprRef based on what the receiver kind was. Correct? Yes, exactly. When we "invoke" a method, we "preload" the set of current references that the method is going to have when it starts. That "preload" step includes any references from (a) the method receiver (non-static methods only) and (b) method parameters. To the extent the method receiver has a direct/indirect reference, that turns into a direct/indirect `ThisRef` during method execution. You can see this happen in the very next lines after what you quoted. But of course the method invocation (the "apply") could have been applied to any arbitrary expression as the receiver. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 817: > >> 815: // Methods - the "value" of a non-static method is a reference to its instance >> 816: final Symbol sym = tree.sym; >> 817: if (sym.kind == MTH) { > > This is perhaps where filtering based on the declaring class could make sense (to avoid having to filter later) ? Perhaps this could also be centralized - e.g. whenever you create an ExprRef you also pass the type for it, and if the type matches that for the current class you create it and add to the list, otherwise you skip it. Yes but see previous comment regarding casting. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 875: > >> 873: // Reference to this? >> 874: if (tree.name == names._this || tree.name == names._super) { >> 875: if (this.refs.contains(ThisRef.direct())) > > This idiom occurs quite a lot. If I'm correct, this basically amounts at asking as to whether the receiver of the method we're currently evaluating is direct or not (which is an invariant, given a method body - e.g. for a given method this "fact" should stay the same). If that's the case, perhaps capturing this in a flag could be better - then you could have just have a single method e.g. `XYZRef.create(boolean direct)`, and remove the branching (here and elsewhere). The code you quoted has nothing specifically to do with method invocations. This code is simply handing the evaluation of the expressions `this` and `super`. For example, `this` could just be a parameter we're passing to another method. When `this` or `super` expressions are evaluated, the thing left on top of the stack is a direct/indirect reference (i.e., an `ExprRef`) exactly when the there is a direct/indirect reference of type `ThisRef` in the current reference set. In cases where `this` is then "invoked", e.g., `this()`, the `ExprRef` (top of Java stack) becomes the method receiver, and when the method is "invoked" it turns back into a `ThisRef` (see earlier question). Regarding the optimization you mention, in light of the above I'm not sure it would still work. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 17:53:25 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 17:53:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 12:15:17 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 175: > >> 173: private DiagnosticPosition[] pendingWarning; >> 174: >> 175: // These fields are scoped to the CONSTRUCTOR OR INVOKED METHOD BEING ANALYZED > > Watch out for "all caps" Will fix. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 900: > >> 898: final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; >> 899: final Type methodOwnerType = sym.owner.type; >> 900: if (this.isSubtype(currentClassType, methodOwnerType)) { > > I believe what you need here is not subtyping but subclassing - see `Symbol.isSubclass` Hmm, I tried using `Symbol.isSubclass()` but it caused test failures. Obviously I don't quite know what I'm doing and I'm loathe to break what is already working. Do you have a suggested patch? > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 909: > >> 907: >> 908: // Check for implicit outer 'this' reference >> 909: if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { > > Similarly here - look for `Symbol.isEnclosedBy` Same comment as previous: I don't quite know what I'm doing and I'm loathe to break what is already working. Do you have a suggested patch? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 18:00:36 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 18:00:36 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 12:17:32 GMT, Maurizio Cimadamore wrote: > There is a concept of push/popScope and then there's a separate concept of call stack (which is just a list of diagnostic position up to the point). I wonder if this could be better modeled by using a single class e.g. Scope/Frame which has a diagnostic position, plus other useful things. I think that would be more confusing, because they're really two different animals. Scopes only have meaning within a single method. They simply serve to bracket the lifetimes of `VarRef` references, following Java curly brace scope. When you "invoke" a method, you put aside the current stack of scopes and start over with an empty scope stack. They don't bridge between methods. Call stacks are just a list of method+code position therein, and they exist outside of any single method. They have nothing to do with Java scopes defined by curly braces. > Perhaps it might even be helpful to have a ref set on each scope, so that you don't have to attach a "depth" to each ref - the depth of the ref would be determined by the "scope" in which it appears. That's another way to skin the same cat... in fact I had a design like that before but then realized it was a lot simpler to just carry around one `RefSet`. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 18:09:27 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 18:09:27 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 12:26:27 GMT, Maurizio Cimadamore wrote: > Do we really need a set for this? There are surely other ways to model things. But I got myself really confused trying to build more complicated models. What I ended up with is this simple model that works: * There is a set of `Ref` subclasses that model the various types of 'this' references possible: `OuterRef`, `ExprRef`, etc. * There is a singleton `this.refs`, which just is a `Set`, containing the 'this' references that are alive at the current moment * As we "execute" code, all we need to do is update the `this.refs` based on what the current bit of code does E.g.... When a variable is assigned a value that has a reference, we add a `VarRef` for that variable. When we leave a scope, we remove any `Ref`'s that are no longer in scope. Before executing a method, we add `Ref`'s for the method receiver and parameter. When we return from a non-void method, we convert any `ReturnRef` into a `ExprRef`. Etc. THAT I can understand. I don't see converting the above into a bitmap or whatever as worth the additional complexity. We're not programming in perl here. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 18:16:25 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 18:16:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: <1r69eKftXv6ZlGQP76mNrfgbldbDcMxhnyVOQ8oUV7U=.8facaf51-1f7e-486a-912e-a9a5912b7d88@github.com> On Thu, 12 Jan 2023 17:39:05 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 200: > >> 198: // >> 199: >> 200: public void analyzeTree(Env env) { > > nit: this method could be removed in favor of the overloaded version below Thanks - will fix. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 204: > >> 202: } >> 203: >> 204: public void analyzeTree(Env env, JCTree tree) { > > nit: `env` parameter doesn't seem to be used could be dropped I think Thanks - will fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 18:16:27 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 18:16:27 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 17:48:37 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 909: >> >>> 907: >>> 908: // Check for implicit outer 'this' reference >>> 909: if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { >> >> Similarly here - look for `Symbol.isEnclosedBy` > > Same comment as previous: I don't quite know what I'm doing and I'm loathe to break what is already working. Do you have a suggested patch? I can't seem to be able to run tests - I get failures in the build: * For target support_test_micro_tools-classes__the.BUILD_INDIFY_batch: ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 18:16:31 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 18:16:31 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 12:28:12 GMT, Maurizio Cimadamore wrote: > This might also be related with the fact that we deal with return values in different ways than with e.g. values returned from a nested scope (where we just pop, and then copy all pending expression to the outer depth). Yes, a method return value that represents a reference is an `ExprRef` just before the `return` is actually executed, but then it turns into a `ReturnRef`. A `ReturnRef` is really just a yellow sticky note that reminds us "Hey whenever you finish 'executing' this method, remember that there is a reference in its return value". > This might also be related with the fact that we deal with return values in different ways than with e.g. values returned from a nested scope (where we just pop, and then copy all pending expression to the outer depth). Exactly. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 18:21:22 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 18:21:22 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: <1vfnyE9dnZELUp1To60nQYEUIre7g5pcfXHKKHOug0I=.9af24b57-2627-45d8-a7cc-1b4235e99237@github.com> On Thu, 12 Jan 2023 18:11:01 GMT, Maurizio Cimadamore wrote: >> Same comment as previous: I don't quite know what I'm doing and I'm loathe to break what is already working. Do you have a suggested patch? > > I can't seem to be able to run tests - I get failures in the build: > > > * For target support_test_micro_tools-classes__the.BUILD_INDIFY_batch: This patch: diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk index 1c89328a388..7c3f0293edc 100644 --- a/make/test/BuildMicrobenchmark.gmk +++ b/make/test/BuildMicrobenchmark.gmk @@ -76,7 +76,7 @@ $(eval $(call SetupJavaCompilation, BUILD_INDIFY, \ TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \ SRC := $(TOPDIR)/test/jdk/java/lang/invoke, \ INCLUDE_FILES := indify/Indify.java, \ - DISABLED_WARNINGS := rawtypes serial options, \ + DISABLED_WARNINGS := this-escape rawtypes serial options, \ BIN := $(MICROBENCHMARK_TOOLS_CLASSES), \ JAVAC_FLAGS := -XDstringConcat=inline -Xprefer:newer, \ )) @@ -91,7 +91,7 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \ TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \ SMALL_JAVA := false, \ CLASSPATH := $(MICROBENCHMARK_CLASSPATH), \ - DISABLED_WARNINGS := processing rawtypes cast serial preview, \ + DISABLED_WARNINGS := this-escape processing rawtypes cast serial preview, \ SRC := $(MICROBENCHMARK_SRC), \ BIN := $(MICROBENCHMARK_CLASSES), \ JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \ diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index 9d35c2fbc0a..4e2b1e558e7 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -897,6 +897,7 @@ class ThisEscapeAnalyzer extends TreeScanner { // Check for implicit 'this' reference final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; final Type methodOwnerType = sym.owner.type; + //if (currentClassType.tsym.isSubClass(sym.owner, types)) { if (this.isSubtype(currentClassType, methodOwnerType)) { if (this.refs.contains(ThisRef.direct())) this.refs.add(ExprRef.direct(this.depth)); @@ -906,6 +907,7 @@ class ThisEscapeAnalyzer extends TreeScanner { } // Check for implicit outer 'this' reference + // if (currentClassType.tsym.isEnclosedBy((ClassSymbol)sym.owner)) { if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { if (this.refs.contains(OuterRef.direct())) this.refs.add(ExprRef.direct(this.depth)); Fixes the build failure. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 18:40:28 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 18:40:28 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Thu, 12 Jan 2023 16:40:33 GMT, Maurizio Cimadamore wrote: > I guess what I'm thinking about: No leak is possible in that example. * `new Foo()` creates an instance of `Foo` (not a subclass of `Foo`) therefore `m()` is not overridden * Any subclass of `Foo` that may exist in the outside world cannot use the `Foo()` constructor that leaks because it's private ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 18:43:21 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 18:43:21 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <1vfnyE9dnZELUp1To60nQYEUIre7g5pcfXHKKHOug0I=.9af24b57-2627-45d8-a7cc-1b4235e99237@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <1vfnyE9dnZELUp1To60nQYEUIre7g5pcfXHKKHOug0I=.9af24b57-2627-45d8-a7cc-1b4235e99237@github.com> Message-ID: On Thu, 12 Jan 2023 18:18:38 GMT, Maurizio Cimadamore wrote: >> I can't seem to be able to run tests - I get failures in the build: >> >> >> * For target support_test_micro_tools-classes__the.BUILD_INDIFY_batch: > > This patch: > > > diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk > index 1c89328a388..7c3f0293edc 100644 > --- a/make/test/BuildMicrobenchmark.gmk > +++ b/make/test/BuildMicrobenchmark.gmk > @@ -76,7 +76,7 @@ $(eval $(call SetupJavaCompilation, BUILD_INDIFY, \ > TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \ > SRC := $(TOPDIR)/test/jdk/java/lang/invoke, \ > INCLUDE_FILES := indify/Indify.java, \ > - DISABLED_WARNINGS := rawtypes serial options, \ > + DISABLED_WARNINGS := this-escape rawtypes serial options, \ > BIN := $(MICROBENCHMARK_TOOLS_CLASSES), \ > JAVAC_FLAGS := -XDstringConcat=inline -Xprefer:newer, \ > )) > @@ -91,7 +91,7 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \ > TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \ > SMALL_JAVA := false, \ > CLASSPATH := $(MICROBENCHMARK_CLASSPATH), \ > - DISABLED_WARNINGS := processing rawtypes cast serial preview, \ > + DISABLED_WARNINGS := this-escape processing rawtypes cast serial preview, \ > SRC := $(MICROBENCHMARK_SRC), \ > BIN := $(MICROBENCHMARK_CLASSES), \ > JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \ > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > index 9d35c2fbc0a..4e2b1e558e7 100644 > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > @@ -897,6 +897,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > // Check for implicit 'this' reference > final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; > final Type methodOwnerType = sym.owner.type; > + //if (currentClassType.tsym.isSubClass(sym.owner, types)) { > if (this.isSubtype(currentClassType, methodOwnerType)) { > if (this.refs.contains(ThisRef.direct())) > this.refs.add(ExprRef.direct(this.depth)); > @@ -906,6 +907,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > } > > // Check for implicit outer 'this' reference > + // if (currentClassType.tsym.isEnclosedBy((ClassSymbol)sym.owner)) { > if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { > if (this.refs.contains(OuterRef.direct())) > this.refs.add(ExprRef.direct(this.depth)); > > > Fixes the build failure. This patch passes all tests: diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index 9d35c2fbc0a..e755c54d0c8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -451,7 +451,7 @@ class ThisEscapeAnalyzer extends TreeScanner { } // If the expression type is incompatible with 'this', discard it - if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) + if (type != null && !this.targetClass.sym.isSubClass(type.tsym, types)) this.refs.remove(ExprRef.direct(this.depth)); } } @@ -672,7 +672,7 @@ class ThisEscapeAnalyzer extends TreeScanner { if (explicitOuterThis != null) { this.scan(explicitOuterThis); this.refs.removeExprs(this.depth, direct -> outerRefs.add(new OuterRef(direct))); - } else if (this.types.hasOuterClass(type, this.methodClass.type)) { + } else if (type.tsym.isEnclosedBy(this.methodClass.sym)) { if (this.refs.contains(ThisRef.direct())) outerRefs.add(OuterRef.direct()); if (this.refs.contains(ThisRef.indirect())) @@ -801,9 +801,8 @@ class ThisEscapeAnalyzer extends TreeScanner { // Explicit outer 'this' reference? final Type selectedType = this.types.erasure(tree.selected.type); if (selectedType.hasTag(CLASS)) { - final Type.ClassType selectedClassType = (Type.ClassType)selectedType; if (tree.name == this.names._this && - this.types.hasOuterClass(currentClassType, selectedClassType)) { + currentClassType.tsym.isEnclosedBy((ClassSymbol)selectedType.tsym)) { if (this.refs.contains(OuterRef.direct())) this.refs.add(ExprRef.direct(this.depth)); if (this.refs.contains(OuterRef.indirect())) @@ -895,9 +894,7 @@ class ThisEscapeAnalyzer extends TreeScanner { final MethodSymbol sym = (MethodSymbol)tree.sym; // Check for implicit 'this' reference - final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; - final Type methodOwnerType = sym.owner.type; - if (this.isSubtype(currentClassType, methodOwnerType)) { + if (methodClass.sym.isSubClass(sym.owner, types)) { if (this.refs.contains(ThisRef.direct())) this.refs.add(ExprRef.direct(this.depth)); if (this.refs.contains(ThisRef.indirect())) @@ -906,7 +903,7 @@ class ThisEscapeAnalyzer extends TreeScanner { } // Check for implicit outer 'this' reference - if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { + if (methodClass.sym.isEnclosedBy((ClassSymbol)sym.owner)) { if (this.refs.contains(OuterRef.direct())) this.refs.add(ExprRef.direct(this.depth)); Btw, I believe a similar trick can be used in TreeInfo.isExplicitThisReference. If I'm correct, `hasOuterClass` should probably be removed as it duplicates already existing functionality. Since I'm bringing this up, as TreeInfo.isExplicitThisReference is only used by the new analyzer, it would be cleaner if it was defined there, at least until it's clear it might be needed by some other client. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 18:51:33 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 18:51:33 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Thu, 12 Jan 2023 18:37:06 GMT, Archie L. Cobbs wrote: >> I guess what I'm thinking about: >> >> class Foo { >> private Foo() { >> m(this); >> } >> >> public void m() { ... } // overridable >> >> static Foo makeFoo() { return new Foo(); } >> } > >> I guess what I'm thinking about: > > No leak is possible in that example. > * `new Foo()` creates an instance of `Foo` (not a subclass of `Foo`) therefore `m()` is not overridden > * Any subclass of `Foo` that may exist in the outside world cannot use the `Foo()` constructor that leaks because it's private but what if `m` is a static method in a separate compilation unit? Should it be able to observe a partially initialized Foo? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 19:04:22 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 19:04:22 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 17:29:22 GMT, Maurizio Cimadamore wrote: >> I put it there because of switch expressions and `yeild`... ? > > Well, yield can... yield a value - `case` doesn't. So I'm confused. Also because the variable is called `referenceExpressionNode` and `CASE` is not an expression. Can `CASE` leave anything on the stack? YIELD does, but CASE? It's just an artifact of the way switch expressions are handled: @Override public void visitSwitchExpression(JCSwitchExpression tree) { visitScoped(tree, true, t -> { scan(t.selector); refs.discardExprs(depth); RefSet combinedRefs = new RefSet<>(); for (List cases = t.cases; cases.nonEmpty(); cases = cases.tail) { scan(cases.head); combinedRefs.addAll(refs.removeExprs(depth)); } refs.addAll(combinedRefs); }); } @Override public void visitCase(JCCase tree) { scan(tree.stats); // no need to scan labels } After scanning a switch expression case, the `yield`'ed value will be on the top of the stack. Then `visitCase` does NOT remove it, so that it can be picked up and removed by `visitSwitchExpression()`. But this can be cleaned up a little bit, by having `visitSwitchExpression()` not delegate to `visitCase()` but rather iterate through the case statements itself directly. Then we can remove the `CASE` as you suggest. Also I realized we need to handle `yield`'ed values like `return` values, i.e., collect and remember them until the entire case is complete. I'll fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 19:04:25 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 19:04:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 17:33:48 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 875: >> >>> 873: // Reference to this? >>> 874: if (tree.name == names._this || tree.name == names._super) { >>> 875: if (this.refs.contains(ThisRef.direct())) >> >> This idiom occurs quite a lot. If I'm correct, this basically amounts at asking as to whether the receiver of the method we're currently evaluating is direct or not (which is an invariant, given a method body - e.g. for a given method this "fact" should stay the same). If that's the case, perhaps capturing this in a flag could be better - then you could have just have a single method e.g. `XYZRef.create(boolean direct)`, and remove the branching (here and elsewhere). > > The code you quoted has nothing specifically to do with method invocations. This code is simply handing the evaluation of the expressions `this` and `super`. For example, `this` could just be a parameter we're passing to another method. > > When `this` or `super` expressions are evaluated, the thing left on top of the stack is a direct/indirect reference (i.e., an `ExprRef`) exactly when the there is a direct/indirect reference of type `ThisRef` in the current reference set. > > In cases where `this` is then "invoked", e.g., `this()`, the `ExprRef` (top of Java stack) becomes the method receiver, and when the method is "invoked" it turns back into a `ThisRef` (see earlier question). > > Regarding the optimization you mention, in light of the above I'm not sure it would still work. My point is about who puts ThisRef in the set to begin with. It seems to me that ThisRef is put there at the start of a method analysis. After which, there's several code points where we say "if there's a direct ThisRef in the set, do this, otherwise, if there's an indirect ThisRef in the set, do that". But the ThisRef (whether indirect or direct) seems set once and for all (when we start the analysis, and then inside visitApply). There is also this bit in `visitReference`: case SUPER: if (this.refs.contains(ThisRef.direct())) receiverRefs.add(ThisRef.direct()); if (this.refs.contains(ThisRef.indirect())) receiverRefs.add(ThisRef.indirect()); break; But this doesn't change what I'm saying - there seems to be a general property when we execute this analysis which says whether the current execution context has a direct `this` or not. This seems to me better captured with a boolean, which is then fed back to all the other various downstream ref creation. The main observation, at least for me, is that the code unifies everything under refs, when in reality there are different aspects: * the set of variables that can point to this, whether directly or indirectly (this is truly a set) * whether the current context has a direct or indirect this (this seems more a flag to me) * whether the expression on top of stack is direct/indirect this reference or not (again, 3 possible values here) - but granted, there `depth` here to take into account, so you probably end up with a set (given that we don't want to model a scope with its own set) When reading the code, seeing set expression like containment checks or removals for things that doesn't seem to be truly sets (unless I'm missing something) was genuinely confusing me. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 19:15:20 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 19:15:20 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 17:40:36 GMT, Maurizio Cimadamore wrote: > But the filtering will end up dropping the expression Ref on the floor, right? (because B and A are unrelated). Ah, I see what you mean. Here's a more complete example: public class CastLeak { public CastLeak() { ((CastLeak)(Runnable)this).mightLeak(); } public void mightLeak() { } } That would be a leak for any subclass that implements `Runnable`. Yet no warning is generated. So the filtering by expression type is going to potentially create false negatives. But it also eliminates a bunch of false positives. And the false negatives are probably all somewhat pathological like the example above. So I still think it's worth doing. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 19:27:24 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 19:27:24 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <1vfnyE9dnZELUp1To60nQYEUIre7g5pcfXHKKHOug0I=.9af24b57-2627-45d8-a7cc-1b4235e99237@github.com> Message-ID: On Thu, 12 Jan 2023 18:40:38 GMT, Maurizio Cimadamore wrote: >> This patch: >> >> >> diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk >> index 1c89328a388..7c3f0293edc 100644 >> --- a/make/test/BuildMicrobenchmark.gmk >> +++ b/make/test/BuildMicrobenchmark.gmk >> @@ -76,7 +76,7 @@ $(eval $(call SetupJavaCompilation, BUILD_INDIFY, \ >> TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \ >> SRC := $(TOPDIR)/test/jdk/java/lang/invoke, \ >> INCLUDE_FILES := indify/Indify.java, \ >> - DISABLED_WARNINGS := rawtypes serial options, \ >> + DISABLED_WARNINGS := this-escape rawtypes serial options, \ >> BIN := $(MICROBENCHMARK_TOOLS_CLASSES), \ >> JAVAC_FLAGS := -XDstringConcat=inline -Xprefer:newer, \ >> )) >> @@ -91,7 +91,7 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \ >> TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \ >> SMALL_JAVA := false, \ >> CLASSPATH := $(MICROBENCHMARK_CLASSPATH), \ >> - DISABLED_WARNINGS := processing rawtypes cast serial preview, \ >> + DISABLED_WARNINGS := this-escape processing rawtypes cast serial preview, \ >> SRC := $(MICROBENCHMARK_SRC), \ >> BIN := $(MICROBENCHMARK_CLASSES), \ >> JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \ >> diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> index 9d35c2fbc0a..4e2b1e558e7 100644 >> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> @@ -897,6 +897,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> // Check for implicit 'this' reference >> final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; >> final Type methodOwnerType = sym.owner.type; >> + //if (currentClassType.tsym.isSubClass(sym.owner, types)) { >> if (this.isSubtype(currentClassType, methodOwnerType)) { >> if (this.refs.contains(ThisRef.direct())) >> this.refs.add(ExprRef.direct(this.depth)); >> @@ -906,6 +907,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> } >> >> // Check for implicit outer 'this' reference >> + // if (currentClassType.tsym.isEnclosedBy((ClassSymbol)sym.owner)) { >> if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { >> if (this.refs.contains(OuterRef.direct())) >> this.refs.add(ExprRef.direct(this.depth)); >> >> >> Fixes the build failure. > > This patch passes all tests: > > > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > index 9d35c2fbc0a..e755c54d0c8 100644 > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > @@ -451,7 +451,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > } > > // If the expression type is incompatible with 'this', discard it > - if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) > + if (type != null && !this.targetClass.sym.isSubClass(type.tsym, types)) > this.refs.remove(ExprRef.direct(this.depth)); > } > } > @@ -672,7 +672,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > if (explicitOuterThis != null) { > this.scan(explicitOuterThis); > this.refs.removeExprs(this.depth, direct -> outerRefs.add(new OuterRef(direct))); > - } else if (this.types.hasOuterClass(type, this.methodClass.type)) { > + } else if (type.tsym.isEnclosedBy(this.methodClass.sym)) { > if (this.refs.contains(ThisRef.direct())) > outerRefs.add(OuterRef.direct()); > if (this.refs.contains(ThisRef.indirect())) > @@ -801,9 +801,8 @@ class ThisEscapeAnalyzer extends TreeScanner { > // Explicit outer 'this' reference? > final Type selectedType = this.types.erasure(tree.selected.type); > if (selectedType.hasTag(CLASS)) { > - final Type.ClassType selectedClassType = (Type.ClassType)selectedType; > if (tree.name == this.names._this && > - this.types.hasOuterClass(currentClassType, selectedClassType)) { > + currentClassType.tsym.isEnclosedBy((ClassSymbol)selectedType.tsym)) { > if (this.refs.contains(OuterRef.direct())) > this.refs.add(ExprRef.direct(this.depth)); > if (this.refs.contains(OuterRef.indirect())) > @@ -895,9 +894,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > final MethodSymbol sym = (MethodSymbol)tree.sym; > > // Check for implicit 'this' reference > - final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; > - final Type methodOwnerType = sym.owner.type; > - if (this.isSubtype(currentClassType, methodOwnerType)) { > + if (methodClass.sym.isSubClass(sym.owner, types)) { > if (this.refs.contains(ThisRef.direct())) > this.refs.add(ExprRef.direct(this.depth)); > if (this.refs.contains(ThisRef.indirect())) > @@ -906,7 +903,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > } > > // Check for implicit outer 'this' reference > - if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { > + if (methodClass.sym.isEnclosedBy((ClassSymbol)sym.owner)) { > if (this.refs.contains(OuterRef.direct())) > this.refs.add(ExprRef.direct(this.depth)); > > > Btw, I believe a similar trick can be used in TreeInfo.isExplicitThisReference. If I'm correct, `hasOuterClass` should probably be removed as it duplicates already existing functionality. > > Since I'm bringing this up, as TreeInfo.isExplicitThisReference is only used by the new analyzer, it would be cleaner if it was defined there, at least until it's clear it might be needed by some other client. Weird. I don't get that build failure. Neither does github... I have been relying on the github build "Actions" succeeding to determine if "the build works" and according to that it is building. I will add the `DISABLED_WARNINGS` in any case. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 21:07:28 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 21:07:28 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Thu, 12 Jan 2023 18:48:25 GMT, Maurizio Cimadamore wrote: >>> I guess what I'm thinking about: >> >> No leak is possible in that example. >> * `new Foo()` creates an instance of `Foo` (not a subclass of `Foo`) therefore `m()` is not overridden >> * Any subclass of `Foo` that may exist in the outside world cannot use the `Foo()` constructor that leaks because it's private > > but what if `m` is a static method in a separate compilation unit? Should it be able to observe a partially initialized Foo? Caring about the proper initialization of any class in the _current_ compilation unit is an explicit non-goal. We only care about bugs where a superclass and subclass are in separate compilation units. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 21:07:30 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 21:07:30 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <1vfnyE9dnZELUp1To60nQYEUIre7g5pcfXHKKHOug0I=.9af24b57-2627-45d8-a7cc-1b4235e99237@github.com> Message-ID: On Thu, 12 Jan 2023 19:24:50 GMT, Archie L. Cobbs wrote: >> This patch passes all tests: >> >> >> diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> index 9d35c2fbc0a..e755c54d0c8 100644 >> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> @@ -451,7 +451,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> } >> >> // If the expression type is incompatible with 'this', discard it >> - if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) >> + if (type != null && !this.targetClass.sym.isSubClass(type.tsym, types)) >> this.refs.remove(ExprRef.direct(this.depth)); >> } >> } >> @@ -672,7 +672,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> if (explicitOuterThis != null) { >> this.scan(explicitOuterThis); >> this.refs.removeExprs(this.depth, direct -> outerRefs.add(new OuterRef(direct))); >> - } else if (this.types.hasOuterClass(type, this.methodClass.type)) { >> + } else if (type.tsym.isEnclosedBy(this.methodClass.sym)) { >> if (this.refs.contains(ThisRef.direct())) >> outerRefs.add(OuterRef.direct()); >> if (this.refs.contains(ThisRef.indirect())) >> @@ -801,9 +801,8 @@ class ThisEscapeAnalyzer extends TreeScanner { >> // Explicit outer 'this' reference? >> final Type selectedType = this.types.erasure(tree.selected.type); >> if (selectedType.hasTag(CLASS)) { >> - final Type.ClassType selectedClassType = (Type.ClassType)selectedType; >> if (tree.name == this.names._this && >> - this.types.hasOuterClass(currentClassType, selectedClassType)) { >> + currentClassType.tsym.isEnclosedBy((ClassSymbol)selectedType.tsym)) { >> if (this.refs.contains(OuterRef.direct())) >> this.refs.add(ExprRef.direct(this.depth)); >> if (this.refs.contains(OuterRef.indirect())) >> @@ -895,9 +894,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> final MethodSymbol sym = (MethodSymbol)tree.sym; >> >> // Check for implicit 'this' reference >> - final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; >> - final Type methodOwnerType = sym.owner.type; >> - if (this.isSubtype(currentClassType, methodOwnerType)) { >> + if (methodClass.sym.isSubClass(sym.owner, types)) { >> if (this.refs.contains(ThisRef.direct())) >> this.refs.add(ExprRef.direct(this.depth)); >> if (this.refs.contains(ThisRef.indirect())) >> @@ -906,7 +903,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> } >> >> // Check for implicit outer 'this' reference >> - if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { >> + if (methodClass.sym.isEnclosedBy((ClassSymbol)sym.owner)) { >> if (this.refs.contains(OuterRef.direct())) >> this.refs.add(ExprRef.direct(this.depth)); >> >> >> Btw, I believe a similar trick can be used in TreeInfo.isExplicitThisReference. If I'm correct, `hasOuterClass` should probably be removed as it duplicates already existing functionality. >> >> Since I'm bringing this up, as TreeInfo.isExplicitThisReference is only used by the new analyzer, it would be cleaner if it was defined there, at least until it's clear it might be needed by some other client. > > Weird. I don't get that build failure. > > Neither does github... I have been relying on the github build "Actions" succeeding to determine if "the build works" and according to that it is building. > > I will add the `DISABLED_WARNINGS` in any case. Thanks for the patch! The semantics of `hasOuterClass()` returns false if A and B are the same class, while `isEnclosedBy()` returns true if A and B are the same class. However, I don't think it would actually matter in practice... Regardless, I'll add the extra equality comparison and apply your patch and also the suggestions to integrate `isExplicitThisReference()` and eliminate `hasOuterClass()`. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 21:31:25 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 21:31:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 19:01:10 GMT, Maurizio Cimadamore wrote: >> The code you quoted has nothing specifically to do with method invocations. This code is simply handing the evaluation of the expressions `this` and `super`. For example, `this` could just be a parameter we're passing to another method. >> >> When `this` or `super` expressions are evaluated, the thing left on top of the stack is a direct/indirect reference (i.e., an `ExprRef`) exactly when the there is a direct/indirect reference of type `ThisRef` in the current reference set. >> >> In cases where `this` is then "invoked", e.g., `this()`, the `ExprRef` (top of Java stack) becomes the method receiver, and when the method is "invoked" it turns back into a `ThisRef` (see earlier question). >> >> Regarding the optimization you mention, in light of the above I'm not sure it would still work. > > My point is about who puts ThisRef in the set to begin with. It seems to me that ThisRef is put there at the start of a method analysis. After which, there's several code points where we say "if there's a direct ThisRef in the set, do this, otherwise, if there's an indirect ThisRef in the set, do that". But the ThisRef (whether indirect or direct) seems set once and for all (when we start the analysis, and then inside visitApply). > > There is also this bit in `visitReference`: > > > case SUPER: > if (this.refs.contains(ThisRef.direct())) > receiverRefs.add(ThisRef.direct()); > if (this.refs.contains(ThisRef.indirect())) > receiverRefs.add(ThisRef.indirect()); > break; > > > But this doesn't change what I'm saying - there seems to be a general property when we execute this analysis which says whether the current execution context has a direct `this` or not. This seems to me better captured with a boolean, which is then fed back to all the other various downstream ref creation. > > The main observation, at least for me, is that the code unifies everything under refs, when in reality there are different aspects: > > * the set of variables that can point to this, whether directly or indirectly (this is truly a set) > * whether the current context has a direct or indirect this (this seems more a flag to me) > * whether the expression on top of stack is direct/indirect this reference or not (again, 3 possible values here) - but granted, there `depth` here to take into account, so you probably end up with a set (given that we don't want to model a scope with its own set) > > When reading the code, seeing set expression like containment checks or removals for things that doesn't seem to be truly sets (unless I'm missing something) was genuinely confusing me. I get what you're saying - it seems silly to model what is essentially a fixed, boolean property with the membership of a singleton in a set field, rather than with a simple boolean field. There is a conceptual trade-off though... a lot of the code relates to converting `Ref`'s from one type to another. For example, as pointed out above, a method invocation might convert a `ExprRef` to a `ThisRef`, then to a `ReturnRef`'s, etc. Having these things all be considered part of the same family helps conceptually. The fact that a direct `ThisRef` is a singleton is just a coincidence in this way of looking at things. The benefit is the simplicity of being able to think of the data model as "just a set of references". For example, methods like `RefSet.replaceExprs()` become less elegant (or basically impossible) if there have to be special cases for each type of reference, whereas currently we can do clean stuff like this: @Override public void visitReturn(JCReturn tree) { scan(tree.expr); refs.replaceExprs(depth, ReturnRef::new); } But I'm also realizing now that several places can be cleaned up by taking this event further. E.g., we should replace this code: if (refs.contains(ThisRef.direct())) outerRefs.add(OuterRef.direct()); if (refs.contains(ThisRef.indirect())) outerRefs.add(OuterRef.indirect()); with something like this: refs.mapInto(outerRefs, ThisRef.class, OuterRef::new); I will go through and refactor to do that and clean things up a little more. > When reading the code, seeing set expression like containment checks or removals for things that doesn't seem to be truly sets (unless I'm missing something) was genuinely confusing me. Probably my fault for not providing better documentation of the overall "set of references" conceptual approach. FWIW I added a little bit more in f83a9cf0. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From joe.darcy at oracle.com Thu Jan 12 21:36:37 2023 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Thu, 12 Jan 2023 13:36:37 -0800 Subject: FYI, JSR 269 MR for Java SE 20 changes Message-ID: <251f8681-1667-8d6b-64f2-1593b2fd050a@oracle.com> FYI, https://jcp.org/aboutJava/communityprocess/maintenance/jsr269/index14.html -Joe From mcimadamore at openjdk.org Thu Jan 12 21:47:24 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 21:47:24 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 21:28:12 GMT, Archie L. Cobbs wrote: >> My point is about who puts ThisRef in the set to begin with. It seems to me that ThisRef is put there at the start of a method analysis. After which, there's several code points where we say "if there's a direct ThisRef in the set, do this, otherwise, if there's an indirect ThisRef in the set, do that". But the ThisRef (whether indirect or direct) seems set once and for all (when we start the analysis, and then inside visitApply). >> >> There is also this bit in `visitReference`: >> >> >> case SUPER: >> if (this.refs.contains(ThisRef.direct())) >> receiverRefs.add(ThisRef.direct()); >> if (this.refs.contains(ThisRef.indirect())) >> receiverRefs.add(ThisRef.indirect()); >> break; >> >> >> But this doesn't change what I'm saying - there seems to be a general property when we execute this analysis which says whether the current execution context has a direct `this` or not. This seems to me better captured with a boolean, which is then fed back to all the other various downstream ref creation. >> >> The main observation, at least for me, is that the code unifies everything under refs, when in reality there are different aspects: >> >> * the set of variables that can point to this, whether directly or indirectly (this is truly a set) >> * whether the current context has a direct or indirect this (this seems more a flag to me) >> * whether the expression on top of stack is direct/indirect this reference or not (again, 3 possible values here) - but granted, there `depth` here to take into account, so you probably end up with a set (given that we don't want to model a scope with its own set) >> >> When reading the code, seeing set expression like containment checks or removals for things that doesn't seem to be truly sets (unless I'm missing something) was genuinely confusing me. > > I get what you're saying - it seems silly to model what is essentially a fixed, boolean property with the membership of a singleton in a set field, rather than with a simple boolean field. > > There is a conceptual trade-off though... a lot of the code relates to converting `Ref`'s from one type to another. For example, as pointed out above, a method invocation might convert a `ExprRef` to a `ThisRef`, then to a `ReturnRef`'s, etc. Having these things all be considered part of the same family helps conceptually. The fact that a direct `ThisRef` is a singleton is just a coincidence in this way of looking at things. > > The benefit is the simplicity of being able to think of the data model as "just a set of references". > > For example, methods like `RefSet.replaceExprs()` become less elegant (or basically impossible) if there have to be special cases for each type of reference, whereas currently we can do clean stuff like this: > > > @Override > public void visitReturn(JCReturn tree) { > scan(tree.expr); > refs.replaceExprs(depth, ReturnRef::new); > } > > > But I'm also realizing now that several places can be cleaned up by taking this event further. E.g., we should replace this code: > > if (refs.contains(ThisRef.direct())) > outerRefs.add(OuterRef.direct()); > if (refs.contains(ThisRef.indirect())) > outerRefs.add(OuterRef.indirect()); > > with something like this: > > refs.mapInto(outerRefs, ThisRef.class, OuterRef::new); > > > I will go through and refactor to do that and clean things up a little more. > >> When reading the code, seeing set expression like containment checks or removals for things that doesn't seem to be truly sets (unless I'm missing something) was genuinely confusing me. > > Probably my fault for not providing better documentation of the overall "set of references" conceptual approach. FWIW I added a little bit more in f83a9cf0. > ```java > ```java > if (refs.contains(ThisRef.direct())) > outerRefs.add(OuterRef.direct()); > if (refs.contains(ThisRef.indirect())) > outerRefs.add(OuterRef.indirect()); > ``` > > > > > > > > > > > > with something like this: > ```java > refs.mapInto(outerRefs, ThisRef.class, OuterRef::new); > ``` > ``` This sounds like a good idea, that idiom is quite widespread, so it should help avoiding repetition. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 04:04:36 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 04:04:36 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: - Fix bug where all but the last yeild statement were being ignored. - Add method RefSet.mapInto() and use to refactor/clean up. - Fix possible assertion failure when handling if statements. - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. Suggested-by: mcimadamore - Add comment regarding limitations of expresison type filtering. - Add a few more DISABLED_WARNINGS to unbreak build. - Clean up handling of switch expressions a bit. - Remove unused method variant of analyzeTree(). - Avoid all caps in comments. - Clarify confusing comment. - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/6e96a7d7..edf3c3f5 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=07 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=06-07 Stats: 540 lines in 8 files changed: 120 ins; 92 del; 328 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Fri Jan 13 04:04:37 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 13 Jan 2023 04:04:37 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 19:12:27 GMT, Archie L. Cobbs wrote: >> Uhm. Turns out I probably did not understand the filter correctly, and now I'm more dubious about what it actually does. Say you have this hierarchy: >> >> >> interface A { } >> class B { >> B() { >> A a = (A)this; >> ... >> } >> } >> class C extends B implements A { } >> ``` >> >> Pathological case, I know. But the filtering will end up dropping the expression Ref on the floor, right? (because B and A are unrelated). > >> But the filtering will end up dropping the expression Ref on the floor, right? (because B and A are unrelated). > > Ah, I see what you mean. > > Here's a more complete example: > > public class CastLeak { > > public CastLeak() { > ((CastLeak)(Runnable)this).mightLeak(); > } > > public void mightLeak() { > } > } > > That would be a leak for any subclass that implements `Runnable`. Yet no warning is generated. > > So the filtering by expression type is going to potentially create false negatives. But it also eliminates a bunch of false positives. And the false negatives are probably all somewhat pathological like the example above. > > So I still think it's worth doing. Ok - I thought false negative was the thing to absolutely avoid - and that was the no. 1 concern. I think a possible approach to keep both the filtering and the code more or less similar to what you have, is to save the type of the expression in the ExprRef. Then, I believe that, at the end of scan() you can just get whatever type is there, and check that it's the correct one, if not drop it. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 04:04:37 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 04:04:37 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 21:47:28 GMT, Maurizio Cimadamore wrote: > Ok - I thought false negative was the thing to absolutely avoid - and that was the no. 1 concern. You're right. I think at the time I reasoned that it would be unusual enough for the type of an expression to start as an instanceof X, then change to not being an instanceof X, and then change back, that it was worth it to go ahead and filter these out. But admittedly that was based on intuition, not science. > I think a possible approach to keep both the filtering and the code more or less similar to what you have, is to save the type of the expression in the ExprRef. Then, I believe that, at the end of scan() you can just get whatever type is there, and check that it's the correct one, if not drop it. That's a nice idea... thanks. I'll play around with it some. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Fri Jan 13 11:01:24 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 13 Jan 2023 11:01:24 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Thu, 12 Jan 2023 21:04:09 GMT, Archie L. Cobbs wrote: >> but what if `m` is a static method in a separate compilation unit? Should it be able to observe a partially initialized Foo? > > Caring about the proper initialization of any class in the _current_ compilation unit is an explicit non-goal. > > We only care about bugs where a superclass and subclass are in separate compilation units. So, to clarify, in this case: import java.util.*; class B { final Object ref; private B(Object ref) { Foo.consume(this); this.ref = ref; } } Even though `this` leaks to a method clearly before it is fully initialized, we do not care because there can be no subclass involved observing this. I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well - we're effectively leaking a class whose final field has not been initialized! That said, if that was discussed, and it was decided for the warning not to deal with this case, that's ok. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Fri Jan 13 11:11:31 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 13 Jan 2023 11:11:31 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 10:58:33 GMT, Maurizio Cimadamore wrote: >> Caring about the proper initialization of any class in the _current_ compilation unit is an explicit non-goal. >> >> We only care about bugs where a superclass and subclass are in separate compilation units. > > So, to clarify, in this case: > > > import java.util.*; > > class B { > final Object ref; > > private B(Object ref) { > Foo.consume(this); > this.ref = ref; > } > } > > > Even though `this` leaks to a method clearly before it is fully initialized, we do not care because there can be no subclass involved observing this. I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well - we're effectively leaking a class whose final field has not been initialized! > > That said, if that was discussed, and it was decided for the warning not to deal with this case, that's ok. Perhaps my confusion might come from the name `this-escape` of the lint warning - which seems overpromising in this respect. But I looked at the description of the lint warning using `javac --help-lint` and I got this: this-escape Warn when a constructor invokes a method that could be overriden in a subclass; Which indeed aligns well with what this PR is doing. So that's ok. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Fri Jan 13 11:11:31 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 13 Jan 2023 11:11:31 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 11:05:51 GMT, Maurizio Cimadamore wrote: >> So, to clarify, in this case: >> >> >> import java.util.*; >> >> class B { >> final Object ref; >> >> private B(Object ref) { >> Foo.consume(this); >> this.ref = ref; >> } >> } >> >> >> Even though `this` leaks to a method clearly before it is fully initialized, we do not care because there can be no subclass involved observing this. I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well - we're effectively leaking a class whose final field has not been initialized! >> >> That said, if that was discussed, and it was decided for the warning not to deal with this case, that's ok. > > Perhaps my confusion might come from the name `this-escape` of the lint warning - which seems overpromising in this respect. But I looked at the description of the lint warning using `javac --help-lint` and I got this: > > > this-escape Warn when a constructor invokes a method that could be overriden in a subclass; > > > Which indeed aligns well with what this PR is doing. So that's ok. Something seems to be up with the lint description for this-escape - compare this: serial Warn about Serializable classes that do not have a serialVersionUID field. Also warn about other suspect declarations in Serializable and Externalizable classes and interfaces. with this: this-escape Warn when a constructor invokes a method that could be overriden in a subclass; such a method would execute before the subclass constructor completes its initialization. Indentation seems to be missing, which causes readability issues in the `--help-lint` output. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 12:45:34 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 12:45:34 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 04:04:36 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: > > - Fix bug where all but the last yeild statement were being ignored. > - Add method RefSet.mapInto() and use to refactor/clean up. > - Fix possible assertion failure when handling if statements. > - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. > > Suggested-by: mcimadamore > - Add comment regarding limitations of expresison type filtering. > - Add a few more DISABLED_WARNINGS to unbreak build. > - Clean up handling of switch expressions a bit. > - Remove unused method variant of analyzeTree(). > - Avoid all caps in comments. > - Clarify confusing comment. > - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 516: > 514: Name name = TreeInfo.name(invoke.meth); > 515: if (name == names._super) { > 516: scanInitializers(); it seems like the code scan initializers every time it finds a super() invocation, I guess that this scanning could be done once per class ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 14:34:40 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 14:34:40 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 04:04:36 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: > > - Fix bug where all but the last yeild statement were being ignored. > - Add method RefSet.mapInto() and use to refactor/clean up. > - Fix possible assertion failure when handling if statements. > - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. > > Suggested-by: mcimadamore > - Add comment regarding limitations of expresison type filtering. > - Add a few more DISABLED_WARNINGS to unbreak build. > - Clean up handling of switch expressions a bit. > - Remove unused method variant of analyzeTree(). > - Avoid all caps in comments. > - Clarify confusing comment. > - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 533: > 531: if (sym != null && > 532: sym.owner.kind == TYP && > 533: ((ClassSymbol)sym.owner).fullname == names.java_lang_Object && nit: in general we use another idiom for this in the compiler: sym.owner.type.tsym == syms.objectType.tsym where `syms` is an instance of: `com.sun.tools.javac.code.Symtab` ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 15:11:48 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 15:11:48 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 11:08:33 GMT, Maurizio Cimadamore wrote: >> Perhaps my confusion might come from the name `this-escape` of the lint warning - which seems overpromising in this respect. But I looked at the description of the lint warning using `javac --help-lint` and I got this: >> >> >> this-escape Warn when a constructor invokes a method that could be overriden in a subclass; >> >> >> Which indeed aligns well with what this PR is doing. So that's ok. > > Something seems to be up with the lint description for this-escape - compare this: > > > serial Warn about Serializable classes that do not have a serialVersionUID field. > Also warn about other suspect declarations in Serializable and Externalizable classes and interfaces. > > with this: > > > this-escape Warn when a constructor invokes a method that could be overriden in a subclass; > such a method would execute before the subclass constructor completes its initialization. > > > Indentation seems to be missing, which causes readability issues in the `--help-lint` output. > I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well... Yes - and this very question did come up in the discussions around this warning (see amber-dev). The decision was to go with drawing the "warning boundary" at the compilation unit. The reasoning is that (a) this aligns with the compiler's "knowledge boundary", i.e., we can know for sure from code inspection, and also (b) focuses the warning on the particularly pernicious aspect of these bugs, which is that they arise from the non-obvious interaction among two or more files - even when looking at any single one of those files, there doesn't seem to be any apparent problem. In other words, we decided "not to try to save any single source code from itself". But I think it's still an interesting question. Maybe experience will provide more guidance over time. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 15:11:49 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 15:11:49 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 15:08:43 GMT, Archie L. Cobbs wrote: >> Something seems to be up with the lint description for this-escape - compare this: >> >> >> serial Warn about Serializable classes that do not have a serialVersionUID field. >> Also warn about other suspect declarations in Serializable and Externalizable classes and interfaces. >> >> with this: >> >> >> this-escape Warn when a constructor invokes a method that could be overriden in a subclass; >> such a method would execute before the subclass constructor completes its initialization. >> >> >> Indentation seems to be missing, which causes readability issues in the `--help-lint` output. > >> I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well... > > Yes - and this very question did come up in the discussions around this warning (see amber-dev). > > The decision was to go with drawing the "warning boundary" at the compilation unit. The reasoning is that (a) this aligns with the compiler's "knowledge boundary", i.e., we can know for sure from code inspection, and also (b) focuses the warning on the particularly pernicious aspect of these bugs, which is that they arise from the non-obvious interaction among two or more files - even when looking at any single one of those files, there doesn't seem to be any apparent problem. In other words, we decided "not to try to save any single source code from itself". > > But I think it's still an interesting question. Maybe experience will provide more guidance over time. > Something seems to be up with the lint description for this-escape - compare this: Oops, will fix - thanks. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 15:16:59 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 15:16:59 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 12:42:24 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: >> >> - Fix bug where all but the last yeild statement were being ignored. >> - Add method RefSet.mapInto() and use to refactor/clean up. >> - Fix possible assertion failure when handling if statements. >> - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. >> >> Suggested-by: mcimadamore >> - Add comment regarding limitations of expresison type filtering. >> - Add a few more DISABLED_WARNINGS to unbreak build. >> - Clean up handling of switch expressions a bit. >> - Remove unused method variant of analyzeTree(). >> - Avoid all caps in comments. >> - Clarify confusing comment. >> - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 516: > >> 514: Name name = TreeInfo.name(invoke.meth); >> 515: if (name == names._super) { >> 516: scanInitializers(); > > it seems like the code scan initializers every time it finds a super() invocation, I guess that this scanning could be done once per class Yes... I did it that way is so that it doesn't require any adaptation if/when JDK-8194743 ever gets implemented. And it keeps the code a little simpler in exchange for a little redundancy. I'm happy to fix this if you think it is necessary though. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 533: > >> 531: if (sym != null && >> 532: sym.owner.kind == TYP && >> 533: ((ClassSymbol)sym.owner).fullname == names.java_lang_Object && > > nit: in general we use another idiom for this in the compiler: > > sym.owner.type.tsym == syms.objectType.tsym > > where `syms` is an instance of: `com.sun.tools.javac.code.Symtab` Thanks - will fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Fri Jan 13 16:09:37 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 13 Jan 2023 16:09:37 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 15:08:59 GMT, Archie L. Cobbs wrote: >>> I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well... >> >> Yes - and this very question did come up in the discussions around this warning (see amber-dev). >> >> The decision was to go with drawing the "warning boundary" at the compilation unit. The reasoning is that (a) this aligns with the compiler's "knowledge boundary", i.e., we can know for sure from code inspection, and also (b) focuses the warning on the particularly pernicious aspect of these bugs, which is that they arise from the non-obvious interaction among two or more files - even when looking at any single one of those files, there doesn't seem to be any apparent problem. In other words, we decided "not to try to save any single source code from itself". >> >> But I think it's still an interesting question. Maybe experience will provide more guidance over time. > >> Something seems to be up with the lint description for this-escape - compare this: > > Oops, will fix - thanks. > The decision was to go with drawing the "warning boundary" at the compilation unit. The reasoning is that (a) this aligns with the compiler's "knowledge boundary", i.e., we can know for sure from code inspection, and also (b) focuses the warning on the particularly pernicious aspect of these bugs, which is that they arise from the non-obvious interaction among two or more files Sorry for being picky - you mention this "compilation unit" boundary before, but this is not really the reason here. Note that in my example B constructor calls out to a static method that is "outside" the boundary. The reason as to why my example is not flagged is simply that "escaping" is defined as "escaping into a subclass method", not just "escaping from the constructor (into some other compilation unit)". ------------- PR: https://git.openjdk.org/jdk/pull/11874 From archie.cobbs at gmail.com Fri Jan 13 16:13:05 2023 From: archie.cobbs at gmail.com (Archie Cobbs) Date: Fri, 13 Jan 2023 10:13:05 -0600 Subject: Soliciting opinions on JDK-8219412 In-Reply-To: References: Message-ID: On Thu, Jan 12, 2023 at 7:17 AM Maxim Degtyarev wrote: > > The static argument list identifies the enum constants (by string) > corresponding to the case numbers. > > This will decrease theoretical maximum of switch blocks in enum switch > statement due to constant pool size limitations. So it may affect some code > with huge switches over enum. > Just trying to make sure I understand this... The list of identifiers that gets passed to SwitchBootstraps.enumSwitch() is stored in an array, and the array is built from individual strings pulled from the constant pool. So is this what you're saying: the number of switch cases is limited by how many entries the constant pool can hold? (I think that's 2^16 - 1) If that's the case, then doesn't that bug already exist in the compiler in TransPatterns.handleSwitch()? -Archie -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From vromero at openjdk.org Fri Jan 13 16:15:32 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 16:15:32 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: <77lMG_P3_ZGjTegQictMdNN1IKjWixuzLWy5-GbHYnI=.bdbfc529-2ac8-4bba-b3a6-d08f0977e372@github.com> On Fri, 13 Jan 2023 15:14:05 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 516: >> >>> 514: Name name = TreeInfo.name(invoke.meth); >>> 515: if (name == names._super) { >>> 516: scanInitializers(); >> >> it seems like the code scan initializers every time it finds a super() invocation, I guess that this scanning could be done once per class > > Yes... I did it that way is so that it doesn't require any adaptation if/when JDK-8194743 ever gets implemented. And it keeps the code a little simpler in exchange for a little redundancy. > > I'm happy to fix this if you think it is necessary though. I'm OK either way we can revisit this later either as part of this PR or in a future one. I let it to your consideration ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 16:23:39 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 16:23:39 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 16:06:04 GMT, Maurizio Cimadamore wrote: >>> Something seems to be up with the lint description for this-escape - compare this: >> >> Oops, will fix - thanks. > >> The decision was to go with drawing the "warning boundary" at the compilation unit. The reasoning is that (a) this aligns with the compiler's "knowledge boundary", i.e., we can know for sure from code inspection, and also (b) focuses the warning on the particularly pernicious aspect of these bugs, which is that they arise from the non-obvious interaction among two or more files > > Sorry for being picky - you mention this "compilation unit" boundary before, but this is not really the reason here. Note that in my example B constructor calls out to a static method that is "outside" the boundary. The reason as to why my example is not flagged is simply that "escaping" is defined as "escaping into a subclass method", not just "escaping from the constructor (into some other compilation unit)". Oops, you're right, I answered the wrong question so to speak. The "must involve a subclass" requirement is another dimension on which a "boundary" was declared. This was also part of the original discussion. So yes the requirement is: "requires involvement of a subclass" **AND** "that subclass lives in a separate compilation unit". ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 16:23:42 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 16:23:42 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: <77lMG_P3_ZGjTegQictMdNN1IKjWixuzLWy5-GbHYnI=.bdbfc529-2ac8-4bba-b3a6-d08f0977e372@github.com> References: <77lMG_P3_ZGjTegQictMdNN1IKjWixuzLWy5-GbHYnI=.bdbfc529-2ac8-4bba-b3a6-d08f0977e372@github.com> Message-ID: On Fri, 13 Jan 2023 16:12:50 GMT, Vicente Romero wrote: >> Yes... I did it that way is so that it doesn't require any adaptation if/when JDK-8194743 ever gets implemented. And it keeps the code a little simpler in exchange for a little redundancy. >> >> I'm happy to fix this if you think it is necessary though. > > I'm OK either way we can revisit this later either as part of this PR or in a future one. I let it to your consideration Sounds good - thanks. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From brian.goetz at oracle.com Fri Jan 13 16:24:42 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 13 Jan 2023 16:24:42 +0000 Subject: Soliciting opinions on JDK-8219412 In-Reply-To: References: Message-ID: Yeah, I think the observation is not a particularly significant one. Yes, indy-heavy translation schemes often use more CP slots, which in turn could hasten the ?damn, I have to split this class up? problem. But its an incremental effect at best. Also, while the ?obvious? bootstrap signature is having each enum name stored as a Constant_String_info in the constant pool, which does require one slot per case, that?s not the only encoding. You could pass a single string of the form ?A;B;C? and split it at link time; we do something similar with the record bootstraps for equals/hashCode/toString. On Jan 13, 2023, at 11:13 AM, Archie Cobbs > wrote: On Thu, Jan 12, 2023 at 7:17 AM Maxim Degtyarev > wrote: > The static argument list identifies the enum constants (by string) corresponding to the case numbers. This will decrease theoretical maximum of switch blocks in enum switch statement due to constant pool size limitations. So it may affect some code with huge switches over enum. Just trying to make sure I understand this... The list of identifiers that gets passed to SwitchBootstraps.enumSwitch() is stored in an array, and the array is built from individual strings pulled from the constant pool. So is this what you're saying: the number of switch cases is limited by how many entries the constant pool can hold? (I think that's 2^16 - 1) If that's the case, then doesn't that bug already exist in the compiler in TransPatterns.handleSwitch()? -Archie -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From vromero at openjdk.org Fri Jan 13 17:38:27 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 17:38:27 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 04:04:36 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: > > - Fix bug where all but the last yeild statement were being ignored. > - Add method RefSet.mapInto() and use to refactor/clean up. > - Fix possible assertion failure when handling if statements. > - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. > > Suggested-by: mcimadamore > - Add comment regarding limitations of expresison type filtering. > - Add a few more DISABLED_WARNINGS to unbreak build. > - Clean up handling of switch expressions a bit. > - Remove unused method variant of analyzeTree(). > - Avoid all caps in comments. > - Clarify confusing comment. > - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 685: > 683: > 684: @Override > 685: public void visitDoLoop(JCDoWhileLoop tree) { I was thinking, code can also loop using labels and `break` / `continue`, not something we need to cover as part of this prototype but could be a future TODO that we can document ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 17:52:31 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 17:52:31 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 17:35:08 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: >> >> - Fix bug where all but the last yeild statement were being ignored. >> - Add method RefSet.mapInto() and use to refactor/clean up. >> - Fix possible assertion failure when handling if statements. >> - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. >> >> Suggested-by: mcimadamore >> - Add comment regarding limitations of expresison type filtering. >> - Add a few more DISABLED_WARNINGS to unbreak build. >> - Clean up handling of switch expressions a bit. >> - Remove unused method variant of analyzeTree(). >> - Avoid all caps in comments. >> - Clarify confusing comment. >> - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 685: > >> 683: >> 684: @Override >> 685: public void visitDoLoop(JCDoWhileLoop tree) { > > I was thinking, code can also loop using labels and `break` / `continue`, not something we need to cover as part of this prototype but could be a future TODO that we can document Hah - I didn't think of that. But actually I don't think we would miss anything (see if you agree). The code "executes" every loop, in a sort-of simulation, adding references until the set of references converges. Moreover, that reference set is "append only" while this is happening. Therefore, during actual execution, a break or continue may cause less code to be executed than in our simulation, but never more code than our simulation. So during actual execution it might be that fewer actual 'this' references are created, but never more. Therefore, this effect might cause false positives (which of course we already have with loops and code in general because we take all possible branches), but never false negatives. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 19:09:54 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 19:09:54 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: - Use more idiomatic test for java.lang.Object. - Revert 27cb30129; the error was actually fixed in edf3c3f51. - Fix formatting issue with the "this-escape" --help-lint description. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/edf3c3f5..ae37ff7c Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=08 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=07-08 Stats: 12 lines in 3 files changed: 3 ins; 4 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 19:20:29 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 19:20:29 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: <9xqxePs8UvBJIyPMojy6Bjbl7h3VguJcIwjFhbPr_78=.5ed61dac-21e7-4214-8faf-85f5612f5b46@github.com> On Fri, 13 Jan 2023 17:49:05 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 685: >> >>> 683: >>> 684: @Override >>> 685: public void visitDoLoop(JCDoWhileLoop tree) { >> >> I was thinking, code can also loop using labels and `break` / `continue`, not something we need to cover as part of this prototype but could be a future TODO that we can document > > Hah - I didn't think of that. But actually I don't think we would miss anything (see if you agree). > > The code "executes" every loop, in a sort-of simulation, adding references until the set of references converges. Moreover, that reference set is "append only" while this is happening. > > Therefore, during actual execution, a break or continue may cause less code to be executed than in our simulation, but never more code than our simulation. So during actual execution it might be that fewer actual 'this' references are created, but never more. > > Therefore, this effect might cause false positives (which of course we already have with loops and code in general because we take all possible branches), but never false negatives. yep I agree ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 20:19:53 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 20:19:53 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 19:09:54 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Use more idiomatic test for java.lang.Object. > - Revert 27cb30129; the error was actually fixed in edf3c3f51. > - Fix formatting issue with the "this-escape" --help-lint description. test/langtools/tools/javac/warnings/ThisEscape/ThisEscapeBasic.java line 8: > 6: */ > 7: > 8: public class ThisEscapeBasic { I wonder if it could be better to just fold most of these tests in particular the small ones and create just one, or a few tests, with several subclasses, that will reduce the overhead if in the future we change the code and we need to change the golden files. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 20:24:46 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 20:24:46 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 19:09:54 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Use more idiomatic test for java.lang.Object. > - Revert 27cb30129; the error was actually fixed in edf3c3f51. > - Fix formatting issue with the "this-escape" --help-lint description. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1088: > 1086: private void visitLooped(T tree, Consumer visitor) { > 1087: visitScoped(tree, false, t -> { > 1088: while (true) { I have also been thinking if the loop analysis could go wild and execute a large, unbound number of times. But it seems from Archie's experiments that this probably won't occur in "normal" code and worst case scenario if that were to occur we can always limit the number of times we will process loops to a set number of times ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 21:23:24 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 21:23:24 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 20:16:25 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: >> >> - Use more idiomatic test for java.lang.Object. >> - Revert 27cb30129; the error was actually fixed in edf3c3f51. >> - Fix formatting issue with the "this-escape" --help-lint description. > > test/langtools/tools/javac/warnings/ThisEscape/ThisEscapeBasic.java line 8: > >> 6: */ >> 7: >> 8: public class ThisEscapeBasic { > > I wonder if it could be better to just fold most of these tests in particular the small ones and create just one, or a few tests, with several subclasses, that will reduce the overhead if in the future we change the code and we need to change the golden files. I really don't have any informed opinion on this. I can see arguments both ways... putting all you eggs in one basket can be seen alternately as foolhardy or highly efficient :) FWIW in the past I've had problems with trying to combine multiples tests that generate errors into one file. The compiler seems to like to bail out early when it sees errors. I guess that experience was working subconsciously. Of course that doesn't apply here as these are all warnings. And a bunch of separate files make the test run slower. So I agree with you - I'll consolidate them. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 21:31:25 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 21:31:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 20:21:24 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: >> >> - Use more idiomatic test for java.lang.Object. >> - Revert 27cb30129; the error was actually fixed in edf3c3f51. >> - Fix formatting issue with the "this-escape" --help-lint description. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1088: > >> 1086: private void visitLooped(T tree, Consumer visitor) { >> 1087: visitScoped(tree, false, t -> { >> 1088: while (true) { > > I have also been thinking if the loop analysis could go wild and execute a large, unbound number of times. But it seems from Archie's experiments that this probably won't occur in "normal" code and worst case scenario if that were to occur we can always limit the number of times we will process loops to a set number of times The number of times around any single loop is bounded by the number of new references that can possibly be created during the analysis of that loop. That number is at most 2 * (1 + 1 + 1 + 1 + N) where N is the number of parameters and/or variables declared in that scope (the 2 is for direct or indirect, and the 1's are for each of the singleton reference types `ThisRef`, `OuterRef`, `ExprRef`, and `ReturnRef`). If you have nested scopes A, B, C each with Na, Nb, and Nc variables declared therein (respectively), then the bound would be something like 2 * (1 + 1 + 1 + 1 + Na + (Na * Nb) + (Na * Nb * Nc)) worst case (waving hands here). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 21:36:30 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 21:36:30 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: <77lMG_P3_ZGjTegQictMdNN1IKjWixuzLWy5-GbHYnI=.bdbfc529-2ac8-4bba-b3a6-d08f0977e372@github.com> Message-ID: On Fri, 13 Jan 2023 16:20:41 GMT, Archie L. Cobbs wrote: >> I'm OK either way we can revisit this later either as part of this PR or in a future one. I let it to your consideration > > Sounds good - thanks. Ah. I just realized that we need to do it your way because of the following bug: Suppose you have a constructor and a field with initializer that both leak, but you have `@SuppressWarnings("this-escape")` on the constructor. Then the leak for the field will never be reported because we never get to it. I'll fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 22:04:03 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 22:04:03 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: <77lMG_P3_ZGjTegQictMdNN1IKjWixuzLWy5-GbHYnI=.bdbfc529-2ac8-4bba-b3a6-d08f0977e372@github.com> Message-ID: <1ylDnjbWJwdsJP-dVL1zthfhVHZbcOgnC3gxgNuKBZk=.6367e3b4-18ae-4232-b43a-c469e58f9a2d@github.com> On Fri, 13 Jan 2023 21:33:02 GMT, Archie L. Cobbs wrote: >> Sounds good - thanks. > > Ah. I just realized that we need to do it your way because of the following bug: > > Suppose you have a constructor and a field with initializer that both leak, but you have `@SuppressWarnings("this-escape")` on the constructor. > > Then the leak for the field will never be reported because we never get to it. > > I'll fix. yep, right in that case that leak wouldn't be reported ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 22:48:59 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 22:48:59 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v10] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: - Fix bug where field initializer warnings could be incorrectly suppressed. - Consolidate all the unit tests that generate warnings into one. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/ae37ff7c..0b06dc32 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=09 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=08-09 Stats: 1454 lines in 35 files changed: 658 ins; 762 del; 34 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Sat Jan 14 01:57:32 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Sat, 14 Jan 2023 01:57:32 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Fri, 13 Jan 2023 00:57:14 GMT, Archie L. Cobbs wrote: >> Ok - I thought false negative was the thing to absolutely avoid - and that was the no. 1 concern. I think a possible approach to keep both the filtering and the code more or less similar to what you have, is to save the type of the expression in the ExprRef. Then, I believe that, at the end of scan() you can just get whatever type is there, and check that it's the correct one, if not drop it. > >> Ok - I thought false negative was the thing to absolutely avoid - and that was the no. 1 concern. > > You're right. I think at the time I reasoned that it would be unusual enough for the type of an expression to start as an instanceof X, then change to not being an instanceof X, and then change back, that it was worth it to go ahead and filter these out. But admittedly that was based on intuition, not science. > >> I think a possible approach to keep both the filtering and the code more or less similar to what you have, is to save the type of the expression in the ExprRef. Then, I believe that, at the end of scan() you can just get whatever type is there, and check that it's the correct one, if not drop it. > > That's a nice idea... thanks. I'll play around with it some. I was curious how much of a difference this type filtering makes, so I built the JDK with and without it. The results were identical except for one case: package java.lang.invoke; ... public abstract sealed class CallSite permits ConstantCallSite, MutableCallSite, VolatileCallSite { ... CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable { this(targetType); // need to initialize target to make CallSite.type() work in createTargetHook ConstantCallSite selfCCS = (ConstantCallSite) this; MethodHandle boundTarget = (MethodHandle) createTargetHook.invokeWithArguments(selfCCS); setTargetNormal(boundTarget); // ConstantCallSite doesn't publish CallSite.target UNSAFE.storeStoreFence(); // barrier between target and isFrozen updates } When we do type filtering, `(ConstantCallSite) this` causes the 'this' reference to be discarded so no leak is reported on the next line for `invokeWithArguments(selfCCS)`. Just a side note, there is also a leak on the next line because final method `setTargetNormal()` invokes `MethodHandleNatives.setCallSiteTargetNormal(this, newTarget)`, so a leak does get reported anyway even with type filtering. When type filtering is disabled, we report a leak at `invokeWithArguments(selfCCS)` - which is accurate. So what did we learn? First it looks like type filtering has very minimal effect. I think this is because it requires some version of two casts in a row in and out of type compatibility, and this is probably very rare. But looking at the one data point we do have, the type filtering did in fact cause a false negative. And when building the entire JDK, it causes zero net new false positives. So to me this is evidence that we should just remove the type filtering altogether... @vicente-romero-oracle your thoughts? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Mon Jan 16 11:56:24 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 16 Jan 2023 11:56:24 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v10] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 22:48:59 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Fix bug where field initializer warnings could be incorrectly suppressed. > - Consolidate all the unit tests that generate warnings into one. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1096: > 1094: > 1095: // Perform the given action within a new scope > 1096: private void visitScoped(boolean promote, Runnable action) { type-variable unused here? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Mon Jan 16 12:54:22 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 16 Jan 2023 12:54:22 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 21:28:51 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1088: >> >>> 1086: private void visitLooped(T tree, Consumer visitor) { >>> 1087: visitScoped(tree, false, t -> { >>> 1088: while (true) { >> >> I have also been thinking if the loop analysis could go wild and execute a large, unbound number of times. But it seems from Archie's experiments that this probably won't occur in "normal" code and worst case scenario if that were to occur we can always limit the number of times we will process loops to a set number of times > > The number of times around any single loop is bounded by the number of new references that can possibly be created during the analysis of that loop. > > That number is at most 2 * (1 + 1 + 1 + 1 + N) where N is the number of parameters and/or variables declared in that scope (the 2 is for direct or indirect, and the 1's are for each of the singleton reference types `ThisRef`, `OuterRef`, `ExprRef`, and `ReturnRef`). > > If you have nested scopes A, B, C each with Na, Nb, and Nc variables declared therein (respectively), then the bound would be something like 2 * (1 + 1 + 1 + 1 + Na + (Na * Nb) + (Na * Nb * Nc)) worst case (waving hands here). I have played a bit with the patch, trying to disable certain features. The main reason to deal with loops and recursive calls the way the patch does is to eliminate false positives. If we see a loop, and we can't perform the analysis multiple times (as the PR does), then we'd have to conclude that the loop can be potentially escaping (as we might have missed an local var update). Same goes for recursive calls (e.g. a recursive call would be treated as escaping). Same goes for analyzing invoked methods that fall in the same compilation unit. If we don't do that, more methods might look as "escaping". So, here's what I found: * compiling the JDK with the current patch produces 2376 warnings * disabling support for recursive calls produces 2427 warnings * treating all method calls inside a loop to be escaping produces 2464 warnings * disabling scanning of methods in same compilation unit produces 4317 warnings (Note: the patches I used to do this analysis are a bit blunt, and perhaps can be made a bit less conservative, which might result in less false positives added - I just went for the simplest possible approach, just to test the contribute of each analysis). This seems to suggest that even a blunt approach to deal with recursion and loop does not result in a significant increase of false positives (~2% more). That said, disabling scanning of methods in the same compilation unit results in a big impact in terms of false positive (~100% increase). So, I'm pretty confident that, should performance problems arise, we could probably dial back the analysis not to do loops (or to do them in a bounded way, as Vicente suggest, which is much better of what I tried here) - and that will probably give us the same results we have today (or a very very minor increase of false positives). But scanning of dependent methods in same compilation unit seems to be more or less a must-have. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jlahoda at openjdk.org Mon Jan 16 15:21:58 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Mon, 16 Jan 2023 15:21:58 GMT Subject: [jdk20] RFR: 8300195: Fall-through issue occurs when using record pattern in switch statements Message-ID: When converting pattern matching switches, cases with common prefix tests are factored out into separate sub-switches. But, when this happens, the cases generated are the statement cases, even if the original cases where rule cases. So, this may lead to an unintended fall through. The proposal here is to inject breaks with correct targets as needed. Alternatively, we could keep the kind of the cases, but that is more tricky, as the cases must break the main switch, not the nested ones. ------------- Commit messages: - 8300195: Fall-through issue occurs when using record pattern in switch statements Changes: https://git.openjdk.org/jdk20/pull/109/files Webrev: https://webrevs.openjdk.org/?repo=jdk20&pr=109&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8300195 Stats: 124 lines in 2 files changed: 113 ins; 4 del; 7 mod Patch: https://git.openjdk.org/jdk20/pull/109.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/109/head:pull/109 PR: https://git.openjdk.org/jdk20/pull/109 From duke at openjdk.org Mon Jan 16 15:49:28 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 16 Jan 2023 15:49:28 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v10] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 11:53:40 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Fix bug where field initializer warnings could be incorrectly suppressed. >> - Consolidate all the unit tests that generate warnings into one. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1096: > >> 1094: >> 1095: // Perform the given action within a new scope >> 1096: private void visitScoped(boolean promote, Runnable action) { > > type-variable unused here? Thanks - will fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From amaembo at gmail.com Mon Jan 16 16:17:18 2023 From: amaembo at gmail.com (Tagir Valeev) Date: Mon, 16 Jan 2023 17:17:18 +0100 Subject: Unchecked conversion spec Message-ID: Hello! I have trouble understanding the unchecked conversion section of JLS (5.1.6.2)[1]. I have the following code: import java.util.function.Supplier; public class Test { static class Box implements Supplier { @Override public T get() { return null; } } > void typeArg(S s) { Box b = (Box) s; } } javac with -Xlint:all compiles it without unchecked warning (tried various versions from JDK 11 to JDK 20ea, the behavior is the same). The spec says: The unchecked narrowing reference conversions are as follows: A narrowing reference conversion from a type S to a parameterized class or interface type T is unchecked, unless at least one of the following is true: - All of the type arguments of T are unbounded wildcards. - T <: S, and S has no subtype X other than T where the type arguments of X are not contained in the type arguments of T. In my example, T = Box and S = S. To my understanding, "All of the type arguments of T are unbounded wildcards." is false ( is bounded), and Box is not a subtype of S, so "T <: S" is wrong. This means that this conversion should be unchecked and a warning should be issued. I feel that javac behavior is correct. Probably I don't understand the spec correctly. Could you please help me with this? Thank you in advance, Tagir Valeev. [1] https://docs.oracle.com/javase/specs/jls/se19/html/jls-5.html#jls-5.1.6.2 From duke at openjdk.org Mon Jan 16 16:32:25 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 16 Jan 2023 16:32:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: <-vggQR3X6BuroIsmEmI6yohrVGF3MyE-ap7tokjc-7M=.077053ee-fcf9-43db-be53-a9c89ab38a15@github.com> On Mon, 16 Jan 2023 12:51:49 GMT, Maurizio Cimadamore wrote: >> The number of times around any single loop is bounded by the number of new references that can possibly be created during the analysis of that loop. >> >> That number is at most 2 * (1 + 1 + 1 + 1 + N) where N is the number of parameters and/or variables declared in that scope (the 2 is for direct or indirect, and the 1's are for each of the singleton reference types `ThisRef`, `OuterRef`, `ExprRef`, and `ReturnRef`). >> >> If you have nested scopes A, B, C each with Na, Nb, and Nc variables declared therein (respectively), then the bound would be something like 2 * (1 + 1 + 1 + 1 + Na + (Na * Nb) + (Na * Nb * Nc)) worst case (waving hands here). > > I have played a bit with the patch, trying to disable certain features. The main reason to deal with loops and recursive calls the way the patch does is to eliminate false positives. If we see a loop, and we can't perform the analysis multiple times (as the PR does), then we'd have to conclude that the loop can be potentially escaping (as we might have missed an local var update). Same goes for recursive calls (e.g. a recursive call would be treated as escaping). Same goes for analyzing invoked methods that fall in the same compilation unit. If we don't do that, more methods might look as "escaping". > > So, here's what I found: > > * compiling the JDK with the current patch produces 2376 warnings > * disabling support for recursive calls produces 2427 warnings > * treating all method calls inside a loop to be escaping produces 2464 warnings > * disabling scanning of methods in same compilation unit produces 4317 warnings > > (Note: the patches I used to do this analysis are a bit blunt, and perhaps can be made a bit less conservative, which might result in less false positives added - I just went for the simplest possible approach, just to test the contribute of each analysis). > > This seems to suggest that even a blunt approach to deal with recursion and loop does not result in a significant increase of false positives (~2% more). That said, disabling scanning of methods in the same compilation unit results in a big impact in terms of false positive (~100% increase). > > So, I'm pretty confident that, should performance problems arise, we could probably dial back the analysis not to do loops (or to do them in a bounded way, as Vicente suggest, which is much better of what I tried here) - and that will probably give us the same results we have today (or a very very minor increase of false positives). But scanning of dependent methods in same compilation unit seems to be more or less a must-have. Thanks for doing that analysis - very interesting. It looks like you might be counting the "here via invocation" lines as separate warnings. These are really part of the previous `possible 'this' escape` line, e.g.: .../java/awt/Frame.java:429: Note: possible 'this' escape before subclass is fully initialized init(title, null); ^ .../java/awt/Frame.java:460: Note: previous possible 'this' escape happens here via invocation SunToolkit.checkAndSetPolicy(this); ^ Semi-related... I was also curious what would happen if we changed the semantics of the warning from "subclass must be in a separate compilation unit" to "subclass must be in a separate package". I'm not proposing we change this definition, and obviously there are trade-offs in where you draw this boundary, but was curious anywan (at one point I thought it might be worth having an option for this, e.g., with variants like `-Xlint:this-escape` vs. `-Xlint:this-escape:package`, or even `-Xlint:this-escape:module`, etc.). In any case, here are the results: * Warnings for subclass in separate compilation unit: 2093 * Warnings for subclass in separate package: 1334 So a 36% reduction - not too surprising since the JDK includes a bunch of non-public implementation classes. FWIW this is the patch I used: diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index e81df22b017..f309a4742aa 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -216,24 +217,24 @@ class ThisEscapeAnalyzer extends TreeScanner { private Lint lint = ThisEscapeAnalyzer.this.lint; private JCClassDecl currentClass; - private boolean privateOuter; + private boolean nonPublicOuter; @Override public void visitClassDef(JCClassDecl tree) { JCClassDecl currentClassPrev = currentClass; - boolean privateOuterPrev = privateOuter; + boolean nonPublicOuterPrev = nonPublicOuter; Lint lintPrev = lint; lint = lint.augment(tree.sym); try { currentClass = tree; - privateOuter |= tree.sym.isAnonymous(); - privateOuter |= (tree.mods.flags & Flags.PRIVATE) != 0; + nonPublicOuter |= tree.sym.isAnonymous(); + nonPublicOuter |= (tree.mods.flags & Flags.PUBLIC) == 0; // Recurse super.visitClassDef(tree); } finally { currentClass = currentClassPrev; - privateOuter = privateOuterPrev; + nonPublicOuter = nonPublicOuterPrev; lint = lintPrev; } } @@ -268,10 +269,10 @@ class ThisEscapeAnalyzer extends TreeScanner { // Determine if this is a constructor we should analyze boolean analyzable = currentClassIsExternallyExtendable() && TreeInfo.isConstructor(tree) && - !tree.sym.isPrivate() && + (tree.sym.isPublic() || (tree.sym.flags() & Flags.PROTECTED) != 0) && !suppressed.contains(tree.sym); - // Determine if this method is "invokable" in an analysis (can't be overridden) + // Determine if this method is "invokable" in an analysis (can't be overridden outside package) boolean invokable = !currentClassIsExternallyExtendable() || TreeInfo.isConstructor(tree) || (tree.mods.flags & (Flags.STATIC | Flags.PRIVATE | Flags.FINAL)) != 0; @@ -286,12 +287,13 @@ class ThisEscapeAnalyzer extends TreeScanner { } } - // Determines if the current class could be extended in some external compilation unit + // Determines if the current class could be extended in some other package private boolean currentClassIsExternallyExtendable() { return !currentClass.sym.isFinal() && + currentClass.sym.isPublic() && !(currentClass.sym.isSealed() && currentClass.permitting.isEmpty()) && !(currentClass.sym.owner.kind == MTH) && - !privateOuter; + !nonPublicOuter; } }.scan(env.tree); ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Mon Jan 16 17:16:26 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 16 Jan 2023 17:16:26 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: <-vggQR3X6BuroIsmEmI6yohrVGF3MyE-ap7tokjc-7M=.077053ee-fcf9-43db-be53-a9c89ab38a15@github.com> References: <-vggQR3X6BuroIsmEmI6yohrVGF3MyE-ap7tokjc-7M=.077053ee-fcf9-43db-be53-a9c89ab38a15@github.com> Message-ID: On Mon, 16 Jan 2023 16:29:31 GMT, Archie L. Cobbs wrote: > It looks like you might be counting the "here via invocation" lines as separate warnings. These are really part of the previous `possible 'this' escape` line, e.g.: yes, I really did the simplest possible thing (e.g. just counting the number of escape-this warnings, regardless of their kinds). Perhaps some of my measurements might be skewed as a result - but I think that magnitude-wise they are still telling. > > ``` > .../java/awt/Frame.java:429: Note: possible 'this' escape before subclass is fully initialized > init(title, null); > ^ > .../java/awt/Frame.java:460: Note: previous possible 'this' escape happens here via invocation > SunToolkit.checkAndSetPolicy(this); > ^ > ``` > > Semi-related... I was also curious what would happen if we changed the semantics of the warning from "subclass must be in a separate compilation unit" to "subclass must be in a separate package". To be fair, this is what my brain was reading when you talked about "compilation unit" - but then saw that the code was doing it differently. You see, for "sealed" classes we have a notion of "maintenance domain". E.g. the classes in a `permits` clause of a `sealed` declaration must belong to the same module (if available) or same package (if no module is available). That's how you get the exhaustiveness analysis and all the goodies, by essentially making a close-world assumption on the classes that are passed to javac for a given compilation task. I think it would make a lot of sense to apply these very same boundaries to the escape-this analysis (and, in fact, when looking at warnings coming out of the JDK, I often found false positives that were caused by this). > > I'm not proposing we change this definition, and obviously there are trade-offs in where you draw this boundary, but was curious anywan (at one point I thought it might be worth having an option for this, e.g., with variants like `-Xlint:this-escape` vs. `-Xlint:this-escape:package`, or even `-Xlint:this-escape:module`, etc.). Perhaps - but, as said above, `sealed` already does this by default - so there's a (strong) precedent, I believe, should we want to bend the analysis that way. > > In any case, here are the results: > > * Warnings for subclass in separate compilation unit: 2093 > > * Warnings for subclass in separate package: 1334 > > > So a 36% reduction - not too surprising since the JDK includes a bunch of non-public implementation classes. That corresponds to what I've sampled (unscientifically). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Mon Jan 16 23:22:00 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 16 Jan 2023 23:22:00 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: - Remove unused type variable on method visitScoped(). - Remove expression type filtering; it doesn't seem to be needed. - Clean up unused import. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/0b06dc32..a0b4310d Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=10 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=09-10 Stats: 21 lines in 2 files changed: 0 ins; 20 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From jwaters at openjdk.org Tue Jan 17 04:44:09 2023 From: jwaters at openjdk.org (Julian Waters) Date: Tue, 17 Jan 2023 04:44:09 GMT Subject: RFR: 8163229: several regression tests have a main method that is never executed [v4] In-Reply-To: References: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> Message-ID: <-1jOh8WCItZn5N_zEEM1tgDu6Hs-IsWrp_yO7yOw0xQ=.bf28b6f7-49bf-421a-b38c-834bb4dcf749@github.com> On Thu, 5 Jan 2023 21:24:09 GMT, Archie L. Cobbs wrote: >> This PR deals with some housekeeping relating to compiler unit tests. >> >> JDK-8163229 points out that there are several tests that have a `public static void main(String[])` method, but because the test expects to fail during compilation, the test is never actually run, and so these `main` methods are just clutter that can be removed. >> >> However, there are also some tests where the test is never run, but the `main()` method generates one or more of the expected compilation errors. Obviously we need to keep those, but they don't need to be declared as `public static void main(String[])` which is misleading. So instead we rename these methods to `meth()`, and also we remove the `String[]` parameter when it's not needed by the test. > > Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: > > Remove two more unnecessary main() methods. Verified that the test failures are unrelated, will help you sponsor ------------- PR: https://git.openjdk.org/jdk/pull/10992 From duke at openjdk.org Tue Jan 17 04:47:13 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 04:47:13 GMT Subject: Integrated: 8163229: several regression tests have a main method that is never executed In-Reply-To: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> References: <43_ndNUnEtQisakxCPVIqZGvizAmLUd2cKQ60X_3HRs=.05235cae-336f-4cb4-9e2a-88c4ba5753b8@github.com> Message-ID: On Fri, 4 Nov 2022 16:30:10 GMT, Archie L. Cobbs wrote: > This PR deals with some housekeeping relating to compiler unit tests. > > JDK-8163229 points out that there are several tests that have a `public static void main(String[])` method, but because the test expects to fail during compilation, the test is never actually run, and so these `main` methods are just clutter that can be removed. > > However, there are also some tests where the test is never run, but the `main()` method generates one or more of the expected compilation errors. Obviously we need to keep those, but they don't need to be declared as `public static void main(String[])` which is misleading. So instead we rename these methods to `meth()`, and also we remove the `String[]` parameter when it's not needed by the test. This pull request has now been integrated. Changeset: 382fe51b Author: Archie L. Cobbs Committer: Julian Waters URL: https://git.openjdk.org/jdk/commit/382fe51b6d7eba7094afa070032bedaa9ffc0633 Stats: 191 lines in 129 files changed: 0 ins; 72 del; 119 mod 8163229: several regression tests have a main method that is never executed Reviewed-by: vromero ------------- PR: https://git.openjdk.org/jdk/pull/10992 From mcimadamore at openjdk.org Tue Jan 17 11:14:28 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 17 Jan 2023 11:14:28 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Sat, 14 Jan 2023 01:54:23 GMT, Archie L. Cobbs wrote: >>> Ok - I thought false negative was the thing to absolutely avoid - and that was the no. 1 concern. >> >> You're right. I think at the time I reasoned that it would be unusual enough for the type of an expression to start as an instanceof X, then change to not being an instanceof X, and then change back, that it was worth it to go ahead and filter these out. But admittedly that was based on intuition, not science. >> >>> I think a possible approach to keep both the filtering and the code more or less similar to what you have, is to save the type of the expression in the ExprRef. Then, I believe that, at the end of scan() you can just get whatever type is there, and check that it's the correct one, if not drop it. >> >> That's a nice idea... thanks. I'll play around with it some. > > I was curious how much of a difference this type filtering makes, so I built the JDK with and without it. > > The results were identical except for one case: > > package java.lang.invoke; > ... > public abstract sealed class CallSite permits ConstantCallSite, MutableCallSite, VolatileCallSite { > ... > CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable { > this(targetType); // need to initialize target to make CallSite.type() work in createTargetHook > ConstantCallSite selfCCS = (ConstantCallSite) this; > MethodHandle boundTarget = (MethodHandle) createTargetHook.invokeWithArguments(selfCCS); > setTargetNormal(boundTarget); // ConstantCallSite doesn't publish CallSite.target > UNSAFE.storeStoreFence(); // barrier between target and isFrozen updates > } > > When we do type filtering, `(ConstantCallSite) this` causes the 'this' reference to be discarded so no leak is reported on the next line for `invokeWithArguments(selfCCS)`. Just a side note, there is also a leak on the next line because final method `setTargetNormal()` invokes `MethodHandleNatives.setCallSiteTargetNormal(this, newTarget)`, so a leak does get reported anyway even with type filtering. > > When type filtering is disabled, we report a leak at `invokeWithArguments(selfCCS)` - which is accurate. > > So what did we learn? > > First it looks like type filtering has very minimal effect. I think this is because it requires some version of two casts in a row in and out of type compatibility, and this is probably very rare. > > But looking at the one data point we do have, the type filtering did in fact cause a false negative. > > And when building the entire JDK, it causes zero net new false positives. > > So to me this is evidence that we should just remove the type filtering altogether... > > @vicente-romero-oracle your thoughts? I believe the conclusion you reached is sound - it doesn't look like type filtering adds much, and it can be actively harmful. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Tue Jan 17 11:18:30 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 17 Jan 2023 11:18:30 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 23:22:00 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Remove unused type variable on method visitScoped(). > - Remove expression type filtering; it doesn't seem to be needed. > - Clean up unused import. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 444: > 442: > 443: // Sanity check > 444: Assert.check(checkInvariants(true, referenceExpressionNode)); Just a note that now the only reason we set up that big switch is to capture `referenceExpressionNode` which is only used in `checkInvariants` (which looks more of a debugging function). I'll leave it up to you whether to keep it as is. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Tue Jan 17 11:29:31 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 17 Jan 2023 11:29:31 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 23:22:00 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Remove unused type variable on method visitScoped(). > - Remove expression type filtering; it doesn't seem to be needed. > - Clean up unused import. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 417: > 415: boolean referenceExpressionNode; > 416: switch (tree.getTag()) { > 417: case SWITCH_EXPRESSION: Missing indent? src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1450: > 1448: > 1449: // Information about a constructor or method in the compilation unit > 1450: private static class MethodInfo { This could be a record, right? I believe you can then drop accessors and toString? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Tue Jan 17 11:47:29 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 17 Jan 2023 11:47:29 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 23:22:00 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Remove unused type variable on method visitScoped(). > - Remove expression type filtering; it doesn't seem to be needed. > - Clean up unused import. I was looking more at the warnings generated with the Lint enabled - and found this one, which is interesting (src/classes/build/tools/cldrconverter/Bundle.java): private static final Map bundles = new HashMap<>(); ... Bundle(String id, String cldrPath, String bundles, String currencies) { // escaping constructor this.id = id; this.cldrPath = cldrPath; if ("localenames".equals(bundles)) { bundleTypes = EnumSet.of(Type.LOCALENAMES); } else if ("currencynames".equals(bundles)) { bundleTypes = EnumSet.of(Type.CURRENCYNAMES); } else { bundleTypes = Type.ALL_TYPES; } if (currencies == null) { currencies = "local"; } this.currencies = currencies; addBundle(); } private void addBundle() { Bundle.bundles.put(id, this); // escaping here } Now, this reminds me a lot of some of the examples with static factories we discussed last week. The Bundle constructor is non-private, so it gets the analysis. There is a call to the private method `addBundle` - which also gets inspected. This method accesses the static hashmap and then calls "put" on it, passing the `this` parameter. Now, according to my understanding, this is not, strictly speaking, a classic case of escaping this through a virtual method call (which can be overridden in a subclass). Here `this` is just escaping "somewhere" (a static hashmap). Yes, other clients might be able to access the hashmap, and observe a possibly uninitialized value - but this is in the same bucket as the factory example I gave last week, where a private constructor (called by public factory) was leaking `this` via a static method. Given this, I believe the above case is a "false positive". The problem seems to be that we don't know what the code for HashMap::put is, so we cannot know if that code might end up calling some virtual method on our `this` - and so we warn. Correct? It is a bit sad because an idiom such as this is not infrequent - e.g. a constructor setting up some "cached" value somewhere - but, because of the limitations of the analysis, this is treated as a case of escaping. I wonder if leveraging module boundaries here could help: the only way for `Map::put` to leverage some virtual method in `this` (whose type is Bundle) is if if the map implementation can access Bundle - but in this case we know that the map is an HashMap (static final constant) - and HashMap is defined in a module that doesn't have access to Bundle. Actually, in this case, since Bundle is package-private, we know that no code outside this package will be able to do much with it (unless the package also defines a public/protected sublass). I think stuff like this could be used to reduce the rate of false positives when calling methods we can't inspect - but it's probably something that is hard to generalize. While we can reason about module and package boundaries - one thorny problem here is that what Map::put implementation is invoked depends on what map instance is assigned to the final field (because, dynamic dispatch). So, unless the escaping method is static, the analysis required to detect these false positive would likely be prohibitive (and, rarely applicable). As I said, a bit sad, because this idiom is frequent - I counted how many times did a ".put(... this)" occured in the Lint warnings generated by this PR and found 88 matches. Not sky-high, but not negligible either. And the issue here is that the programmer is likely doing "the right" thing, so the warning will be perceived as a tad annoying. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 17 14:49:39 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 14:49:39 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 11:23:07 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: >> >> - Remove unused type variable on method visitScoped(). >> - Remove expression type filtering; it doesn't seem to be needed. >> - Clean up unused import. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 417: > >> 415: boolean referenceExpressionNode; >> 416: switch (tree.getTag()) { >> 417: case SWITCH_EXPRESSION: > > Missing indent? Thanks - will fix (habits are hard to break). > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 444: > >> 442: >> 443: // Sanity check >> 444: Assert.check(checkInvariants(true, referenceExpressionNode)); > > Just a note that now the only reason we set up that big switch is to capture `referenceExpressionNode` which is only used in `checkInvariants` (which looks more of a debugging function). I'll leave it up to you whether to keep it as is. Correct... the debug check is valuable and low cost so I think it's worth keeping for now. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 17 14:53:49 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 14:53:49 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 11:23:24 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: >> >> - Remove unused type variable on method visitScoped(). >> - Remove expression type filtering; it doesn't seem to be needed. >> - Clean up unused import. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1450: > >> 1448: >> 1449: // Information about a constructor or method in the compilation unit >> 1450: private static class MethodInfo { > > This could be a record, right? I believe you can then drop accessors and toString? Yes! Will fix - thanks. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 17 15:39:42 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 15:39:42 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 11:44:22 GMT, Maurizio Cimadamore wrote: > Yes, other clients might be able to access the hashmap, and observe a possibly uninitialized value - but this is in the same bucket as the factory example I gave last week, where a private constructor (called by public factory) was leaking this via a static method. It's similar but slightly different - in [your earlier example](https://github.com/openjdk/jdk/pull/11874#discussion_r1069250348), there was no chance a subclass was involved, so no leak was possible (according to our definition of a leak, which requires a subclass involvement). In this `Bundle` example, a subclass could be involved so the warning is generated. But that's just a technicality - I get what you're saying. > Given this, I believe the above case is a "false positive". The problem seems to be that we don't know what the code for HashMap::put is, so we cannot know if that code might end up calling some virtual method on our this - and so we warn. Correct? Yes, although it's a "false positive" according to our defined semantics... well, to be clear: it's a false positive in that there is actually no bug there, but it's not a false positive in the sense that an actual "leak" is occurring, based on our definition of "leak". For example, suppose the subclass of `Bundle` happens to implement `Predicate` and `HashMap::put` happens to invoke `test()` on any values that implement `Predicate`. Because our semantics say to treat `HashMap::put` like a black box and make no assumptions on its behavior we have to admit this unlikely scenario. But I'm being technical. What programmer's actually care about is how often the warning actually helps them prevent an _actual or probable bug_, not whether it meets some technical definition. > the only way for Map::put to leverage some virtual method in this (whose type is Bundle) is if if the map implementation can access Bundle Except for the subclass implementing some interface and `HashMap` casting for it. > As I said, a bit sad, because this idiom is frequent... I am in agreement with your general sentiment. In short, we want a higher ratio of "actual bug possibilities" to "really obscure and unlikely bug possibilities". Based on this and our other discussions I'm thinking that, at least for the first round, we should be less aggressive. Then later, as we get more experience with the warning over time, we can tighten the screws if needed. An easy way to be less aggressive is to draw a more conservative "maintenance boundary", which is the area inside of which we don't care about 'this' escape bugs. In the current implementation, the maintenance boundary = the compilation unit (i.e., the source file `X.java`). So to limit ourselves to possible bugs we do care about, we ask: Is X not final, not sealed (or, sealed but permitting some class defined outside of X.java), and does X have a non-private constructor? Instead, we could widen the maintenance boundary to the package/module boundary, and instead ask: Is X public, not final, not sealed, and does X have a non-private constructor? This is not a perfect drawing of that boundary, because it ignores which packages are exported in a module, but that error is a conservative one, and it avoids tricky issues with how files are compiled. This would eliminate your false positive example above, albeit not for the reasons you state, but rather simply because `Bundle` is package-private. From previous test, it reduces warnings in the JDK by 36%. Your thoughts? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Tue Jan 17 16:11:36 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 17 Jan 2023 16:11:36 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 15:36:49 GMT, Archie L. Cobbs wrote: > nstead, we could widen the maintenance boundary to the package/module boundary, and instead ask: Is X public, not final, not sealed, and does X have a non-private constructor? > > This is not a perfect drawing of that boundary, because it ignores which packages are exported in a module, but that error is a conservative one, and it avoids tricky issues with how files are compiled. > > This would eliminate your false positive example above, albeit not for the reasons you state, but rather simply because `Bundle` is package-private. From previous test, it reduces warnings in the JDK by 36%. > > Your thoughts? I agree with this conclusion. Also, even if a class is public, our question should be: is this class in a non-exported package? Because, if so, even a public class can be "implementation specific". ------------- PR: https://git.openjdk.org/jdk/pull/11874 From briangoetz at openjdk.org Tue Jan 17 16:11:40 2023 From: briangoetz at openjdk.org (Brian Goetz) Date: Tue, 17 Jan 2023 16:11:40 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 23:22:00 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Remove unused type variable on method visitScoped(). > - Remove expression type filtering; it doesn't seem to be needed. > - Clean up unused import. Let's not forget that allowing `this` to escape not only offers the opportunity for entertaining "how could this field be null" bugs, but also invalidates the final field safety guarantees of the JMM.? So I think excluding private classes because they can't be extended only addresses half the risk. A more complete analysis would analyze the base class + possible subclass combinations, and could exclude some escapes which are harmless (i.e., the base class passes `this` to an overridable method, but no overrides make use of it, and no other ovverides are possible).? But that seems its moving in the opposite direction of what you're looking for? On 1/17/2023 10:50 AM, Maurizio Cimadamore wrote: > > I agree with this conclusion. Also, even if a class is public, our > question should be: is this class in a non-exported package? Because, > if so, even a public class can be "implementation specific". > ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jlahoda at openjdk.org Tue Jan 17 16:20:20 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Tue, 17 Jan 2023 16:20:20 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v10] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 22:48:59 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Fix bug where field initializer warnings could be incorrectly suppressed. > - Consolidate all the unit tests that generate warnings into one. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 293: > 291: return !currentClass.sym.isFinal() && > 292: !(currentClass.sym.isSealed() && currentClass.permitting.isEmpty()) && > 293: !(currentClass.sym.owner.kind == MTH) && Maybe `isDirectlyOrIndirectlyLocal`? Suggestion: !currentClass.sym.isDirectlyOrIndirectlyLocal() (Or enhance the `privateOuter` flag to also handle local classes? something like `tree.sym.kind.matches(Kinds.KindSelector.VAL_MTH)`.) src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 298: > 296: }.scan(env.tree); > 297: > 298: // TODO: eliminate sealed classes where all permitted subclasses are in this compilation unit +1 on better check for permitted (shouldn't be too difficult, or am I mistaken?) src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 327: > 325: JCBlock block = (JCBlock)defs.head; > 326: visitTopLevel(klass, () -> analyzeStatements(block.stats)); > 327: continue; Nit: this continue is unnecessary; maybe use `instanceof JCBlok block` instead of `.hasTag(BLOCK)` (inside javac, where we know the implementation classes, we decided to do pattern matching `instanceof`, I believe). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jlahoda at openjdk.org Tue Jan 17 16:20:24 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Tue, 17 Jan 2023 16:20:24 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 23:22:00 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Remove unused type variable on method visitScoped(). > - Remove expression type filtering; it doesn't seem to be needed. > - Clean up unused import. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 908: > 906: public void visitAssert(JCAssert tree) { > 907: scan(tree.cond); > 908: refs.discardExprs(depth); Should also handle `tree.detail`? (Obscure of course, but could be `assert true : foo(this);`.) ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 17 17:19:40 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 17:19:40 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v10] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 13:30:11 GMT, Jan Lahoda wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Fix bug where field initializer warnings could be incorrectly suppressed. >> - Consolidate all the unit tests that generate warnings into one. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 293: > >> 291: return !currentClass.sym.isFinal() && >> 292: !(currentClass.sym.isSealed() && currentClass.permitting.isEmpty()) && >> 293: !(currentClass.sym.owner.kind == MTH) && > > Maybe `isDirectlyOrIndirectlyLocal`? > Suggestion: > > !currentClass.sym.isDirectlyOrIndirectlyLocal() > > > (Or enhance the `privateOuter` flag to also handle local classes? something like `tree.sym.kind.matches(Kinds.KindSelector.VAL_MTH)`.) Yes, that's better - thanks, will fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 17 17:58:42 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 17:58:42 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v10] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 13:30:57 GMT, Jan Lahoda wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Fix bug where field initializer warnings could be incorrectly suppressed. >> - Consolidate all the unit tests that generate warnings into one. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 298: > >> 296: }.scan(env.tree); >> 297: >> 298: // TODO: eliminate sealed classes where all permitted subclasses are in this compilation unit > > +1 on better check for permitted (shouldn't be too difficult, or am I mistaken?) Yes it's easy & I was just procrastinating. Will fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jlaskey at openjdk.org Tue Jan 17 18:03:39 2023 From: jlaskey at openjdk.org (Jim Laskey) Date: Tue, 17 Jan 2023 18:03:39 GMT Subject: RFR: JDK-8285932 Implementation of JEP 430 String Templates (Preview) [v34] In-Reply-To: References: Message-ID: <4iErqSLrHHY_Wmv5yztRHFs5v2LGQTjez0TJMfZ_sV0=.0a73c032-240e-4957-ac28-51d93091beae@github.com> On Wed, 11 Jan 2023 14:07:53 GMT, Jim Laskey wrote: >> Enhance the Java programming language with string templates, which are similar to string literals but contain embedded expressions. A string template is interpreted at run time by replacing each expression with the result of evaluating that expression, possibly after further validation and transformation. This is a [preview language feature and API](http://openjdk.java.net/jeps/12). > > Jim Laskey has updated the pull request incrementally with one additional commit since the last revision: > > Update to JDK 21 Still active. ------------- PR: https://git.openjdk.org/jdk/pull/10889 From vromero at openjdk.org Tue Jan 17 18:12:57 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 17 Jan 2023 18:12:57 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 23:22:00 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Remove unused type variable on method visitScoped(). > - Remove expression type filtering; it doesn't seem to be needed. > - Clean up unused import. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 215: > 213: // Classify all ctors and methods as analyzable and/or invokable. > 214: // Track which constructors and fields have warnings suppressed. > 215: new TreeScanner() { I wonder if it would be better to have this visitor be defined externally, the benefit of this would be that it can be created only once instead of every time we enter this method, also I think it would improve the readability of this method. But I let this to your consideration ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 17 18:16:20 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 18:16:20 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 16:15:33 GMT, Jan Lahoda wrote: >> Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: >> >> - Remove unused type variable on method visitScoped(). >> - Remove expression type filtering; it doesn't seem to be needed. >> - Clean up unused import. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 908: > >> 906: public void visitAssert(JCAssert tree) { >> 907: scan(tree.cond); >> 908: refs.discardExprs(depth); > > Should also handle `tree.detail`? (Obscure of course, but could be `assert true : foo(this);`.) Thanks - will fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 17 18:36:12 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 18:36:12 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 18:09:51 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: >> >> - Remove unused type variable on method visitScoped(). >> - Remove expression type filtering; it doesn't seem to be needed. >> - Clean up unused import. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 215: > >> 213: // Classify all ctors and methods as analyzable and/or invokable. >> 214: // Track which constructors and fields have warnings suppressed. >> 215: new TreeScanner() { > > I wonder if it would be better to have this visitor be defined externally, the benefit of this would be that it can be created only once instead of every time we enter this method, also I think it would improve the readability of this method. But I let this to your consideration This method is only supposed to ever be entered once... but you made me realize that there should probably be an assertion check for that assumption. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 17 19:21:27 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 19:21:27 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 15:53:57 GMT, Brian Goetz wrote: > A more complete analysis would analyze the base class + possible subclass combinations, and could exclude some escapes which are harmless (i.e., the base class passes `this` to an overridable method, but no overrides make use of it, and no other ovverides are possible). But that seems its moving in the opposite direction of what you're looking for? So far we've stuck to the requirement that whatever analysis we are doing is done on a a per-file basis, one at a time, so analyzing possible class + subclass combinations is currently limited to what's available in a single file. Now this is not an inviolate requirement, and removing it would certainly enable the analysis to rule out more false positives (as with your example), but it's not something we've really considered doing yet, mainly because of item 2 below. In the big picture, it seems like our goals are roughly: 1. Be able to detect a high % of the "truly threatening" leaks that are out there (minimize false negatives) 1. Keep the implementation relative simple and minimize compiler performance impact 1. Try to avoid having so many false positives that developers are turned off or annoyed I think we're pretty good on item 1, although this one somewhat of a speculative judgement call. For item 2 we're in the right ballpark I think... (others may disagree). For item 3, this is where there is still some worry and uncertainty. It's not just about what kind of leaks/bugs are out there, it's also that it's hard to predict how humans will react. So starting with a less aggressive posture, allowing for getting more so over time, is a the more conservative option. The simplest way to do that is to widen the "maintenance boundary" as mentioned. Now this could impact item 1 but at least any new false negatives would necessarily be contained within a single package/module. To restate: we can always get more aggressive if that turns out to be warranted. But if you start out too aggressive and the world barfs on it and just turns it off, you've probably missed your chance forever. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 17 19:49:07 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 19:49:07 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v12] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with seven additional commits since the last revision: - Omit sealed classes when permitted subclasses are in the compilation unit. - Add assertion check for reuse of analyzer, which is unsupported. - Include assert detail expressions in the analysis. - Use more modern patterned instanceof instead of hasTag() + cast. - Use TreeInfo.isDirectlyOrIndirectlyLocal() to detect such classes. - Clean up code a bit by using a record for "MethodInfo" class. - Properly indent switch statement. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/a0b4310d..24730cb3 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=11 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=10-11 Stats: 111 lines in 2 files changed: 33 ins; 38 del; 40 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Tue Jan 17 20:34:32 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 17 Jan 2023 20:34:32 GMT Subject: [jdk20] RFR: 8300195: Fall-through issue occurs when using record pattern in switch statements In-Reply-To: References: Message-ID: <0rvVDNuIuIPjvJUJlie6hP1gcAdsPvrAVTnVWe45QqY=.37844aa9-b7bd-44eb-907e-6ca64ea88396@github.com> On Mon, 16 Jan 2023 15:11:12 GMT, Jan Lahoda wrote: > When converting pattern matching switches, cases with common prefix tests are factored out into separate sub-switches. But, when this happens, the cases generated are the statement cases, even if the original cases where rule cases. So, this may lead to an unintended fall through. The proposal here is to inject breaks with correct targets as needed. > > Alternatively, we could keep the kind of the cases, but that is more tricky, as the cases must break the main switch, not the nested ones. looks sensible ------------- Marked as reviewed by vromero (Reviewer). PR: https://git.openjdk.org/jdk20/pull/109 From duke at openjdk.org Tue Jan 17 22:29:54 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 22:29:54 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 15:53:57 GMT, Brian Goetz wrote: > I agree with this conclusion. Also, even if a class is public, our question should be: is this class in a non-exported package? Because, if so, even a public class can be "implementation specific". Agreed - I originally thought this was harder but actually the containing module is easy to access. I've prototyped this now in a new `ThisEscapeModule` branch - relative diff is [here](https://github.com/archiecobbs/jdk/compare/ThisEscape...archiecobbs:jdk:ThisEscapeModule). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 17 23:59:04 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 17 Jan 2023 23:59:04 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v13] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Document the this-escape lint option in the javac(1) man page. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/24730cb3..6666df57 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=12 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=11-12 Stats: 44 lines in 1 file changed: 44 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From jlahoda at openjdk.org Wed Jan 18 10:29:36 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Wed, 18 Jan 2023 10:29:36 GMT Subject: [jdk20] RFR: 8300195: Fall-through issue occurs when using record pattern in switch statements [v2] In-Reply-To: References: Message-ID: > When converting pattern matching switches, cases with common prefix tests are factored out into separate sub-switches. But, when this happens, the cases generated are the statement cases, even if the original cases where rule cases. So, this may lead to an unintended fall through. The proposal here is to inject breaks with correct targets as needed. > > Alternatively, we could keep the kind of the cases, but that is more tricky, as the cases must break the main switch, not the nested ones. Jan Lahoda has updated the pull request incrementally with one additional commit since the last revision: Fixing test on Windows. ------------- Changes: - all: https://git.openjdk.org/jdk20/pull/109/files - new: https://git.openjdk.org/jdk20/pull/109/files/4f7b2fa3..5ecb6eda Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk20&pr=109&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk20&pr=109&range=00-01 Stats: 3 lines in 1 file changed: 2 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk20/pull/109.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/109/head:pull/109 PR: https://git.openjdk.org/jdk20/pull/109 From jlahoda at openjdk.org Wed Jan 18 10:47:25 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Wed, 18 Jan 2023 10:47:25 GMT Subject: [jdk20] Integrated: 8300195: Fall-through issue occurs when using record pattern in switch statements In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 15:11:12 GMT, Jan Lahoda wrote: > When converting pattern matching switches, cases with common prefix tests are factored out into separate sub-switches. But, when this happens, the cases generated are the statement cases, even if the original cases where rule cases. So, this may lead to an unintended fall through. The proposal here is to inject breaks with correct targets as needed. > > Alternatively, we could keep the kind of the cases, but that is more tricky, as the cases must break the main switch, not the nested ones. This pull request has now been integrated. Changeset: c1b4212a Author: Jan Lahoda URL: https://git.openjdk.org/jdk20/commit/c1b4212a53e5d26108e560a82250b01689ae03f0 Stats: 126 lines in 2 files changed: 115 ins; 4 del; 7 mod 8300195: Fall-through issue occurs when using record pattern in switch statements Reviewed-by: vromero ------------- PR: https://git.openjdk.org/jdk20/pull/109 From jwilhelm at openjdk.org Wed Jan 18 22:07:58 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Wed, 18 Jan 2023 22:07:58 GMT Subject: RFR: Merge jdk20 Message-ID: Forwardport JDK 20 -> JDK 21 ------------- Commit messages: - Merge remote-tracking branch 'jdk20/master' into Merge_jdk20 - 8300275: SegmentScope.isAccessibleBy returning incorrect values - 8300195: Fall-through issue occurs when using record pattern in switch statements - 8295723: security/infra/wycheproof/RunWycheproof.java fails with Assertion Error - 8295687: Better BMP bounds - 8293742: Better Banking of Sounds - 8293554: Enhanced DH Key Exchanges - 8287411: Enhance DTLS Performance - 8293717: Objective view of ObjectView - 8293734: Improve BMP image handling - ... and 5 more: https://git.openjdk.org/jdk/compare/8b70c432...77fb81ec The webrevs contain the adjustments done while merging with regards to each parent branch: - master: https://webrevs.openjdk.org/?repo=jdk&pr=12085&range=00.0 - jdk20: https://webrevs.openjdk.org/?repo=jdk&pr=12085&range=00.1 Changes: https://git.openjdk.org/jdk/pull/12085/files Stats: 564 lines in 27 files changed: 332 ins; 117 del; 115 mod Patch: https://git.openjdk.org/jdk/pull/12085.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12085/head:pull/12085 PR: https://git.openjdk.org/jdk/pull/12085 From duke at openjdk.org Wed Jan 18 22:27:08 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 18 Jan 2023 22:27:08 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v14] In-Reply-To: References: Message-ID: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: - Relax warning to apply only if subclass could exist in another module/package. - Tweaks to man page. - Add YieldRef to Javadoc algorithm summary. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/6666df57..86e26a74 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=13 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=12-13 Stats: 191 lines in 9 files changed: 16 ins; 136 del; 39 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 18 22:27:08 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 18 Jan 2023 22:27:08 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v13] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 23:59:04 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: > > Document the this-escape lint option in the javac(1) man page. FYI, based on discussions & feedback I'm making the warning less aggressive. We'll now only warn when a subclass could exist outside of the current module, instead of outside the current compilation unit (i.e., source file). FWIW this reduces the warning count in the JDK itself from 2093 to 1334 (36% reduction). In the future we can consider tightening this up, but for now this will be a more conservative way to introduce the new warning to the world. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From darcy at openjdk.org Wed Jan 18 23:08:18 2023 From: darcy at openjdk.org (Joe Darcy) Date: Wed, 18 Jan 2023 23:08:18 GMT Subject: RFR: JDK-8300595: Use improved @see and @link syntax in javax.lang.model Message-ID: I'll update copyright years if needed before pushing. ------------- Commit messages: - JDK-8300595: Use improved @see and @link syntax in javax.lang.model Changes: https://git.openjdk.org/jdk/pull/12086/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12086&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8300595 Stats: 27 lines in 7 files changed: 0 ins; 0 del; 27 mod Patch: https://git.openjdk.org/jdk/pull/12086.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12086/head:pull/12086 PR: https://git.openjdk.org/jdk/pull/12086 From jjg at openjdk.org Wed Jan 18 23:08:20 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Wed, 18 Jan 2023 23:08:20 GMT Subject: RFR: JDK-8300595: Use improved @see and @link syntax in javax.lang.model In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 22:55:29 GMT, Joe Darcy wrote: > I'll update copyright years if needed before pushing. Can you change the JBS description, and PR description, to include `javax.tools`, please src/java.compiler/share/classes/javax/lang/model/util/Elements.java line 60: > 58: * {@link #getPackageElement(ModuleElement, CharSequence)}, > 59: * where the provided ModuleSymbol is any > 60: * {@linkplain java.lang.module##root-modules root module}, whatta lotta dots! ------------- Marked as reviewed by jjg (Reviewer). PR: https://git.openjdk.org/jdk/pull/12086 From darcy at openjdk.org Wed Jan 18 23:11:32 2023 From: darcy at openjdk.org (Joe Darcy) Date: Wed, 18 Jan 2023 23:11:32 GMT Subject: RFR: JDK-8300595: Use improved @see and @link syntax in javax.lang.model and javax.tools In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 23:00:44 GMT, Jonathan Gibbons wrote: >> I'll update copyright years if needed before pushing. > > src/java.compiler/share/classes/javax/lang/model/util/Elements.java line 60: > >> 58: * {@link #getPackageElement(ModuleElement, CharSequence)}, >> 59: * where the provided ModuleSymbol is any >> 60: * {@linkplain java.lang.module##root-modules root module}, > > whatta lotta dots! Dots be gone! :-) ------------- PR: https://git.openjdk.org/jdk/pull/12086 From duke at openjdk.org Wed Jan 18 23:12:34 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 18 Jan 2023 23:12:34 GMT Subject: RFR: 7176515: ExceptionInInitializerError for an enum with multiple switch statements [v8] In-Reply-To: References: Message-ID: > This patch is both a minor optimization and a fix for JDK-7176515. > > JDK-7176515 relates to how javac handles `switch` statements on `Enum` values, which are effectively "syntactic sugar". > > The simple approach would be to just get the enum's `ordinal()` value and then revert to a normal integer value switch on that. However, this snapshots the ordinal values at compile-time, and thus can fail if the `Enum` class is recompiled later. > > Presumably to avoid that possibility (are there any other reasons?) the compiler instead uses a lookup table. This table is dynamically constructed at runtime by a static initializer in a synthetic class. This avoids the "stale ordinal" problem of the simple approach, but it also creates a potential class initialization loop if there happens to an `Enum` switch inside an `Enum` class constructor, as demonstrated by the bug. > > This patch makes the following change: If we are handling an `Enum` switch, and the `Enum` class we are switching on is also the class we are compiling, then just go with the simple approach, because the "stale ordinal" problem can't happen in this case so there's no need to build a runtime lookup table. > > This results in two improvements: > * It avoids building the lookup table for switches on self > * It fixes JDK-7176515 as stated > > Although the reproducing test case provided in JDK-7176515 gets fixed by this patch, the underlying issue is still there and can still be triggered with a slightly more complicated test case (included, but commented out). > > So JDK-7176515 could be left open (or a new bug created) and a separate discussion had about how to "really" fix it. > > Part of this discussion should be defining what that means, i.e., the boundaries of the bug. There are some scenarios that are basically impossible to fix, for example, two `Enum` classes whose constructors take as a parameter instances of the other `Enum` class and then switch on it. That cycle has nothing to do with how switches are handled. Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Simplify code a bit by using Map.computeIfAbsent(). ------------- Changes: - all: https://git.openjdk.org/jdk/pull/10797/files - new: https://git.openjdk.org/jdk/pull/10797/files/6f7f30f7..53be679b Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=07 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=10797&range=06-07 Stats: 4 lines in 1 file changed: 0 ins; 3 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/10797.diff Fetch: git fetch https://git.openjdk.org/jdk pull/10797/head:pull/10797 PR: https://git.openjdk.org/jdk/pull/10797 From darcy at openjdk.org Wed Jan 18 23:19:57 2023 From: darcy at openjdk.org (Joe Darcy) Date: Wed, 18 Jan 2023 23:19:57 GMT Subject: RFR: JDK-8300595: Use improved @see and @link syntax in javax.lang.model and javax.tools [v2] In-Reply-To: References: Message-ID: > I'll update copyright years if needed before pushing. Joe Darcy has updated the pull request incrementally with one additional commit since the last revision: Update copyrights. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12086/files - new: https://git.openjdk.org/jdk/pull/12086/files/1af9bae3..138f4cea Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12086&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12086&range=00-01 Stats: 7 lines in 7 files changed: 0 ins; 0 del; 7 mod Patch: https://git.openjdk.org/jdk/pull/12086.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12086/head:pull/12086 PR: https://git.openjdk.org/jdk/pull/12086 From jwilhelm at openjdk.org Wed Jan 18 23:32:35 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Wed, 18 Jan 2023 23:32:35 GMT Subject: Integrated: Merge jdk20 In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 21:56:13 GMT, Jesper Wilhelmsson wrote: > Forwardport JDK 20 -> JDK 21 This pull request has now been integrated. Changeset: fc9f8baf Author: Jesper Wilhelmsson URL: https://git.openjdk.org/jdk/commit/fc9f8baf56a8888362ad60d0e6dc8953690b80d3 Stats: 564 lines in 27 files changed: 332 ins; 117 del; 115 mod Merge ------------- PR: https://git.openjdk.org/jdk/pull/12085 From iris at openjdk.org Thu Jan 19 00:08:27 2023 From: iris at openjdk.org (Iris Clark) Date: Thu, 19 Jan 2023 00:08:27 GMT Subject: RFR: JDK-8300595: Use improved @see and @link syntax in javax.lang.model and javax.tools [v2] In-Reply-To: References: Message-ID: <_lQpxg2a0QseLpt3qXINYz-xCfqgBfkTeDJ9i6ozi10=.6bc7828e-e08b-4d82-9bbd-13d67cb932d2@github.com> On Wed, 18 Jan 2023 23:19:57 GMT, Joe Darcy wrote: >> I'll update copyright years if needed before pushing. > > Joe Darcy has updated the pull request incrementally with one additional commit since the last revision: > > Update copyrights. Marked as reviewed by iris (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12086 From darcy at openjdk.org Thu Jan 19 01:17:36 2023 From: darcy at openjdk.org (Joe Darcy) Date: Thu, 19 Jan 2023 01:17:36 GMT Subject: Integrated: JDK-8300595: Use improved @see and @link syntax in javax.lang.model and javax.tools In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 22:55:29 GMT, Joe Darcy wrote: > I'll update copyright years if needed before pushing. This pull request has now been integrated. Changeset: 8e3036cf Author: Joe Darcy URL: https://git.openjdk.org/jdk/commit/8e3036cf7430cee5c5df2584d0a0eef816868c62 Stats: 34 lines in 7 files changed: 0 ins; 0 del; 34 mod 8300595: Use improved @see and @link syntax in javax.lang.model and javax.tools Reviewed-by: jjg, iris ------------- PR: https://git.openjdk.org/jdk/pull/12086 From darcy at openjdk.org Thu Jan 19 21:53:44 2023 From: darcy at openjdk.org (Joe Darcy) Date: Thu, 19 Jan 2023 21:53:44 GMT Subject: RFR: JDK-8300400: Update --release 20 symbol information for JDK 20 build 32 Message-ID: Bug JDK-8299740 in JDK 20 b32 introduced a change that should be reflected in the symbol file. ------------- Commit messages: - JDK-8300400: Update --release 20 symbol information for JDK 20 build 32 Changes: https://git.openjdk.org/jdk/pull/12105/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12105&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8300400 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/12105.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12105/head:pull/12105 PR: https://git.openjdk.org/jdk/pull/12105 From iris at openjdk.org Thu Jan 19 22:02:01 2023 From: iris at openjdk.org (Iris Clark) Date: Thu, 19 Jan 2023 22:02:01 GMT Subject: RFR: JDK-8300400: Update --release 20 symbol information for JDK 20 build 32 In-Reply-To: References: Message-ID: On Thu, 19 Jan 2023 21:43:59 GMT, Joe Darcy wrote: > Bug JDK-8299740 in JDK 20 b32 introduced a change that should be reflected in the symbol file. Marked as reviewed by iris (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12105 From jjg at openjdk.org Thu Jan 19 23:18:20 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Thu, 19 Jan 2023 23:18:20 GMT Subject: RFR: JDK-8300400: Update --release 20 symbol information for JDK 20 build 32 In-Reply-To: References: Message-ID: On Thu, 19 Jan 2023 21:43:59 GMT, Joe Darcy wrote: > Bug JDK-8299740 in JDK 20 b32 introduced a change that should be reflected in the symbol file. Marked as reviewed by jjg (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12105 From darcy at openjdk.org Thu Jan 19 23:27:23 2023 From: darcy at openjdk.org (Joe Darcy) Date: Thu, 19 Jan 2023 23:27:23 GMT Subject: Integrated: JDK-8300400: Update --release 20 symbol information for JDK 20 build 32 In-Reply-To: References: Message-ID: On Thu, 19 Jan 2023 21:43:59 GMT, Joe Darcy wrote: > Bug JDK-8299740 in JDK 20 b32 introduced a change that should be reflected in the symbol file. This pull request has now been integrated. Changeset: 93a933d4 Author: Joe Darcy URL: https://git.openjdk.org/jdk/commit/93a933d4eff24f975dea32cd4b2b28ccbb50ed8f Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod 8300400: Update --release 20 symbol information for JDK 20 build 32 Reviewed-by: iris, jjg ------------- PR: https://git.openjdk.org/jdk/pull/12105 From asotona at openjdk.org Fri Jan 20 11:09:03 2023 From: asotona at openjdk.org (Adam Sotona) Date: Fri, 20 Jan 2023 11:09:03 GMT Subject: RFR: 8300740: Add @SuppressWarnings option "lossy-conversions" description to jdk.compiler module javadoc and javac man page Message-ID: Hi, @SuppressWarnings option "lossy-conversions" has been added to JDK 20 (see JDK-8286377), however the option description is missing in jdk.compiler module javadoc and javac man page. This patch add missing javadoc decription to jdk.compiler module-info.java Please review. Thanks, Adam ------------- Commit messages: - 8300740: Add @SuppressWarnings option "lossy-conversions" description to jdk.compiler module javadoc and javac man page Changes: https://git.openjdk.org/jdk/pull/12111/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12111&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8300740 Stats: 1 line in 1 file changed: 1 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/12111.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12111/head:pull/12111 PR: https://git.openjdk.org/jdk/pull/12111 From duke at openjdk.org Fri Jan 20 15:11:28 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 20 Jan 2023 15:11:28 GMT Subject: RFR: 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc In-Reply-To: References: Message-ID: On Fri, 20 Jan 2023 10:59:48 GMT, Adam Sotona wrote: > Hi, > @SuppressWarnings option "lossy-conversions" has been added to JDK 20 (see JDK-8286377), however the option description is missing in jdk.compiler module javadoc and javac man page. > This patch add missing javadoc decription to jdk.compiler module-info.java > > Please review. > > Thanks, > Adam The current patch doesn't include a man page update (the bug refers to both Javadoc and man page). That's OK but if so then maybe the bug should be split into two as well so the man page part of the issue can be tracked? ------------- PR: https://git.openjdk.org/jdk/pull/12111 From jjg at openjdk.org Fri Jan 20 15:52:57 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Fri, 20 Jan 2023 15:52:57 GMT Subject: RFR: 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc In-Reply-To: References: Message-ID: On Fri, 20 Jan 2023 15:08:39 GMT, Archie L. Cobbs wrote: > The current patch doesn't include a man page update (the bug refers to both Javadoc and man page). > > That's OK but if so then maybe the bug should be split into two as well so the man page part of the issue can be tracked? We should try and do the man page at this time as well. ------------- PR: https://git.openjdk.org/jdk/pull/12111 From asotona at openjdk.org Fri Jan 20 17:12:48 2023 From: asotona at openjdk.org (Adam Sotona) Date: Fri, 20 Jan 2023 17:12:48 GMT Subject: RFR: 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc [v2] In-Reply-To: References: Message-ID: > Hi, > @SuppressWarnings option "lossy-conversions" has been added to JDK 20 (see JDK-8286377), however the option description is missing in jdk.compiler module javadoc and javac man page. > This patch add missing javadoc decription to jdk.compiler module-info.java > > Please review. > > Thanks, > Adam Adam Sotona has updated the pull request incrementally with one additional commit since the last revision: manpage update ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12111/files - new: https://git.openjdk.org/jdk/pull/12111/files/55c78a53..64c9bcc6 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12111&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12111&range=00-01 Stats: 3 lines in 1 file changed: 3 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/12111.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12111/head:pull/12111 PR: https://git.openjdk.org/jdk/pull/12111 From jjg at openjdk.org Fri Jan 20 17:12:49 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Fri, 20 Jan 2023 17:12:49 GMT Subject: RFR: 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc [v2] In-Reply-To: References: Message-ID: On Fri, 20 Jan 2023 17:09:20 GMT, Adam Sotona wrote: >> Hi, >> @SuppressWarnings option "lossy-conversions" has been added to JDK 20 (see JDK-8286377), however the option description is missing in jdk.compiler module javadoc and javac man page. >> This patch add missing javadoc decription to jdk.compiler module-info.java >> >> Please review. >> >> Thanks, >> Adam > > Adam Sotona has updated the pull request incrementally with one additional commit since the last revision: > > manpage update Marked as reviewed by jjg (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12111 From asotona at openjdk.org Fri Jan 20 17:12:50 2023 From: asotona at openjdk.org (Adam Sotona) Date: Fri, 20 Jan 2023 17:12:50 GMT Subject: RFR: 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc In-Reply-To: References: Message-ID: On Fri, 20 Jan 2023 10:59:48 GMT, Adam Sotona wrote: > Hi, > @SuppressWarnings option "lossy-conversions" has been added to JDK 20 (see JDK-8286377), however the option description is missing in jdk.compiler module javadoc and javac man page. > This patch add missing javadoc decription to jdk.compiler module-info.java > > Please review. > > Thanks, > Adam I've included also man page update. ------------- PR: https://git.openjdk.org/jdk/pull/12111 From darcy at openjdk.org Fri Jan 20 18:30:29 2023 From: darcy at openjdk.org (Joe Darcy) Date: Fri, 20 Jan 2023 18:30:29 GMT Subject: RFR: 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc [v2] In-Reply-To: References: Message-ID: On Fri, 20 Jan 2023 17:12:48 GMT, Adam Sotona wrote: >> Hi, >> @SuppressWarnings option "lossy-conversions" has been added to JDK 20 (see JDK-8286377), however the option description is missing in jdk.compiler module javadoc and javac man page. >> This patch add missing javadoc decription to jdk.compiler module-info.java >> >> Please review. >> >> Thanks, >> Adam > > Adam Sotona has updated the pull request incrementally with one additional commit since the last revision: > > manpage update Marked as reviewed by darcy (Reviewer). src/jdk.compiler/share/classes/module-info.java line 165: > 163: * the next > 164: * {@code finally} {@code finally} clauses that do not terminate normally > 165: * {@code lossy-conversions} possible lossy conversions in compound assignment In the table where there is more room to accommodate text, perhaps a longer description mentioning primitive types could be used. ------------- PR: https://git.openjdk.org/jdk/pull/12111 From dholmes at openjdk.org Mon Jan 23 03:24:47 2023 From: dholmes at openjdk.org (David Holmes) Date: Mon, 23 Jan 2023 03:24:47 GMT Subject: [jdk20] RFR: 8290919: Update nroff pages in JDK 20 before RC Message-ID: There was one missing update in javac.1 from: [JDK-8245246](https://bugs.openjdk.org/browse/JDK-8245246): Deprecate -profile option in javac otherwise the change is limited to dropping the "-ea". Thanks. ------------- Commit messages: - Merge branch 'master' into 8290919-manpages - 8290919: Update nroff pages in JDK 20 before RC Changes: https://git.openjdk.org/jdk20/pull/112/files Webrev: https://webrevs.openjdk.org/?repo=jdk20&pr=112&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8290919 Stats: 29 lines in 28 files changed: 1 ins; 0 del; 28 mod Patch: https://git.openjdk.org/jdk20/pull/112.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/112/head:pull/112 PR: https://git.openjdk.org/jdk20/pull/112 From iris at openjdk.org Mon Jan 23 07:18:06 2023 From: iris at openjdk.org (Iris Clark) Date: Mon, 23 Jan 2023 07:18:06 GMT Subject: [jdk20] RFR: 8290919: Update nroff pages in JDK 20 before RC In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 02:59:42 GMT, David Holmes wrote: > There was one missing update in javac.1 from: > > [JDK-8245246](https://bugs.openjdk.org/browse/JDK-8245246): Deprecate -profile option in javac > > otherwise the change is limited to dropping the "-ea". > > Thanks. Marked as reviewed by iris (Reviewer). ------------- PR: https://git.openjdk.org/jdk20/pull/112 From alanb at openjdk.org Mon Jan 23 07:35:07 2023 From: alanb at openjdk.org (Alan Bateman) Date: Mon, 23 Jan 2023 07:35:07 GMT Subject: [jdk20] RFR: 8290919: Update nroff pages in JDK 20 before RC In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 02:59:42 GMT, David Holmes wrote: > There was one missing update in javac.1 from: > > [JDK-8245246](https://bugs.openjdk.org/browse/JDK-8245246): Deprecate -profile option in javac > > otherwise the change is limited to dropping the "-ea". > > Thanks. Marked as reviewed by alanb (Reviewer). ------------- PR: https://git.openjdk.org/jdk20/pull/112 From dholmes at openjdk.org Mon Jan 23 07:39:08 2023 From: dholmes at openjdk.org (David Holmes) Date: Mon, 23 Jan 2023 07:39:08 GMT Subject: [jdk20] RFR: 8290919: Update nroff pages in JDK 20 before RC In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 07:15:08 GMT, Iris Clark wrote: >> There was one missing update in javac.1 from: >> >> [JDK-8245246](https://bugs.openjdk.org/browse/JDK-8245246): Deprecate -profile option in javac >> >> otherwise the change is limited to dropping the "-ea". >> >> Thanks. > > Marked as reviewed by iris (Reviewer). Thanks for the reviews @irisclark and @AlanBateman ! ------------- PR: https://git.openjdk.org/jdk20/pull/112 From dholmes at openjdk.org Mon Jan 23 07:53:05 2023 From: dholmes at openjdk.org (David Holmes) Date: Mon, 23 Jan 2023 07:53:05 GMT Subject: [jdk20] Integrated: 8290919: Update nroff pages in JDK 20 before RC In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 02:59:42 GMT, David Holmes wrote: > There was one missing update in javac.1 from: > > [JDK-8245246](https://bugs.openjdk.org/browse/JDK-8245246): Deprecate -profile option in javac > > otherwise the change is limited to dropping the "-ea". > > Thanks. This pull request has now been integrated. Changeset: fd752178 Author: David Holmes URL: https://git.openjdk.org/jdk20/commit/fd752178e364fb5deeec062bef3dde1fea1dcbe3 Stats: 29 lines in 28 files changed: 1 ins; 0 del; 28 mod 8290919: Update nroff pages in JDK 20 before RC Reviewed-by: iris, alanb ------------- PR: https://git.openjdk.org/jdk20/pull/112 From asotona at openjdk.org Mon Jan 23 08:23:11 2023 From: asotona at openjdk.org (Adam Sotona) Date: Mon, 23 Jan 2023 08:23:11 GMT Subject: Integrated: 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc In-Reply-To: References: Message-ID: On Fri, 20 Jan 2023 10:59:48 GMT, Adam Sotona wrote: > Hi, > @SuppressWarnings option "lossy-conversions" has been added to JDK 20 (see JDK-8286377), however the option description is missing in jdk.compiler module javadoc and javac man page. > This patch add missing javadoc decription to jdk.compiler module-info.java > > Please review. > > Thanks, > Adam This pull request has now been integrated. Changeset: 836198a4 Author: Adam Sotona URL: https://git.openjdk.org/jdk/commit/836198a4009c4a3f10a76dc8734e4792bb2509ba Stats: 4 lines in 2 files changed: 4 ins; 0 del; 0 mod 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc Reviewed-by: jjg, darcy ------------- PR: https://git.openjdk.org/jdk/pull/12111 From jon at spinis-associates.co.uk Mon Jan 23 11:02:22 2023 From: jon at spinis-associates.co.uk (Jon Mann) Date: Mon, 23 Jan 2023 11:02:22 +0000 Subject: Unexpected error compiling generic stream() code in JDK 17 and JDK 19 (but compiles in JDK 8) Message-ID: <1df59a66-aba6-4aff-d04e-3711abf67005@spinis-associates.co.uk> Hello, While updating a large code base I encountered a compilation error in JDK 17 and JDK 19 which does not happen in JDK 8. I eventually managed to reproduce it in the sample code below. JDK 8 compiles the code OK. JDK 17 and JDK 19 both produce the following error: ??? error: getContext() in AbstractSomething cannot implement getContext() in Something ????? return type CAP#1 is not compatible with CAP#2 ????? where Ctx#1,Ctx#2 are type-variables: ??????? Ctx#1 extends Context declared in class AbstractSomething ??????? Ctx#2 extends Context declared in interface Something ????? where CAP#1,CAP#2 are fresh type-variables: ??????? CAP#1 extends Context from capture of ? extends Context ??????? CAP#2 extends Context from capture of ? extends Context ??? 1 error The error does not include any source filenames or line numbers. The error suggests that something is wrong in the AbstractSomething class but the actual cause of the problem seems to be the generics of the stream() code in the getSomethings() method which is not mentioned in the error. JDK 17 and JDK 19 will compile the code after replacing .map(c -> construct(c)) with .map(this::construct) JDK 8 compiles either version of the code. This feels like a regression in the compiler but maybe I am missing something? Thanks, Jon. =========== SAMPLE CODE =========== import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class Test { ??? List getSomethings() { ??????? return Stream.of( ??????????????????????? SomethingA.class, ??????????????????????? SomethingB.class) ??????????????? .map(c -> construct(c)) // UNEXPECTED COMPILER ERROR IN JDK 17+19 (BUT COMPILES IN JDK 8) ??????????????? // .map(this::construct) // COMPILES IN JDK 17+19+8 ??????????????? .collect(Collectors.toList()); ??? } ??? Something construct(Class clazz) { ??????? return null; ??? } ??? interface Context { } ??? interface ContextA extends Context { } ??? interface ContextB extends Context { } ??? interface Something { ??????? Ctx getContext(); ??? } ??? interface SpecificSomething ??????????? extends Something { } ??? abstract static class AbstractSomething ??????????? implements Something { ??????? @Override ??????? public Ctx getContext() { ??????????? return null; ??????? } ??? } ??? static class SomethingA ??????????? extends AbstractSomething ??????????? implements SpecificSomething { } ??? static class SomethingB ??????????? extends AbstractSomething ??????????? implements SpecificSomething { } } From jlahoda at openjdk.org Mon Jan 23 11:33:53 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Mon, 23 Jan 2023 11:33:53 GMT Subject: [jdk20] RFR: 8300623: Lambda deserialization regression involving Enum method reference Message-ID: This patch proposes to revert "8059632: Method reference compilation uses incorrect qualifying type". That fix caused a problem with (de-)serialization: https://bugs.openjdk.org/browse/JDK-8300623 Fixing this deserialization problem does not seem straightforward, so the proposal is to revert JDK-8059632, and investigate more thoroughly for a future release. ------------- Commit messages: - Revert "8059632: Method reference compilation uses incorrect qualifying type" Changes: https://git.openjdk.org/jdk20/pull/113/files Webrev: https://webrevs.openjdk.org/?repo=jdk20&pr=113&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8300623 Stats: 376 lines in 6 files changed: 47 ins; 325 del; 4 mod Patch: https://git.openjdk.org/jdk20/pull/113.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/113/head:pull/113 PR: https://git.openjdk.org/jdk20/pull/113 From mcimadamore at openjdk.org Mon Jan 23 15:21:32 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 23 Jan 2023 15:21:32 GMT Subject: [jdk20] RFR: 8300623: Lambda deserialization regression involving Enum method reference In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 11:12:08 GMT, Jan Lahoda wrote: > This patch proposes to revert "8059632: Method reference compilation uses incorrect qualifying type". That fix caused a problem with (de-)serialization: > https://bugs.openjdk.org/browse/JDK-8300623 > > Fixing this deserialization problem does not seem straightforward, so the proposal is to revert JDK-8059632, and investigate more thoroughly for a future release. Marked as reviewed by mcimadamore (Reviewer). ------------- PR: https://git.openjdk.org/jdk20/pull/113 From vromero at openjdk.org Mon Jan 23 15:58:35 2023 From: vromero at openjdk.org (Vicente Romero) Date: Mon, 23 Jan 2023 15:58:35 GMT Subject: [jdk20] RFR: 8300623: Lambda deserialization regression involving Enum method reference In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 11:12:08 GMT, Jan Lahoda wrote: > This patch proposes to revert "8059632: Method reference compilation uses incorrect qualifying type". That fix caused a problem with (de-)serialization: > https://bugs.openjdk.org/browse/JDK-8300623 > > Fixing this deserialization problem does not seem straightforward, so the proposal is to revert JDK-8059632, and investigate more thoroughly for a future release. Marked as reviewed by vromero (Reviewer). ------------- PR: https://git.openjdk.org/jdk20/pull/113 From vromero at openjdk.org Mon Jan 23 18:48:05 2023 From: vromero at openjdk.org (Vicente Romero) Date: Mon, 23 Jan 2023 18:48:05 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v14] In-Reply-To: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> References: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> Message-ID: On Wed, 18 Jan 2023 22:27:08 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Relax warning to apply only if subclass could exist in another module/package. > - Tweaks to man page. > - Add YieldRef to Javadoc algorithm summary. I'm OK with the last version, @archiecobbs thanks a lot for the patience and continuous effort ------------- Marked as reviewed by vromero (Reviewer). PR: https://git.openjdk.org/jdk/pull/11874 From ihse at openjdk.org Mon Jan 23 18:52:18 2023 From: ihse at openjdk.org (Magnus Ihse Bursie) Date: Mon, 23 Jan 2023 18:52:18 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v14] In-Reply-To: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> References: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> Message-ID: <1q25jQe22r3muIp5sDHBE9yi9LI3o5TIQkUp5VDOzZM=.18d7456d-3c6d-493d-a08e-344413df72fb@github.com> On Wed, 18 Jan 2023 22:27:08 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Relax warning to apply only if subclass could exist in another module/package. > - Tweaks to man page. > - Add YieldRef to Javadoc algorithm summary. Marked as reviewed by ihse (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Mon Jan 23 18:57:16 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 23 Jan 2023 18:57:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v14] In-Reply-To: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> References: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> Message-ID: On Wed, 18 Jan 2023 22:27:08 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Relax warning to apply only if subclass could exist in another module/package. > - Tweaks to man page. > - Add YieldRef to Javadoc algorithm summary. I like the latest version too with improved boundary detection. Moving forward, if we plan to add other complex analyses like this one, we should maybe think to add them as a separate compilation step, rather than adding them in Flow (which might be problematic as parts of Flow are also used as part of Attr. e.g. to infer lambda thrown types). ------------- Marked as reviewed by mcimadamore (Reviewer). PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Mon Jan 23 19:23:06 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 23 Jan 2023 19:23:06 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v14] In-Reply-To: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> References: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> Message-ID: On Wed, 18 Jan 2023 22:27:08 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Relax warning to apply only if subclass could exist in another module/package. > - Tweaks to man page. > - Add YieldRef to Javadoc algorithm summary. Thanks for the careful reviews. > Moving forward, if we plan to add other complex analyses like this one, we should maybe think to add them as a separate compilation step, rather than adding them in Flow (which might be problematic as parts of Flow are also used as part of Attr. e.g. to infer lambda thrown types). Agreed. Perhaps there could be a new phase of compliation `ANALYZE_SOURCE` (?) after `FLOW` where code can assume that all source code is already resolved, validated, attributed, etc. This phase would be the place for read-only tasks like this one, i.e., source-level analyses that generate warnings or perhaps generate some kind of derivative output like a cross-reference file or dependency report. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Mon Jan 23 19:37:34 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 23 Jan 2023 19:37:34 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v14] In-Reply-To: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> References: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> Message-ID: On Wed, 18 Jan 2023 22:27:08 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Relax warning to apply only if subclass could exist in another module/package. > - Tweaks to man page. > - Add YieldRef to Javadoc algorithm summary. [The CSR](https://bugs.openjdk.org/browse/JDK-8299995) also needs a review from a compiler-dev engineer as well if anyone is interested... thanks. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jwilhelm at openjdk.org Mon Jan 23 20:27:19 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Mon, 23 Jan 2023 20:27:19 GMT Subject: RFR: Merge jdk20 Message-ID: Forwardport JDK 20 -> JDK 21 ------------- Commit messages: - Merge - 8290919: Update nroff pages in JDK 20 before RC The webrevs contain the adjustments done while merging with regards to each parent branch: - master: https://webrevs.openjdk.org/?repo=jdk&pr=12150&range=00.0 - jdk20: https://webrevs.openjdk.org/?repo=jdk&pr=12150&range=00.1 Changes: https://git.openjdk.org/jdk/pull/12150/files Stats: 28 lines in 27 files changed: 1 ins; 0 del; 27 mod Patch: https://git.openjdk.org/jdk/pull/12150.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12150/head:pull/12150 PR: https://git.openjdk.org/jdk/pull/12150 From jwilhelm at openjdk.org Mon Jan 23 21:07:12 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Mon, 23 Jan 2023 21:07:12 GMT Subject: Integrated: Merge jdk20 In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 19:52:49 GMT, Jesper Wilhelmsson wrote: > Forwardport JDK 20 -> JDK 21 This pull request has now been integrated. Changeset: 56dc3b08 Author: Jesper Wilhelmsson URL: https://git.openjdk.org/jdk/commit/56dc3b08a62f651835c5bccca987d93ba2bb8961 Stats: 28 lines in 27 files changed: 1 ins; 0 del; 27 mod Merge ------------- PR: https://git.openjdk.org/jdk/pull/12150 From dholmes at openjdk.org Mon Jan 23 23:21:44 2023 From: dholmes at openjdk.org (David Holmes) Date: Mon, 23 Jan 2023 23:21:44 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 Message-ID: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Please review this simple update to the manpage to set the version to 21-ea. This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 Thanks. ------------- Commit messages: - 8290918: Initial nroff manpage generation for JDK 21 Changes: https://git.openjdk.org/jdk/pull/12154/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12154&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8290918 Stats: 28 lines in 27 files changed: 0 ins; 0 del; 28 mod Patch: https://git.openjdk.org/jdk/pull/12154.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12154/head:pull/12154 PR: https://git.openjdk.org/jdk/pull/12154 From lancea at openjdk.org Mon Jan 23 23:27:05 2023 From: lancea at openjdk.org (Lance Andersen) Date: Mon, 23 Jan 2023 23:27:05 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Mon, 23 Jan 2023 22:59:22 GMT, David Holmes wrote: > Please review this simple update to the manpage to set the version to 21-ea. > > This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 > > Thanks. Marked as reviewed by lancea (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12154 From dholmes at openjdk.org Tue Jan 24 00:49:08 2023 From: dholmes at openjdk.org (David Holmes) Date: Tue, 24 Jan 2023 00:49:08 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Mon, 23 Jan 2023 23:24:06 GMT, Lance Andersen wrote: >> Please review this simple update to the manpage to set the version to 21-ea. >> >> This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 >> >> Thanks. > > Marked as reviewed by lancea (Reviewer). Thanks for the review @LanceAndersen ------------- PR: https://git.openjdk.org/jdk/pull/12154 From iris at openjdk.org Tue Jan 24 01:32:03 2023 From: iris at openjdk.org (Iris Clark) Date: Tue, 24 Jan 2023 01:32:03 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Mon, 23 Jan 2023 22:59:22 GMT, David Holmes wrote: > Please review this simple update to the manpage to set the version to 21-ea. > > This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 > > Thanks. Marked as reviewed by iris (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12154 From vromero at openjdk.org Tue Jan 24 03:14:22 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 24 Jan 2023 03:14:22 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v14] In-Reply-To: References: <3BemfnRELENypcLDRYkAbC7_ADmjdyAdq3FI9O7N5no=.c01befda-3422-48b4-a985-79f559b9be6a@github.com> Message-ID: <-5zzJncS-9Lo85VwAiBFRd-8Jcp5zJxpkz5pleWlJas=.0c0cd3a6-c1a6-4263-b5ee-7140edfec2c0@github.com> On Mon, 23 Jan 2023 19:34:42 GMT, Archie L. Cobbs wrote: > [The CSR](https://bugs.openjdk.org/browse/JDK-8299995) also needs a review from a compiler-dev engineer as well if anyone is interested... thanks. some comments on the CSR: - I think the value for field `Compatibility Risk` could be low, instead of medium. Even for code that uses -Xlint:all users will mostly see more warnings, they can change this setting or add @SW annotations to the code if available - The `Implementation` section I think could be moved to a JIRA comment - I think that the `Specification` section has text that probably is describing the solution, to me the specification section should start in this line: `Changes to the module-info.java Javadoc for module jdk.compiler:` ------------- PR: https://git.openjdk.org/jdk/pull/11874 From dholmes at openjdk.org Tue Jan 24 05:42:02 2023 From: dholmes at openjdk.org (David Holmes) Date: Tue, 24 Jan 2023 05:42:02 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Tue, 24 Jan 2023 01:28:53 GMT, Iris Clark wrote: >> Please review this simple update to the manpage to set the version to 21-ea. >> >> This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 >> >> Thanks. > > Marked as reviewed by iris (Reviewer). Thanks for the review @irisclark ! ------------- PR: https://git.openjdk.org/jdk/pull/12154 From darcy at openjdk.org Tue Jan 24 05:46:34 2023 From: darcy at openjdk.org (Joe Darcy) Date: Tue, 24 Jan 2023 05:46:34 GMT Subject: RFR: JDK-8300857: State return value for Types.asElement(NoType) explicitly Message-ID: Just sending out the proposed API changes for now, will add tests later. Please also review the corresponding CSR [JDK-8300951](https://bugs.openjdk.org/browse/JDK-8300951). ------------- Commit messages: - JDK-8300857: State return value for Types.asElement(NoType) explicitly Changes: https://git.openjdk.org/jdk/pull/12159/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12159&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8300857 Stats: 13 lines in 1 file changed: 13 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/12159.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12159/head:pull/12159 PR: https://git.openjdk.org/jdk/pull/12159 From darcy at openjdk.org Tue Jan 24 05:57:04 2023 From: darcy at openjdk.org (Joe Darcy) Date: Tue, 24 Jan 2023 05:57:04 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Mon, 23 Jan 2023 22:59:22 GMT, David Holmes wrote: > Please review this simple update to the manpage to set the version to 21-ea. > > This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 > > Thanks. Marked as reviewed by darcy (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12154 From dholmes at openjdk.org Tue Jan 24 06:31:11 2023 From: dholmes at openjdk.org (David Holmes) Date: Tue, 24 Jan 2023 06:31:11 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Tue, 24 Jan 2023 05:54:44 GMT, Joe Darcy wrote: >> Please review this simple update to the manpage to set the version to 21-ea. >> >> This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 >> >> Thanks. > > Marked as reviewed by darcy (Reviewer). Thanks for the review @jddarcy ! I think that suffices for this trivial change. ------------- PR: https://git.openjdk.org/jdk/pull/12154 From dholmes at openjdk.org Tue Jan 24 06:31:13 2023 From: dholmes at openjdk.org (David Holmes) Date: Tue, 24 Jan 2023 06:31:13 GMT Subject: Integrated: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Mon, 23 Jan 2023 22:59:22 GMT, David Holmes wrote: > Please review this simple update to the manpage to set the version to 21-ea. > > This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 > > Thanks. This pull request has now been integrated. Changeset: 6dd8723f Author: David Holmes URL: https://git.openjdk.org/jdk/commit/6dd8723f66a22e626d98c74cff0b0b344a62626d Stats: 28 lines in 27 files changed: 0 ins; 0 del; 28 mod 8290918: Initial nroff manpage generation for JDK 21 Reviewed-by: lancea, iris, darcy ------------- PR: https://git.openjdk.org/jdk/pull/12154 From jlahoda at openjdk.org Tue Jan 24 06:43:13 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Tue, 24 Jan 2023 06:43:13 GMT Subject: [jdk20] Integrated: 8300623: Lambda deserialization regression involving Enum method reference In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 11:12:08 GMT, Jan Lahoda wrote: > This patch proposes to revert "8059632: Method reference compilation uses incorrect qualifying type". That fix caused a problem with (de-)serialization: > https://bugs.openjdk.org/browse/JDK-8300623 > > Fixing this deserialization problem does not seem straightforward, so the proposal is to revert JDK-8059632, and investigate more thoroughly for a future release. This pull request has now been integrated. Changeset: a3ed7e94 Author: Jan Lahoda URL: https://git.openjdk.org/jdk20/commit/a3ed7e94a23c0c89138d831f4b36b26dce5b3d01 Stats: 376 lines in 6 files changed: 47 ins; 325 del; 4 mod 8300623: Lambda deserialization regression involving Enum method reference Reviewed-by: mcimadamore, vromero ------------- PR: https://git.openjdk.org/jdk20/pull/113 From prappo at openjdk.org Tue Jan 24 10:25:05 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Tue, 24 Jan 2023 10:25:05 GMT Subject: RFR: JDK-8300857: State return value for Types.asElement(NoType) explicitly In-Reply-To: References: Message-ID: On Tue, 24 Jan 2023 05:38:36 GMT, Joe Darcy wrote: > Just sending out the proposed API changes for now, will add tests later. > > Please also review the corresponding CSR [JDK-8300951](https://bugs.openjdk.org/browse/JDK-8300951). Thanks for doing this. It looks good. However, I'll leave it to compiler experts to formally approve the PR and review the CSR. src/java.compiler/share/classes/javax/lang/model/util/Types.java line 58: > 56: *

  • {@linkplain TypeKind#MODULE module pseudo-types} > 57: *
  • {@linkplain TypeKind#NONE "none" pseudo-types} > 58: *
  • {@linkplain TypeKind#NULL null types} Was that extra whitespace between NULL and null intended? ------------- PR: https://git.openjdk.org/jdk/pull/12159 From asotona at openjdk.org Tue Jan 24 13:20:05 2023 From: asotona at openjdk.org (Adam Sotona) Date: Tue, 24 Jan 2023 13:20:05 GMT Subject: [jdk20] Integrated: 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc Message-ID: Reviewed-by: jjg, darcy Backport-of: 836198a4009c4a3f10a76dc8734e4792bb2509ba ------------- Commit messages: - 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc Changes: https://git.openjdk.org/jdk20/pull/114/files Webrev: https://webrevs.openjdk.org/?repo=jdk20&pr=114&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8300591 Stats: 4 lines in 2 files changed: 4 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk20/pull/114.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/114/head:pull/114 PR: https://git.openjdk.org/jdk20/pull/114 From asotona at openjdk.org Tue Jan 24 13:20:06 2023 From: asotona at openjdk.org (Adam Sotona) Date: Tue, 24 Jan 2023 13:20:06 GMT Subject: [jdk20] Integrated: 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc In-Reply-To: References: Message-ID: On Tue, 24 Jan 2023 13:07:30 GMT, Adam Sotona wrote: > Reviewed-by: jjg, darcy > Backport-of: 836198a4009c4a3f10a76dc8734e4792bb2509ba This pull request has now been integrated. Changeset: 60b8a985 Author: Adam Sotona URL: https://git.openjdk.org/jdk20/commit/60b8a98501c6aafa47827b2f05c354c461cfe75c Stats: 4 lines in 2 files changed: 4 ins; 0 del; 0 mod 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc Backport-of: 836198a4009c4a3f10a76dc8734e4792bb2509ba ------------- PR: https://git.openjdk.org/jdk20/pull/114 From dnguyen at openjdk.org Tue Jan 24 20:57:43 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 20:57:43 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update Message-ID: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. All tests passed ------------- Commit messages: - Remove currency symbol entries - Remove whitespace using tool - Remove double quotes generated by translation tool - Revert translation's removal of text - Update files for localization Changes: https://git.openjdk.org/jdk20/pull/116/files Webrev: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8300719 Stats: 1030 lines in 81 files changed: 218 ins; 115 del; 697 mod Patch: https://git.openjdk.org/jdk20/pull/116.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/116/head:pull/116 PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Tue Jan 24 21:08:11 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 21:08:11 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: <4tI9y6FpAFrOiS4N4joygZHAHvPm-Ka2D9_3F8pyD6o=.fbb62ba6-4658-46b5-96f8-307ab3b41f81@github.com> On Tue, 24 Jan 2023 20:50:00 GMT, Damon Nguyen wrote: > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed @prrace @wangweij @naotoj @JoeWang-Java @plummercj @alexeysemenyukoracle Could you review the changes from this localization drop? ------------- PR: https://git.openjdk.org/jdk20/pull/116 From jjg at openjdk.org Tue Jan 24 21:43:04 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Tue, 24 Jan 2023 21:43:04 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet [v3] In-Reply-To: References: Message-ID: > Support for Markdown comments in the standard doclet. > > To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. > > The work is in 3 parts: > > 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. > 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. > 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. > > There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. Jonathan Gibbons has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains eight commits: - Merge with upstream/master - Update copyright years - Rename FFFC variable Share Markdown parser and renderer in instance of MarkdownHandler - Move CommonMark to new internal module. Add legal header to imported CommonMark source files Always use Text nodes inside AttributeTree values Unwrap

    from "simple" paragraphs - Always use Text nodes inside AttributeTree values - Update to CommonMark 0.21. - fix whitespace - JDK-8298405: Markdown support in the standard doclet ------------- Changes: https://git.openjdk.org/jdk/pull/11701/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11701&range=02 Stats: 15635 lines in 145 files changed: 15343 ins; 97 del; 195 mod Patch: https://git.openjdk.org/jdk/pull/11701.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11701/head:pull/11701 PR: https://git.openjdk.org/jdk/pull/11701 From jwilhelm at openjdk.org Tue Jan 24 21:46:12 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Tue, 24 Jan 2023 21:46:12 GMT Subject: RFR: Merge jdk20 Message-ID: Forwardport JDK 20 -> JDK 21 ------------- Commit messages: - Merge - 8300591: @SuppressWarnings option "lossy-conversions" missing from jdk.compiler module javadoc - 8300623: Lambda deserialization regression involving Enum method reference The merge commit only contains trivial merges, so no merge-specific webrevs have been generated. Changes: https://git.openjdk.org/jdk/pull/12172/files Stats: 376 lines in 6 files changed: 47 ins; 325 del; 4 mod Patch: https://git.openjdk.org/jdk/pull/12172.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12172/head:pull/12172 PR: https://git.openjdk.org/jdk/pull/12172 From dnguyen at openjdk.org Tue Jan 24 21:48:11 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 21:48:11 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 20:50:00 GMT, Damon Nguyen wrote: > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed @magicus @LanceAndersen @jonathan-gibbons @pavelrappo @dougxc @lahodaj Could you review the changes from this localization drop for the areas you're familiar with? ------------- PR: https://git.openjdk.org/jdk20/pull/116 From cjplummer at openjdk.org Tue Jan 24 22:05:10 2023 From: cjplummer at openjdk.org (Chris Plummer) Date: Tue, 24 Jan 2023 22:05:10 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 20:50:00 GMT, Damon Nguyen wrote: > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed jdk.console and jdk.management.agent changes look good. ------------- Marked as reviewed by cjplummer (Reviewer). PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Tue Jan 24 22:12:26 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 22:12:26 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v2] In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: Change German help of jar command ------------- Changes: - all: https://git.openjdk.org/jdk20/pull/116/files - new: https://git.openjdk.org/jdk20/pull/116/files/4ced04fb..a2528015 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=00-01 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk20/pull/116.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/116/head:pull/116 PR: https://git.openjdk.org/jdk20/pull/116 From naoto at openjdk.org Tue Jan 24 22:24:15 2023 From: naoto at openjdk.org (Naoto Sato) Date: Tue, 24 Jan 2023 22:24:15 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v2] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:12:26 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Change German help of jar command Changes requested by naoto (Reviewer). src/jdk.jconsole/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties line 174: > 172: MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON=\u53D6\u6D88\u8BA2\u9605(&U) > 173: MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=\u505C\u6B62\u76D1\u542C\u901A\u77E5 > 174: MANAGE_HOTSPOT_MBEANS_IN_COLON_=\u7BA1\u7406\u4EE5\u4E0B\u4F4D\u7F6E\u7684 HotSpot MBean: This looks like a prefix, so instead of removing the space, it should be replaced with `\u0020` like other locations. Also, it seems that other l10n files (de, ja) do not seem to have spaces in the first place. src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_de.properties line 38: > 36: resource.post-msi-script=Auszuf\u00FChrendes Skript nach dem Erstellen der MSI-Datei f\u00FCr das EXE-Installationsprogramm > 37: resource.wxl-file=WiX-Lokalisierungsdatei > 38: resource.wxl-file-name=MsiInstallerStrings_en.wxl Shouldn't this be `de`? src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties line 38: > 36: resource.post-msi-script=exe\u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\u306Emsi\u30D5\u30A1\u30A4\u30EB\u304C\u4F5C\u6210\u3055\u308C\u305F\u5F8C\u306B\u5B9F\u884C\u3059\u308B\u30B9\u30AF\u30EA\u30D7\u30C8 > 37: resource.wxl-file=WiX\u30ED\u30FC\u30AB\u30EA\u30BC\u30FC\u30B7\u30E7\u30F3\u30FB\u30D5\u30A1\u30A4\u30EB > 38: resource.wxl-file-name=MsiInstallerStrings_en.wxl Shouldn't this be `ja`? src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties line 38: > 36: resource.post-msi-script=\u5728\u4E3A exe \u5B89\u88C5\u7A0B\u5E8F\u521B\u5EFA msi \u6587\u4EF6\u4E4B\u540E\u8981\u8FD0\u884C\u7684\u811A\u672C > 37: resource.wxl-file=WiX \u672C\u5730\u5316\u6587\u4EF6 > 38: resource.wxl-file-name=MsiInstallerStrings_en.wxl Shouldn't this be `zh_CN`? src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_zh_CN.properties line 63: > 61: # written authorization of the copyright holder. > 62: > 63: CNY=\uffe5 Do not remove this. ------------- PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Tue Jan 24 22:24:16 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 22:24:16 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v2] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:05:55 GMT, Naoto Sato wrote: >> Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: >> >> Change German help of jar command > > src/jdk.jconsole/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties line 174: > >> 172: MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON=\u53D6\u6D88\u8BA2\u9605(&U) >> 173: MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=\u505C\u6B62\u76D1\u542C\u901A\u77E5 >> 174: MANAGE_HOTSPOT_MBEANS_IN_COLON_=\u7BA1\u7406\u4EE5\u4E0B\u4F4D\u7F6E\u7684 HotSpot MBean: > > This looks like a prefix, so instead of removing the space, it should be replaced with `\u0020` like other locations. > Also, it seems that other l10n files (de, ja) do not seem to have spaces in the first place. OK, I can make the manual edit for this > src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties line 38: > >> 36: resource.post-msi-script=\u5728\u4E3A exe \u5B89\u88C5\u7A0B\u5E8F\u521B\u5EFA msi \u6587\u4EF6\u4E4B\u540E\u8981\u8FD0\u884C\u7684\u811A\u672C >> 37: resource.wxl-file=WiX \u672C\u5730\u5316\u6587\u4EF6 >> 38: resource.wxl-file-name=MsiInstallerStrings_en.wxl > > Shouldn't this be `zh_CN`? The translation tool seems to use the English source file's file name here, so it's replaced. I will handle these 3 occurrences now. I thought I handled all occurrences of this, but these 3 slipped in ------------- PR: https://git.openjdk.org/jdk20/pull/116 From jwilhelm at openjdk.org Tue Jan 24 22:31:11 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Tue, 24 Jan 2023 22:31:11 GMT Subject: Integrated: Merge jdk20 In-Reply-To: References: Message-ID: On Tue, 24 Jan 2023 21:38:18 GMT, Jesper Wilhelmsson wrote: > Forwardport JDK 20 -> JDK 21 This pull request has now been integrated. Changeset: 81d523d3 Author: Jesper Wilhelmsson URL: https://git.openjdk.org/jdk/commit/81d523d382331a06ec57b302890ccd4d25fdd095 Stats: 376 lines in 6 files changed: 47 ins; 325 del; 4 mod Merge ------------- PR: https://git.openjdk.org/jdk/pull/12172 From dnguyen at openjdk.org Tue Jan 24 22:33:24 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 22:33:24 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v3] In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: Change localization codes. Add CNY back ------------- Changes: - all: https://git.openjdk.org/jdk20/pull/116/files - new: https://git.openjdk.org/jdk20/pull/116/files/a2528015..40291c61 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=01-02 Stats: 4 lines in 4 files changed: 1 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jdk20/pull/116.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/116/head:pull/116 PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Tue Jan 24 22:33:28 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 22:33:28 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v2] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:12:02 GMT, Naoto Sato wrote: >> Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: >> >> Change German help of jar command > > src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_de.properties line 38: > >> 36: resource.post-msi-script=Auszuf\u00FChrendes Skript nach dem Erstellen der MSI-Datei f\u00FCr das EXE-Installationsprogramm >> 37: resource.wxl-file=WiX-Lokalisierungsdatei >> 38: resource.wxl-file-name=MsiInstallerStrings_en.wxl > > Shouldn't this be `de`? Changed back similar to with zh_CN > src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties line 38: > >> 36: resource.post-msi-script=exe\u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\u306Emsi\u30D5\u30A1\u30A4\u30EB\u304C\u4F5C\u6210\u3055\u308C\u305F\u5F8C\u306B\u5B9F\u884C\u3059\u308B\u30B9\u30AF\u30EA\u30D7\u30C8 >> 37: resource.wxl-file=WiX\u30ED\u30FC\u30AB\u30EA\u30BC\u30FC\u30B7\u30E7\u30F3\u30FB\u30D5\u30A1\u30A4\u30EB >> 38: resource.wxl-file-name=MsiInstallerStrings_en.wxl > > Shouldn't this be `ja`? Changed back similar to with zh_CN ------------- PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Tue Jan 24 22:33:29 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 22:33:29 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v3] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:14:36 GMT, Naoto Sato wrote: >> Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: >> >> Change localization codes. Add CNY back > > src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_zh_CN.properties line 63: > >> 61: # written authorization of the copyright holder. >> 62: >> 63: CNY=\uffe5 > > Do not remove this. Added back. Thanks for catching this! ------------- PR: https://git.openjdk.org/jdk20/pull/116 From prr at openjdk.org Tue Jan 24 22:44:13 2023 From: prr at openjdk.org (Phil Race) Date: Tue, 24 Jan 2023 22:44:13 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v2] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:12:26 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Change German help of jar command Removing the trailing white space seems OK in the desktop resources. I checked the base (English) version of the files and none of them have trailing white space so it seems unlikely it is significant. ------------- Marked as reviewed by prr (Reviewer). PR: https://git.openjdk.org/jdk20/pull/116 From jlu at openjdk.org Tue Jan 24 22:44:14 2023 From: jlu at openjdk.org (Justin Lu) Date: Tue, 24 Jan 2023 22:44:14 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v3] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:20:22 GMT, Damon Nguyen wrote: >> src/jdk.jconsole/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties line 174: >> >>> 172: MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON=\u53D6\u6D88\u8BA2\u9605(&U) >>> 173: MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=\u505C\u6B62\u76D1\u542C\u901A\u77E5 >>> 174: MANAGE_HOTSPOT_MBEANS_IN_COLON_=\u7BA1\u7406\u4EE5\u4E0B\u4F4D\u7F6E\u7684 HotSpot MBean: >> >> This looks like a prefix, so instead of removing the space, it should be replaced with `\u0020` like other locations. >> Also, it seems that other l10n files (de, ja) do not seem to have spaces in the first place. > > OK, I can make the manual edit for this This change was made because it was compared to the original messages.properties. In that file, the respective line is given as `MANAGE_HOTSPOT_MBEANS_IN_COLON_=Manage Hotspot MBeans in:` with no trailing space. That's why in this file, to ensure consistency, the trailing space was stripped. I think either this space should be removed, or all 4 (en, ja, de, zh) should have the `\u0020` appended. I agree that since it is a prefix it would make sense for a space to be there, but there is no guarantee that what comes after, or even the code that loads the .properties file does not already handles that necessary space. Should the space remain removed like in the English source file and the other l10n files, or do you think all 4 should be changed to add `\u0020`? ------------- PR: https://git.openjdk.org/jdk20/pull/116 From darcy at openjdk.org Tue Jan 24 22:51:10 2023 From: darcy at openjdk.org (Joe Darcy) Date: Tue, 24 Jan 2023 22:51:10 GMT Subject: RFR: JDK-8300857: State return value for Types.asElement(NoType) explicitly In-Reply-To: References: Message-ID: On Tue, 24 Jan 2023 05:38:36 GMT, Joe Darcy wrote: > Just sending out the proposed API changes for now, will add tests later. > > Please also review the corresponding CSR [JDK-8300951](https://bugs.openjdk.org/browse/JDK-8300951). PS I purposely did not provide an explicit specification on how a TypeMirror with a kind of OTHER or ERROR might be handled here to preserve implementation flexibility. As an aside, if we had more time for the original JSR 269 effort, we would likely have worked so that there was a PrimitiveElement enum to host the element form of the built-in primitive types, but we ran out of time do to that work. That would have allowed a fuller round-trip relation of element.asType().asElement() returning something equal to the initial value. ------------- PR: https://git.openjdk.org/jdk/pull/12159 From joehw at openjdk.org Tue Jan 24 22:59:07 2023 From: joehw at openjdk.org (Joe Wang) Date: Tue, 24 Jan 2023 22:59:07 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v3] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: <8IAAljdZ35sxC22s2SeFdCTX5xmx83YUFr8dwOYtXzA=.028e67c7-0969-4204-b843-0c0f2d79574f@github.com> On Tue, 24 Jan 2023 22:33:24 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Change localization codes. Add CNY back Marked as reviewed by joehw (Reviewer). java.xml changes look good to me. Thanks. ------------- PR: https://git.openjdk.org/jdk20/pull/116 From naoto at openjdk.org Tue Jan 24 22:59:08 2023 From: naoto at openjdk.org (Naoto Sato) Date: Tue, 24 Jan 2023 22:59:08 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v3] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:40:55 GMT, Justin Lu wrote: >> OK, I can make the manual edit for this > > This change was made because it was compared to the original messages.properties. In that file, the respective line is given as `MANAGE_HOTSPOT_MBEANS_IN_COLON_=Manage Hotspot MBeans in:` with no trailing space. That's why in this file, to ensure consistency, the trailing space was stripped. > > I think either this space should be removed, or all 4 (en, ja, de, zh) should have the `\u0020` appended. I agree that since it is a prefix it would make sense for a space to be there, but there is no guarantee that what comes after, or even the code that loads the .properties file does not already handles that necessary space. > > Should the space remain removed like in the English source file and the other l10n files, or do you think all 4 should be changed to add `\u0020`? Confirmed that the message is for a label (`sun.tools.jconsole.LabeledComponent`), followed by a Component, so no space seems needed in each file. Sorry for the false alarm. ------------- PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Tue Jan 24 22:59:08 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 22:59:08 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v3] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:49:20 GMT, Naoto Sato wrote: >> This change was made because it was compared to the original messages.properties. In that file, the respective line is given as `MANAGE_HOTSPOT_MBEANS_IN_COLON_=Manage Hotspot MBeans in:` with no trailing space. That's why in this file, to ensure consistency, the trailing space was stripped. >> >> I think either this space should be removed, or all 4 (en, ja, de, zh) should have the `\u0020` appended. I agree that since it is a prefix it would make sense for a space to be there, but there is no guarantee that what comes after, or even the code that loads the .properties file does not already handles that necessary space. >> >> Should the space remain removed like in the English source file and the other l10n files, or do you think all 4 should be changed to add `\u0020`? > > Confirmed that the message is for a label (`sun.tools.jconsole.LabeledComponent`), followed by a Component, so no space seems needed in each file. Sorry for the false alarm. Ok I left this change out of my most recent update just in case. I addressed all the other comments I believe. Thanks! ------------- PR: https://git.openjdk.org/jdk20/pull/116 From asemenyuk at openjdk.org Tue Jan 24 22:59:12 2023 From: asemenyuk at openjdk.org (Alexey Semenyuk) Date: Tue, 24 Jan 2023 22:59:12 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v3] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:33:24 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Change localization codes. Add CNY back src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_de.wxl line 2: > 1: > 2: Please revert the value of the `Culture` attribute. src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_ja.wxl line 2: > 1: > 2: Please revert the value of the `Culture` attribute. src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_zh_CN.wxl line 2: > 1: > 2: Please revert the value of the `Culture` attribute. ------------- PR: https://git.openjdk.org/jdk20/pull/116 From jlu at openjdk.org Tue Jan 24 23:06:14 2023 From: jlu at openjdk.org (Justin Lu) Date: Tue, 24 Jan 2023 23:06:14 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v3] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:33:24 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Change localization codes. Add CNY back src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_ja.properties line 62: > 60: dedup-legal-notices.usage=\ --dedup-legal-notices [error-if-not-same-content]\n \u3059\u3079\u3066\u306E\u6CD5\u5F8B\u4E0A\u306E\u6CE8\u610F\u70B9\u306E\u91CD\u8907\u3092\u9664\u5916\u3057\u307E\u3059\u3002\n error-if-not-same-content\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\n \u540C\u3058\u30D5\u30A1\u30A4\u30EB\u540D\u306E2\u3064\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u7570\u306A\u3063\u3066\u3044\u308B\u3068\n \u30A8\u30E9\u30FC\u306B\u306A\u308A\u307E\u3059\u3002 > 61: > 62: exclude-files.argument=\u9664\u5916\u3059\u308B\u30D5\u30A1\u30A4\u30EB\u306E It seems like the translation process added a space here, but it does not appear in the original. This should be removed. src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_zh_CN.properties line 194: > 192: main.plugin.module=\u63D2\u4EF6\u6A21\u5757 > 193: > 194: main.plugin.category=\u7C7B\u522B Same as above. ------------- PR: https://git.openjdk.org/jdk20/pull/116 From asemenyuk at openjdk.org Tue Jan 24 23:19:12 2023 From: asemenyuk at openjdk.org (Alexey Semenyuk) Date: Tue, 24 Jan 2023 23:19:12 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v3] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: <53tinlttCmtNrOBaz7F54bKSeftrurnsr9OVoQzzjC8=.191b9195-e775-4b4b-8811-d34789cec36e@github.com> On Tue, 24 Jan 2023 22:33:24 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Change localization codes. Add CNY back Changes requested by asemenyuk (Reviewer). src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_zh_CN.wxl line 2: > 1: > 2: Please revert the value of the Culture attribute. ------------- PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Tue Jan 24 23:38:23 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 23:38:23 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v4] In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: Remove trailing whitespace ------------- Changes: - all: https://git.openjdk.org/jdk20/pull/116/files - new: https://git.openjdk.org/jdk20/pull/116/files/40291c61..fc32c37f Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=02-03 Stats: 2 lines in 2 files changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk20/pull/116.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/116/head:pull/116 PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Tue Jan 24 23:56:23 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 23:56:23 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: Revert culture attribute ------------- Changes: - all: https://git.openjdk.org/jdk20/pull/116/files - new: https://git.openjdk.org/jdk20/pull/116/files/fc32c37f..616b2502 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=03-04 Stats: 3 lines in 3 files changed: 0 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jdk20/pull/116.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/116/head:pull/116 PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Tue Jan 24 23:59:13 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 23:59:13 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v3] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 23:02:58 GMT, Justin Lu wrote: >> Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: >> >> Change localization codes. Add CNY back > > src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_ja.properties line 62: > >> 60: dedup-legal-notices.usage=\ --dedup-legal-notices [error-if-not-same-content]\n \u3059\u3079\u3066\u306E\u6CD5\u5F8B\u4E0A\u306E\u6CE8\u610F\u70B9\u306E\u91CD\u8907\u3092\u9664\u5916\u3057\u307E\u3059\u3002\n error-if-not-same-content\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\n \u540C\u3058\u30D5\u30A1\u30A4\u30EB\u540D\u306E2\u3064\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u7570\u306A\u3063\u3066\u3044\u308B\u3068\n \u30A8\u30E9\u30FC\u306B\u306A\u308A\u307E\u3059\u3002 >> 61: >> 62: exclude-files.argument=\u9664\u5916\u3059\u308B\u30D5\u30A1\u30A4\u30EB\u306E > > It seems like the translation process added a space here, but it does not appear in the original. This should be removed. Removed both instances of the extra trailing whitespace. > src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_zh_CN.properties line 194: > >> 192: main.plugin.module=\u63D2\u4EF6\u6A21\u5757 >> 193: >> 194: main.plugin.category=\u7C7B\u522B > > Same as above. Addressed as above ------------- PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Tue Jan 24 23:59:17 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 23:59:17 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v2] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:55:43 GMT, Alexey Semenyuk wrote: >> Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: >> >> Change German help of jar command > > src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_de.wxl line 2: > >> 1: >> 2: > > Please revert the value of the `Culture` attribute. I resolved this for the German, Japanese, and Chinese files in the latest commit. > src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_ja.wxl line 2: > >> 1: >> 2: > > Please revert the value of the `Culture` attribute. Resolved in recent commit ------------- PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Tue Jan 24 23:59:19 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Tue, 24 Jan 2023 23:59:19 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v3] In-Reply-To: <53tinlttCmtNrOBaz7F54bKSeftrurnsr9OVoQzzjC8=.191b9195-e775-4b4b-8811-d34789cec36e@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> <53tinlttCmtNrOBaz7F54bKSeftrurnsr9OVoQzzjC8=.191b9195-e775-4b4b-8811-d34789cec36e@github.com> Message-ID: On Tue, 24 Jan 2023 23:16:02 GMT, Alexey Semenyuk wrote: >> Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: >> >> Change localization codes. Add CNY back > > src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_zh_CN.wxl line 2: > >> 1: >> 2: > > Please revert the value of the Culture attribute. Resolved in recent commit ------------- PR: https://git.openjdk.org/jdk20/pull/116 From asemenyuk at openjdk.org Wed Jan 25 00:12:09 2023 From: asemenyuk at openjdk.org (Alexey Semenyuk) Date: Wed, 25 Jan 2023 00:12:09 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 23:56:23 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Revert culture attribute jpackage changes look good ------------- Marked as reviewed by asemenyuk (Reviewer). PR: https://git.openjdk.org/jdk20/pull/116 From jlu at openjdk.org Wed Jan 25 01:11:15 2023 From: jlu at openjdk.org (Justin Lu) Date: Wed, 25 Jan 2023 01:11:15 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 23:56:23 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Revert culture attribute Marked as reviewed by jlu (Author). ------------- PR: https://git.openjdk.org/jdk20/pull/116 From darcy at openjdk.org Wed Jan 25 03:56:30 2023 From: darcy at openjdk.org (Joe Darcy) Date: Wed, 25 Jan 2023 03:56:30 GMT Subject: RFR: JDK-8300857: State return value for Types.asElement(NoType) explicitly [v2] In-Reply-To: References: Message-ID: > Just sending out the proposed API changes for now, will add tests later. > > Please also review the corresponding CSR [JDK-8300951](https://bugs.openjdk.org/browse/JDK-8300951). Joe Darcy has updated the pull request incrementally with two additional commits since the last revision: - Applease jcheck. - Refine spec, add regression test. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12159/files - new: https://git.openjdk.org/jdk/pull/12159/files/2defd826..a60301ce Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12159&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12159&range=00-01 Stats: 109 lines in 3 files changed: 103 ins; 3 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/12159.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12159/head:pull/12159 PR: https://git.openjdk.org/jdk/pull/12159 From darcy at openjdk.org Wed Jan 25 03:59:04 2023 From: darcy at openjdk.org (Joe Darcy) Date: Wed, 25 Jan 2023 03:59:04 GMT Subject: RFR: JDK-8300857: State return value for Types.asElement(NoType) explicitly In-Reply-To: References: Message-ID: On Tue, 24 Jan 2023 05:38:36 GMT, Joe Darcy wrote: > Just sending out the proposed API changes for now, will add tests later. > > Please also review the corresponding CSR [JDK-8300951](https://bugs.openjdk.org/browse/JDK-8300951). Quick discussion of the revised version of the patch: * After looking at the javac implementation, I added spec and implementation support for the type mirrors of packages and modules returning the element for the package or module. This was a very small addendum to add support and allows round-tripping in more cases. * Neither union types nor intersection types are in the explicitly mapped or explicitly not mapped lists. This types are generally returned from trees and elements modeling the inside of method bodies rather than the declaration-level structures in the standardized API. The remaining explicitly listed types-without-elements are straightforward to generate via the standard APIs. ------------- PR: https://git.openjdk.org/jdk/pull/12159 From duke at openjdk.org Wed Jan 25 08:20:13 2023 From: duke at openjdk.org (danielpeintner) Date: Wed, 25 Jan 2023 08:20:13 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v2] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 22:12:26 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Change German help of jar command src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_de.properties line 111: > 109: main.help.opt.main.update=\ -u, --update Ein vorhandenes JAR-Archiv aktualisieren > 110: main.help.opt.main.extract=\ -x, --extract Benannte (oder alle) Dateien aus dem Archiv extrahieren > 111: main.help.opt.main.describe-module=\ -d, --describe-module Gibt den Moduldeskriptor oder automatischen Modulnamen aus Just because I stumbled over this commit. I think the line should be translated as follows: `Gibt die Modulbeschreibung oder den automatischen Modulnamen aus` ------------- PR: https://git.openjdk.org/jdk20/pull/116 From amaembo at gmail.com Wed Jan 25 13:10:57 2023 From: amaembo at gmail.com (Tagir Valeev) Date: Wed, 25 Jan 2023 14:10:57 +0100 Subject: Unchecked conversion spec In-Reply-To: References: Message-ID: Hello! Could anyone please look into this? Thanks! On Mon, Jan 16, 2023 at 5:17 PM Tagir Valeev wrote: > > Hello! > > I have trouble understanding the unchecked conversion section of JLS > (5.1.6.2)[1]. > I have the following code: > > import java.util.function.Supplier; > > public class Test { > static class Box implements Supplier { > @Override > public T get() { > return null; > } > } > > > void typeArg(S s) { > Box b = (Box) s; > } > } > > javac with -Xlint:all compiles it without unchecked warning (tried > various versions from JDK 11 to JDK 20ea, the behavior is the same). > The spec says: > > The unchecked narrowing reference conversions are as follows: > > A narrowing reference conversion from a type S to a parameterized > class or interface type T is unchecked, unless at least one of the > following is true: > - All of the type arguments of T are unbounded wildcards. > - T <: S, and S has no subtype X other than T where the type arguments > of X are not contained in the type arguments of T. > > In my example, T = Box and S = S. To my understanding, "All of > the type arguments of T are unbounded wildcards." is false ( > is bounded), and Box is not a subtype of S, so "T <: S" is > wrong. This means that this conversion should be unchecked and a > warning should be issued. > > I feel that javac behavior is correct. Probably I don't understand the > spec correctly. Could you please help me with this? > > Thank you in advance, > Tagir Valeev. > > [1] https://docs.oracle.com/javase/specs/jls/se19/html/jls-5.html#jls-5.1.6.2 From lancea at openjdk.org Wed Jan 25 13:45:21 2023 From: lancea at openjdk.org (Lance Andersen) Date: Wed, 25 Jan 2023 13:45:21 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 23:56:23 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Revert culture attribute Marked as reviewed by lancea (Reviewer). ------------- PR: https://git.openjdk.org/jdk20/pull/116 From ihse at openjdk.org Wed Jan 25 13:56:21 2023 From: ihse at openjdk.org (Magnus Ihse Bursie) Date: Wed, 25 Jan 2023 13:56:21 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: <-Mjbn1ko2InJOzXLccieEzU8h4bypdm9vTzHdmtA-JQ=.2e1f4d59-e30e-434a-8e62-25777adb3a07@github.com> On Tue, 24 Jan 2023 23:56:23 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Revert culture attribute I skimmed through this, basically looking for trailing white space changes only, and it generally looks okay. Note that some of these trailing whitespace fixes has been independently address in mainline. Forward-porting this might involve some (virtual) conflicts. It is also impossible to see in the Github interface if you are introducing *new* trailing white spaces in the added texts. I hope you are not, and that you have verified this. ------------- Marked as reviewed by ihse (Reviewer). PR: https://git.openjdk.org/jdk20/pull/116 From abimpoudis at openjdk.org Wed Jan 25 15:21:03 2023 From: abimpoudis at openjdk.org (Aggelos Biboudis) Date: Wed, 25 Jan 2023 15:21:03 GMT Subject: RFR: 8301025: ClassCastException in switch with generic record Message-ID: Add missing class bound propagation during pattern matching translation. ------------- Commit messages: - 8301025: ClassCastException in switch with generic record Changes: https://git.openjdk.org/jdk/pull/12200/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12200&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8301025 Stats: 46 lines in 2 files changed: 45 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/12200.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12200/head:pull/12200 PR: https://git.openjdk.org/jdk/pull/12200 From naoto at openjdk.org Wed Jan 25 16:55:04 2023 From: naoto at openjdk.org (Naoto Sato) Date: Wed, 25 Jan 2023 16:55:04 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 23:56:23 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Revert culture attribute LGTM ------------- Marked as reviewed by naoto (Reviewer). PR: https://git.openjdk.org/jdk20/pull/116 From weijun at openjdk.org Wed Jan 25 17:36:38 2023 From: weijun at openjdk.org (Weijun Wang) Date: Wed, 25 Jan 2023 17:36:38 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: <_THK1t7SrTRqoW0o0gfgmCo1Ea1WfgdfeB7jNJDKUKk=.05512373-8cb2-41d3-a71f-589075240bb7@github.com> On Tue, 24 Jan 2023 23:56:23 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Revert culture attribute src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties line 32: > 30: err.bad.constant.pool=\u8BFB\u53D6{0}\u7684\u5E38\u91CF\u6C60\u65F6\u51FA\u9519: {1} > 31: err.class.not.found=\u627E\u4E0D\u5230\u7C7B: {0} > 32: err.crash=\u51FA\u73B0\u4E25\u91CD\u7684\u5185\u90E8\u9519\u8BEF\uFF1A{0}\n\u8BF7\u586B\u5199 Bug \u62A5\u544A\uFF0C\u5E76\u5305\u62EC\u4EE5\u4E0B\u4FE1\u606F\uFF1A\n{1} While personally I like to see Chinese-style punctuation marks (Ex: `?`) used in Chinese contexts instead of their English-style ones (Ex: `:`), it's only updated on this single line and all the others are still using the English-style. There should be a general rule on which style we should use throughout all display messages. ------------- PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Wed Jan 25 17:47:19 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Wed, 25 Jan 2023 17:47:19 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v6] In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: Revert translated punctuation ------------- Changes: - all: https://git.openjdk.org/jdk20/pull/116/files - new: https://git.openjdk.org/jdk20/pull/116/files/616b2502..4222df9a Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=04-05 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk20/pull/116.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/116/head:pull/116 PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Wed Jan 25 17:51:20 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Wed, 25 Jan 2023 17:51:20 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v7] In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: <5QDH5Zhiji1PTh-833JdIopABeDoDCLA5e-u1Q3pkUE=.98a38bd3-3e52-4b51-9287-dc70454c4b89@github.com> > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: Revert one more punctuation ------------- Changes: - all: https://git.openjdk.org/jdk20/pull/116/files - new: https://git.openjdk.org/jdk20/pull/116/files/4222df9a..9a5b45a2 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=06 - incr: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=05-06 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk20/pull/116.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/116/head:pull/116 PR: https://git.openjdk.org/jdk20/pull/116 From weijun at openjdk.org Wed Jan 25 17:52:21 2023 From: weijun at openjdk.org (Weijun Wang) Date: Wed, 25 Jan 2023 17:52:21 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 23:56:23 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Revert culture attribute src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties line 113: > 111: doclet.inheritDocWithinInappropriateTag=\u4E0D\u80FD\u5728\u6B64\u6807\u8BB0\u4E2D\u4F7F\u7528 @inheritDoc > 112: doclet.inheritDocNoDoc=\u88AB\u8986\u76D6\u7684\u65B9\u6CD5\u4E0D\u8BB0\u5F55\u5F02\u5E38\u9519\u8BEF\u7C7B\u578B {0} > 113: doclet.throwsInheritDocUnsupported=\u4E0D\u662F\u7531\u65B9\u6CD5\u58F0\u660E\u7684 exception-type \u7C7B\u578B\u53C2\u6570\u4E0D\u652F\u6301 @inheritDoc\uFF1B\u76F4\u63A5\u8BB0\u5F55\u6B64\u7C7B\u5F02\u5E38\u9519\u8BEF\u7C7B\u578B Should `exception-type` be translated? ------------- PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Wed Jan 25 18:03:54 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Wed, 25 Jan 2023 18:03:54 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Wed, 25 Jan 2023 17:49:59 GMT, Weijun Wang wrote: >> Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: >> >> Revert culture attribute > > src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties line 113: > >> 111: doclet.inheritDocWithinInappropriateTag=\u4E0D\u80FD\u5728\u6B64\u6807\u8BB0\u4E2D\u4F7F\u7528 @inheritDoc >> 112: doclet.inheritDocNoDoc=\u88AB\u8986\u76D6\u7684\u65B9\u6CD5\u4E0D\u8BB0\u5F55\u5F02\u5E38\u9519\u8BEF\u7C7B\u578B {0} >> 113: doclet.throwsInheritDocUnsupported=\u4E0D\u662F\u7531\u65B9\u6CD5\u58F0\u660E\u7684 exception-type \u7C7B\u578B\u53C2\u6570\u4E0D\u652F\u6301 @inheritDoc\uFF1B\u76F4\u63A5\u8BB0\u5F55\u6B64\u7C7B\u5F02\u5E38\u9519\u8BEF\u7C7B\u578B > > Should `exception-type` be translated? The translation tool didn't seem to translate this. Either because it couldn't or because it somehow missed it. I'm not sure which, but I'm open to replacing this with a translation suggestion you have. Or I can leave it as is. > src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties line 32: > >> 30: err.bad.constant.pool=\u8BFB\u53D6{0}\u7684\u5E38\u91CF\u6C60\u65F6\u51FA\u9519: {1} >> 31: err.class.not.found=\u627E\u4E0D\u5230\u7C7B: {0} >> 32: err.crash=\u51FA\u73B0\u4E25\u91CD\u7684\u5185\u90E8\u9519\u8BEF\uFF1A{0}\n\u8BF7\u586B\u5199 Bug \u62A5\u544A\uFF0C\u5E76\u5305\u62EC\u4EE5\u4E0B\u4FE1\u606F\uFF1A\n{1} > > While personally I like to see Chinese-style punctuation marks (Ex: `?`) used in Chinese contexts instead of their English-style ones (Ex: `:`), it's only updated on this single line and all the others are still using the English-style. > > There should be a general rule on which style we should use throughout all display messages. Updated the punctuation (colons and comma) to be more consistent throughout the file. ------------- PR: https://git.openjdk.org/jdk20/pull/116 From weijun at openjdk.org Wed Jan 25 18:03:55 2023 From: weijun at openjdk.org (Weijun Wang) Date: Wed, 25 Jan 2023 18:03:55 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Wed, 25 Jan 2023 17:56:15 GMT, Damon Nguyen wrote: >> src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties line 113: >> >>> 111: doclet.inheritDocWithinInappropriateTag=\u4E0D\u80FD\u5728\u6B64\u6807\u8BB0\u4E2D\u4F7F\u7528 @inheritDoc >>> 112: doclet.inheritDocNoDoc=\u88AB\u8986\u76D6\u7684\u65B9\u6CD5\u4E0D\u8BB0\u5F55\u5F02\u5E38\u9519\u8BEF\u7C7B\u578B {0} >>> 113: doclet.throwsInheritDocUnsupported=\u4E0D\u662F\u7531\u65B9\u6CD5\u58F0\u660E\u7684 exception-type \u7C7B\u578B\u53C2\u6570\u4E0D\u652F\u6301 @inheritDoc\uFF1B\u76F4\u63A5\u8BB0\u5F55\u6B64\u7C7B\u5F02\u5E38\u9519\u8BEF\u7C7B\u578B >> >> Should `exception-type` be translated? > > The translation tool didn't seem to translate this. Either because it couldn't or because it somehow missed it. I'm not sure which, but I'm open to replacing this with a translation suggestion you have. Or I can leave it as is. I'm not sure either. You can ask a javadoc expert whether this is a proper noun or just plain English. I noticed it's also not translated in the Japanese version but the German version has translated it. >> src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties line 32: >> >>> 30: err.bad.constant.pool=\u8BFB\u53D6{0}\u7684\u5E38\u91CF\u6C60\u65F6\u51FA\u9519: {1} >>> 31: err.class.not.found=\u627E\u4E0D\u5230\u7C7B: {0} >>> 32: err.crash=\u51FA\u73B0\u4E25\u91CD\u7684\u5185\u90E8\u9519\u8BEF\uFF1A{0}\n\u8BF7\u586B\u5199 Bug \u62A5\u544A\uFF0C\u5E76\u5305\u62EC\u4EE5\u4E0B\u4FE1\u606F\uFF1A\n{1} >> >> While personally I like to see Chinese-style punctuation marks (Ex: `?`) used in Chinese contexts instead of their English-style ones (Ex: `:`), it's only updated on this single line and all the others are still using the English-style. >> >> There should be a general rule on which style we should use throughout all display messages. > > Updated the punctuation (colons and comma) to be more consistent throughout the file. Looks good now. ------------- PR: https://git.openjdk.org/jdk20/pull/116 From jjg at openjdk.org Wed Jan 25 18:24:55 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Wed, 25 Jan 2023 18:24:55 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v7] In-Reply-To: <5QDH5Zhiji1PTh-833JdIopABeDoDCLA5e-u1Q3pkUE=.98a38bd3-3e52-4b51-9287-dc70454c4b89@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> <5QDH5Zhiji1PTh-833JdIopABeDoDCLA5e-u1Q3pkUE=.98a38bd3-3e52-4b51-9287-dc70454c4b89@github.com> Message-ID: On Wed, 25 Jan 2023 17:51:20 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Revert one more punctuation I don't see anything absurdly wrong in the jdk.compiler files. ------------- Marked as reviewed by jjg (Reviewer). PR: https://git.openjdk.org/jdk20/pull/116 From weijun at openjdk.org Wed Jan 25 18:58:57 2023 From: weijun at openjdk.org (Weijun Wang) Date: Wed, 25 Jan 2023 18:58:57 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v7] In-Reply-To: <5QDH5Zhiji1PTh-833JdIopABeDoDCLA5e-u1Q3pkUE=.98a38bd3-3e52-4b51-9287-dc70454c4b89@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> <5QDH5Zhiji1PTh-833JdIopABeDoDCLA5e-u1Q3pkUE=.98a38bd3-3e52-4b51-9287-dc70454c4b89@github.com> Message-ID: On Wed, 25 Jan 2023 17:51:20 GMT, Damon Nguyen wrote: >> Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. >> All tests passed > > Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: > > Revert one more punctuation zh_cn translations look fine. Thanks. ------------- Marked as reviewed by weijun (Reviewer). PR: https://git.openjdk.org/jdk20/pull/116 From prappo at openjdk.org Wed Jan 25 20:06:53 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Wed, 25 Jan 2023 20:06:53 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Wed, 25 Jan 2023 18:00:33 GMT, Weijun Wang wrote: >> The translation tool didn't seem to translate this. Either because it couldn't or because it somehow missed it. I'm not sure which, but I'm open to replacing this with a translation suggestion you have. Or I can leave it as is. > > I'm not sure either. You can ask a javadoc expert whether this is a proper noun or just plain English. I noticed it's also not translated in the Japanese version but the German version has translated it. It's not a noun. It's an adjective that I had to synthesize for extra clarity and closeness to Java Language Specification (JLS). The English version of that entry is as follows: doclet.throwsInheritDocUnsupported=@inheritDoc is not supported for exception-type type parameters \ that are not declared by a method; document such exception types directly JLS _8.4.6. Method Throws_ defines BNF which conveniently labels elements, a list of which may appear in the `throws` clause, as `ExceptionType`. To make it more English-like and separate two otherwise consecutive occurrences of "type" in that sentence, I split the words with a hyphen and lower-cased them: exception-type. @jonathan-gibbons thoughts? ------------- PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Wed Jan 25 22:02:45 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Wed, 25 Jan 2023 22:02:45 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v8] In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: Update German translation ------------- Changes: - all: https://git.openjdk.org/jdk20/pull/116/files - new: https://git.openjdk.org/jdk20/pull/116/files/9a5b45a2..35829a25 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=07 - incr: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=06-07 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk20/pull/116.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/116/head:pull/116 PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Wed Jan 25 22:19:34 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Wed, 25 Jan 2023 22:19:34 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v2] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Wed, 25 Jan 2023 08:17:26 GMT, danielpeintner wrote: >> Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: >> >> Change German help of jar command > > src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_de.properties line 111: > >> 109: main.help.opt.main.update=\ -u, --update Ein vorhandenes JAR-Archiv aktualisieren >> 110: main.help.opt.main.extract=\ -x, --extract Benannte (oder alle) Dateien aus dem Archiv extrahieren >> 111: main.help.opt.main.describe-module=\ -d, --describe-module Gibt den Moduldeskriptor oder automatischen Modulnamen aus > > Just because I stumbled over this commit. I think the line should be translated as follows: > > `Gibt die Modulbeschreibung oder den automatischen Modulnamen aus` Resolved ------------- PR: https://git.openjdk.org/jdk20/pull/116 From jjg at openjdk.org Wed Jan 25 22:41:34 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Wed, 25 Jan 2023 22:41:34 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Wed, 25 Jan 2023 20:03:48 GMT, Pavel Rappo wrote: >> I'm not sure either. You can ask a javadoc expert whether this is a proper noun or just plain English. I noticed it's also not translated in the Japanese version but the German version has translated it. > > It's not a noun. It's an adjective that I had to synthesize for extra clarity and closeness to Java Language Specification (JLS). The English version of that entry is as follows: > > doclet.throwsInheritDocUnsupported=@inheritDoc is not supported for exception-type type parameters \ > that are not declared by a method; document such exception types directly > > JLS _8.4.6. Method Throws_ defines BNF which conveniently labels elements, a list of which may appear in the `throws` clause, as `ExceptionType`. To make it more English-like and separate two otherwise consecutive occurrences of "type" in that sentence, I split the words with a hyphen and lower-cased them: exception-type. > > @jonathan-gibbons thoughts? While the text is technically correct, it may not be as clear as it could be to all folk that will read this message for whom English is not their primary language. I would suggest translating the phrase as if it were something like @inheritDoc is not supported for type parameters that are exception types and not declared by a method and secondarily, changing the English resource to something like that as well. ------------- PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Wed Jan 25 22:56:59 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Wed, 25 Jan 2023 22:56:59 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v9] In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed Damon Nguyen has updated the pull request incrementally with one additional commit since the last revision: Replace exception-type ------------- Changes: - all: https://git.openjdk.org/jdk20/pull/116/files - new: https://git.openjdk.org/jdk20/pull/116/files/35829a25..53a86ef2 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=08 - incr: https://webrevs.openjdk.org/?repo=jdk20&pr=116&range=07-08 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk20/pull/116.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/116/head:pull/116 PR: https://git.openjdk.org/jdk20/pull/116 From dnguyen at openjdk.org Wed Jan 25 22:56:59 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Wed, 25 Jan 2023 22:56:59 GMT Subject: [jdk20] RFR: 8300719: JDK 20 RDP2 L10n resource files update [v5] In-Reply-To: References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Wed, 25 Jan 2023 22:38:38 GMT, Jonathan Gibbons wrote: >> It's not a noun. It's an adjective that I had to synthesize for extra clarity and closeness to Java Language Specification (JLS). The English version of that entry is as follows: >> >> doclet.throwsInheritDocUnsupported=@inheritDoc is not supported for exception-type type parameters \ >> that are not declared by a method; document such exception types directly >> >> JLS _8.4.6. Method Throws_ defines BNF which conveniently labels elements, a list of which may appear in the `throws` clause, as `ExceptionType`. To make it more English-like and separate two otherwise consecutive occurrences of "type" in that sentence, I split the words with a hyphen and lower-cased them: exception-type. >> >> @jonathan-gibbons thoughts? > > While the text is technically correct, it may not be as clear as it could be to all folk that will read this message for whom English is not their primary language. > > I would suggest translating the phrase as if it were something like > > @inheritDoc is not supported for type parameters that are exception types and not declared by a method > > > and secondarily, changing the English resource to something like that as well. Updated this line with `exception-type` translated. Hopefully this will be addressed in future drops with changes to the translation tool after some bug fixes. ------------- PR: https://git.openjdk.org/jdk20/pull/116 From jjg at openjdk.org Wed Jan 25 23:23:17 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Wed, 25 Jan 2023 23:23:17 GMT Subject: RFR: JDK-8300857: State return value for Types.asElement(NoType) explicitly [v2] In-Reply-To: References: Message-ID: On Wed, 25 Jan 2023 03:56:30 GMT, Joe Darcy wrote: >> Just sending out the proposed API changes for now, will add tests later. >> >> Please also review the corresponding CSR [JDK-8300951](https://bugs.openjdk.org/browse/JDK-8300951). > > Joe Darcy has updated the pull request incrementally with two additional commits since the last revision: > > - Applease jcheck. > - Refine spec, add regression test. src/java.compiler/share/classes/javax/lang/model/util/Types.java line 50: > 48: * The type may be a {@link DeclaredType} or {@link TypeVariable}, > 49: * or a pseudo-type for a {@linkplain TypeKind#PACKAGE package} or > 50: * {@linkplain TypeKind#MODULE module}. Commas look erratic. `The type may be A or B, or C` ------------- PR: https://git.openjdk.org/jdk/pull/12159 From jjg at openjdk.org Wed Jan 25 23:43:22 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Wed, 25 Jan 2023 23:43:22 GMT Subject: RFR: JDK-8300857: State return value for Types.asElement(NoType) explicitly [v2] In-Reply-To: References: Message-ID: On Wed, 25 Jan 2023 03:56:30 GMT, Joe Darcy wrote: >> Just sending out the proposed API changes for now, will add tests later. >> >> Please also review the corresponding CSR [JDK-8300951](https://bugs.openjdk.org/browse/JDK-8300951). > > Joe Darcy has updated the pull request incrementally with two additional commits since the last revision: > > - Applease jcheck. > - Refine spec, add regression test. approved with quibbles for optional update I like the presence of the new test ;-) test/langtools/tools/javac/processing/model/util/types/TestAsElement.java line 78: > 76: > 77: > 78: excess blank lines? test/langtools/tools/javac/processing/model/util/types/TestAsElement.java line 87: > 85: > 86: private void testRoundTripCases() { > 87: expectRoundTrip(eltUtils.getPackageElement("java.lang")); Maybe add a type element as well as the package element and module element ------------- Marked as reviewed by jjg (Reviewer). PR: https://git.openjdk.org/jdk/pull/12159 From darcy at openjdk.org Thu Jan 26 02:08:38 2023 From: darcy at openjdk.org (Joe Darcy) Date: Thu, 26 Jan 2023 02:08:38 GMT Subject: RFR: JDK-8300857: State return value for Types.asElement(NoType) explicitly [v3] In-Reply-To: References: Message-ID: <5UJdh4N6o8BkGSxLJ_8_p5D-cM1TzD0MrI0hV6c9KBM=.b68d7231-541d-4cee-9029-cce3bd562fd6@github.com> > Just sending out the proposed API changes for now, will add tests later. > > Please also review the corresponding CSR [JDK-8300951](https://bugs.openjdk.org/browse/JDK-8300951). Joe Darcy has updated the pull request incrementally with one additional commit since the last revision: Respond to review feedback. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12159/files - new: https://git.openjdk.org/jdk/pull/12159/files/a60301ce..4cf42268 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12159&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12159&range=01-02 Stats: 16 lines in 2 files changed: 5 ins; 4 del; 7 mod Patch: https://git.openjdk.org/jdk/pull/12159.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12159/head:pull/12159 PR: https://git.openjdk.org/jdk/pull/12159 From darcy at openjdk.org Thu Jan 26 02:17:26 2023 From: darcy at openjdk.org (Joe Darcy) Date: Thu, 26 Jan 2023 02:17:26 GMT Subject: Integrated: JDK-8300857: State return value for Types.asElement(NoType) explicitly In-Reply-To: References: Message-ID: On Tue, 24 Jan 2023 05:38:36 GMT, Joe Darcy wrote: > Just sending out the proposed API changes for now, will add tests later. > > Please also review the corresponding CSR [JDK-8300951](https://bugs.openjdk.org/browse/JDK-8300951). This pull request has now been integrated. Changeset: b5a4744f Author: Joe Darcy URL: https://git.openjdk.org/jdk/commit/b5a4744f9019f76664738029f13b4d4f651d20d6 Stats: 117 lines in 3 files changed: 114 ins; 0 del; 3 mod 8300857: State return value for Types.asElement(NoType) explicitly Reviewed-by: jjg ------------- PR: https://git.openjdk.org/jdk/pull/12159 From dnguyen at openjdk.org Thu Jan 26 22:36:39 2023 From: dnguyen at openjdk.org (Damon Nguyen) Date: Thu, 26 Jan 2023 22:36:39 GMT Subject: [jdk20] Integrated: 8300719: JDK 20 RDP2 L10n resource files update In-Reply-To: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> References: <0fuTtDy_5ZjAaxfJV75WRG8xQ76Tj-oM5hdYpG-yfkk=.a4ce241d-52a8-422a-9e1e-40de0afa78cb@github.com> Message-ID: On Tue, 24 Jan 2023 20:50:00 GMT, Damon Nguyen wrote: > Open l10n drop. Files have been updated with translated versions. Whitespace tool has been ran on files. > All tests passed This pull request has now been integrated. Changeset: a67b1e77 Author: Damon Nguyen Committer: Naoto Sato URL: https://git.openjdk.org/jdk20/commit/a67b1e77d33339f5db36c6d15bac0423a31eb5ee Stats: 1023 lines in 82 files changed: 218 ins; 114 del; 691 mod 8300719: JDK 20 RDP2 L10n resource files update Reviewed-by: cjplummer, naoto, prr, joehw, asemenyuk, jlu, lancea, ihse, jjg, weijun ------------- PR: https://git.openjdk.org/jdk20/pull/116 From vromero at openjdk.org Fri Jan 27 05:21:20 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 27 Jan 2023 05:21:20 GMT Subject: RFR: 8296010: AssertionError in annotationTargetType Message-ID: javac is crashing if a class file is forged so that an annotation can be applicable to an unknown target. It would be equivalent to the following declaration: @Target(ElementType.NO_SUCH) @interface A {} if the compiler process this source it would issue a compiler error, indicating that symbol `NO_SUCH` cant be found. Currently our class reader just issues a warning and move on. This is OK as it could be that the loaded class won't be used anyway but if this annotation is actually applied to symbol as in: class B { @A Object o; } then this to my understanding should be a compilation error. Currently javac is crashing and this is not acceptable, so this PR is fixing this issue so that a compilation error is issued instead. ------------- Commit messages: - 8296010: AssertionError in annotationTargetType Changes: https://git.openjdk.org/jdk/pull/12241/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12241&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8296010 Stats: 116 lines in 7 files changed: 98 ins; 1 del; 17 mod Patch: https://git.openjdk.org/jdk/pull/12241.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12241/head:pull/12241 PR: https://git.openjdk.org/jdk/pull/12241 From vromero at openjdk.org Fri Jan 27 05:25:49 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 27 Jan 2023 05:25:49 GMT Subject: RFR: 8296010: AssertionError in annotationTargetType [v2] In-Reply-To: References: Message-ID: > javac is crashing if a class file is forged so that an annotation can be applicable to an unknown target. It would be equivalent to the following declaration: > > > @Target(ElementType.NO_SUCH) > @interface A {} > > if the compiler process this source it would issue a compiler error, indicating that symbol `NO_SUCH` cant be found. Currently our class reader just issues a warning and move on. This is OK as it could be that the loaded class won't be used anyway but if this annotation is actually applied to symbol as in: > > > class B { > @A Object o; > } > > then this to my understanding should be a compilation error. Currently javac is crashing and this is not acceptable, so this PR is fixing this issue so that a compilation error is issued instead. Vicente Romero has updated the pull request incrementally with one additional commit since the last revision: updating parameter name ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12241/files - new: https://git.openjdk.org/jdk/pull/12241/files/50d07c79..59a6f3c1 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12241&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12241&range=00-01 Stats: 11 lines in 1 file changed: 0 ins; 0 del; 11 mod Patch: https://git.openjdk.org/jdk/pull/12241.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12241/head:pull/12241 PR: https://git.openjdk.org/jdk/pull/12241 From duke at openjdk.org Fri Jan 27 18:43:34 2023 From: duke at openjdk.org (duke) Date: Fri, 27 Jan 2023 18:43:34 GMT Subject: Withdrawn: 8296546: Add @spec tags to API In-Reply-To: <5uS_XWg0xRt6Rp20wY65rAmNRcDrp5XN_74k1aQ_4jk=.9f458354-9bca-473e-b60e-e520fa90724b@github.com> References: <5uS_XWg0xRt6Rp20wY65rAmNRcDrp5XN_74k1aQ_4jk=.9f458354-9bca-473e-b60e-e520fa90724b@github.com> Message-ID: On Thu, 10 Nov 2022 01:10:13 GMT, Jonathan Gibbons wrote: > Please review a "somewhat automated" change to insert `@spec` tags into doc comments, as appropriate, to leverage the recent new javadoc feature to generate a new page listing the references to all external specifications listed in the `@spec` tags. > > "Somewhat automated" means that I wrote and used a temporary utility to scan doc comments looking for HTML links to selected sites, such as `ietf.org`, `unicode.org`, `w3.org`. These links may be in the main description of a doc comment, or in `@see` tags. For each link, the URL is examined, and "normalized", and inserted into the doc comment with a new `@spec` tag, giving the link and tile for the spec. > > "Normalized" means... > * Use `https:` where possible (includes pretty much all cases) > * Use a single consistent host name for all URLs coming from the same spec site (i.e. don't use different aliases for the same site) > * Point to the root page of a multi-page spec > * Use a consistent form of the spec, preferring HTML over plain text where both are available (this mostly applies to IETF specs) > > In addition, a "standard" title is determined for all specs, determined either from the content of the (main) spec page or from site index pages. > > The net effect is (or should be) that **all** the changes are to just **add** new `@spec` tags, based on the links found in each doc comment. There should be no other changes to the doc comments, or to the implementation of any classes and interfaces. > > That being said, the utility I wrote does have additional abilities, to update the links that it finds (e.g. changing to use `https:` etc,) but those features are _not_ being used here, but could be used in followup PRs if component teams so desired. I did notice while working on this overall feature that many of our links do point to "outdated" pages, some with eye-catching notices declaring that the spec has been superseded. Determining how, when and where to update such links is beyond the scope of this PR. > > Going forward, it is to be hoped that component teams will maintain the underlying links, and the URLs in `@spec` tags, such that if references to external specifications are updated, this will include updating the `@spec` tags. > > To see the effect of all these new `@spec` tags, see http://cr.openjdk.java.net/~jjg/8296546/api.00/ > > In particular, see the new [External Specifications](http://cr.openjdk.java.net/~jjg/8296546/api.00/external-specs.html) page, which you can also find via the new link near the top of the [Index](http://cr.openjdk.java.net/~jjg/8296546/api.00/index-files/index-1.html) pages. This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jdk/pull/11073 From jjg at openjdk.org Fri Jan 27 18:48:56 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Fri, 27 Jan 2023 18:48:56 GMT Subject: RFR: JDK-8301201: Allow \n@ inside inline tags using inlineContent Message-ID: Please review a simple change to allow the use of _newline_ _whitespace_ `@` inside inline tags that allow rich content (that is, those parsed with `inlineContent`) as compared to those that only allow plain text (that is, those parsed with `inlineText`). The fix is to delete the code which recognizes `@` as the beginning of a block tag. Compare to the similar fix in [JDK-8241780](https://bugs.openjdk.org/browse/JDK-8241780) The general `TagTest.java` is updated for the new feature. ------------- Commit messages: - JDK-8301201: Allow \n@ inside inline tags using inlineContent Changes: https://git.openjdk.org/jdk/pull/12264/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12264&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8301201 Stats: 47 lines in 3 files changed: 37 ins; 5 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/12264.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12264/head:pull/12264 PR: https://git.openjdk.org/jdk/pull/12264 From cushon at openjdk.org Fri Jan 27 19:29:21 2023 From: cushon at openjdk.org (Liam Miller-Cushon) Date: Fri, 27 Jan 2023 19:29:21 GMT Subject: RFR: 8296010: AssertionError in annotationTargetType [v2] In-Reply-To: References: Message-ID: On Fri, 27 Jan 2023 05:25:49 GMT, Vicente Romero wrote: >> javac is crashing if a class file is forged so that an annotation can be applicable to an unknown target. It would be equivalent to the following declaration: >> >> >> @Target({ElementType.FIELD, ElementType.NO_SUCH}) >> @interface A {} >> >> if the compiler process this source it would issue a compiler error, indicating that symbol `NO_SUCH` cant be found. Currently our class reader just issues a warning and move on. This is OK as it could be that the loaded class won't be used anyway but if this annotation is actually applied to symbol as in: >> >> >> class B { >> @A Object o; >> } >> >> then this to my understanding should be a compilation error. Currently javac is crashing and this is not acceptable, so this PR is fixing this issue so that a compilation error is issued instead. > > Vicente Romero has updated the pull request incrementally with one additional commit since the last revision: > > updating parameter name LGTM, thanks! ------------- PR: https://git.openjdk.org/jdk/pull/12241 From jwilhelm at openjdk.org Fri Jan 27 21:08:40 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Fri, 27 Jan 2023 21:08:40 GMT Subject: RFR: Merge jdk20 Message-ID: <7o8i6xuRhpJrSJJg2EUyu-JPcawJAytTWS3yHX3PZd0=.0157940a-bbb2-4dc0-a645-5cde446d5052@github.com> Forwardport JDK 20 -> JDK 21 ------------- Commit messages: - Merge remote-tracking branch 'jdk20/master' into Merge_jdk20 - 8301206: Fix issue with LocaleData after JDK-8300719 - 8300953: ClassDesc::ofInternalName missing @since tag - 8300719: JDK 20 RDP2 L10n resource files update The webrevs contain the adjustments done while merging with regards to each parent branch: - master: https://webrevs.openjdk.org/?repo=jdk&pr=12267&range=00.0 - jdk20: https://webrevs.openjdk.org/?repo=jdk&pr=12267&range=00.1 Changes: https://git.openjdk.org/jdk/pull/12267/files Stats: 1078 lines in 85 files changed: 220 ins; 114 del; 744 mod Patch: https://git.openjdk.org/jdk/pull/12267.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12267/head:pull/12267 PR: https://git.openjdk.org/jdk/pull/12267 From jwilhelm at openjdk.org Fri Jan 27 22:49:26 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Fri, 27 Jan 2023 22:49:26 GMT Subject: Integrated: Merge jdk20 In-Reply-To: <7o8i6xuRhpJrSJJg2EUyu-JPcawJAytTWS3yHX3PZd0=.0157940a-bbb2-4dc0-a645-5cde446d5052@github.com> References: <7o8i6xuRhpJrSJJg2EUyu-JPcawJAytTWS3yHX3PZd0=.0157940a-bbb2-4dc0-a645-5cde446d5052@github.com> Message-ID: On Fri, 27 Jan 2023 21:00:03 GMT, Jesper Wilhelmsson wrote: > Forwardport JDK 20 -> JDK 21 This pull request has now been integrated. Changeset: 5c59de52 Author: Jesper Wilhelmsson URL: https://git.openjdk.org/jdk/commit/5c59de52a31da937663ad2cef055213489b0516e Stats: 1078 lines in 85 files changed: 220 ins; 114 del; 744 mod Merge ------------- PR: https://git.openjdk.org/jdk/pull/12267 From ihse at openjdk.org Sat Jan 28 21:11:19 2023 From: ihse at openjdk.org (Magnus Ihse Bursie) Date: Sat, 28 Jan 2023 21:11:19 GMT Subject: RFR: 8298044: Fix hidden but significant trailing whitespace in properties files for langtools code In-Reply-To: References: Message-ID: On Fri, 2 Dec 2022 16:36:22 GMT, Magnus Ihse Bursie wrote: > According to [the specification](https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/util/Properties.html#load(java.io.Reader)) trailing whitespaces in the values of properties files are (somewhat surprisingly) actually significant. > > We have multiple files in the JDK with trailing whitespaces in the values. For most of this files, this is likely incorrect and due to oversight, but in a few cases it might actually be intended (like "The value is: "). > > After a discussion in the PR for [JDK-8295729](https://bugs.openjdk.org/browse/JDK-8295729), the consensus was to replace valid trailing spaces with the corresponding unicode sequence, `\u0020`. (And of course remove non-wanted trailing spaces.) > > Doing so has a dual benefit: > > 1) It makes it clear to everyone reading the code that there is a trailing space and it is intended > > 2) It will allow us to remove all actual trailing space characters, and turn on the corresponding check in jcheck to keep the properties files, just like all other source code files, free of trailing spaces. > > Ultimately, the call of whether a trailing space is supposed to be there, or is a bug, lies with the respective component teams owning these files. Thus I have split up the set of properties files with trailing spaces in several groups, to match the JDK teams, and open a JBS issue for each of them. This issue is for code I believe belongs with the langtools team. Bot-Keep-Alive-Ping ------------- PR: https://git.openjdk.org/jdk/pull/11487 From vromero at openjdk.org Sun Jan 29 02:26:54 2023 From: vromero at openjdk.org (Vicente Romero) Date: Sun, 29 Jan 2023 02:26:54 GMT Subject: RFR: 8297158: Suspicious collection method call in Types.isSameTypeVisitor Message-ID: As reported there is a code in `com.sun.tools.javac.code.Types` that was basically a no-op. The code in question is: if (tMap.containsKey(ti)) { throw new AssertionError("Malformed intersection"); } tMap.put(ti.tsym, ti); where tMap is defined as: `Map`, but `ti` is a type so the condition, `tMap.containsKey(ti)`, is always false. The assertion should be thrown if an intersection type has two or more repeated interfaces. But there are other places in the compiler where this is checked for and an error is issued. So it shouldn't be possible to get to this point during a compilation. There are several tests, including combo tests, already stressing this code for this reason there is no need to add more regression tests. TIA ------------- Commit messages: - 8297158: Suspicious collection method call in Types.isSameTypeVisitor Changes: https://git.openjdk.org/jdk/pull/12279/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12279&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8297158 Stats: 9 lines in 4 files changed: 0 ins; 3 del; 6 mod Patch: https://git.openjdk.org/jdk/pull/12279.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12279/head:pull/12279 PR: https://git.openjdk.org/jdk/pull/12279 From vromero at openjdk.org Sun Jan 29 02:26:54 2023 From: vromero at openjdk.org (Vicente Romero) Date: Sun, 29 Jan 2023 02:26:54 GMT Subject: RFR: 8297158: Suspicious collection method call in Types.isSameTypeVisitor In-Reply-To: References: Message-ID: On Sun, 29 Jan 2023 02:20:10 GMT, Vicente Romero wrote: > As reported there is a code in `com.sun.tools.javac.code.Types` that was basically a no-op. The code in question is: > > > if (tMap.containsKey(ti)) { > throw new AssertionError("Malformed intersection"); > } > tMap.put(ti.tsym, ti); > > where tMap is defined as: `Map`, but `ti` is a type so the condition, `tMap.containsKey(ti)`, is always false. The assertion should be thrown if an intersection type has two or more repeated interfaces. But there are other places in the compiler where this is checked for and an error is issued. So it shouldn't be possible to get to this point during a compilation. There are several tests, including combo tests, already stressing this code for this reason there is no need to add more regression tests. > > TIA src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java line 5119: > 5117: > 5118: Type checkIntersection(JCTree tree, List bounds) { > 5119: Set boundSet = new HashSet<>(); this set had the same issue, two different Type instances can refer to the same type but the `tsym` field they have should point to a common symbol. This is why we should have a set on these symbols ------------- PR: https://git.openjdk.org/jdk/pull/12279 From vromero at openjdk.org Sun Jan 29 04:27:02 2023 From: vromero at openjdk.org (Vicente Romero) Date: Sun, 29 Jan 2023 04:27:02 GMT Subject: RFR: 8293519: deprecation warnings should be emitted for uses of annotation methods inside other annotations Message-ID: Javac is forgetting to double check if the left hand side in an annotation name-value pair is a deprecated method, basically in this case: @interface Anno { @Deprecated boolean b() default false; } @Anno(b = true) // a warning should be issued here class Foo {} this PR is fixing this oversight, TIA ------------- Commit messages: - 8293519: deprecation warnings should be emitted for uses of annotation methods inside other annotations Changes: https://git.openjdk.org/jdk/pull/12280/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12280&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8293519 Stats: 20 lines in 3 files changed: 20 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/12280.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12280/head:pull/12280 PR: https://git.openjdk.org/jdk/pull/12280 From vromero at openjdk.org Tue Jan 31 05:44:42 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 31 Jan 2023 05:44:42 GMT Subject: RFR: 8295019: Cannot call a method with a parameter of a local class declared in a lambda Message-ID: Very interesting and, a bit tricky, bug. So the compiler is rejecting code like: class LocalClassDeclaredInsideLambdaTest { void run(Runnable r) {} void m() { run(() -> { class C { static void takeC(C c) {} static C giveC() { return null; } } C.takeC(C.giveC()); }); } } with error: LocalClassInsideLambda.java:12: error: incompatible types: C cannot be converted to C C.takeC(C.giveC()); ^ Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output 1 error which is very misleading as the type seems to be the same. The issue here is that both the lambda and invocation `C.giveC()` are considered poly expressions. `C.giveC()` is not a poly expression but at the moment the compiler is analyzing if an invocation is a poly expression or not, it doesn't have enough information and errs on the safe side. We have a cache at `com.sun.tools.javac.comp.ArgumentAttr`, see field `argumentTypeCache`, which stores the current deferred type of arguments considered poly expressions. The problem with this particular code is that inside of the lambda there is a class declaration and every time the lambda is attributed a new class type is created. The lambda, and thus the expression `C.giveC()` are attributed twice. The first time we have an speculative attribution, as a result `argumentTypeCache` will have two entries, one for the lambda and one for `C.giveC()` but the type of `C` is the type created during speculative attribution on a copy of the original lambda tree, let's call it C1. Later on another pass the lambda is attributed `"for real"`, during the check phase. At this point the entry for the lambda in the cache pointed by `argumentTypeCache` has been removed but there is still the entry for `C.giveC()` which still refers to `C1`. So now in the `"for real"` attribution of the lambda which happens on the original tree, not in a copy, a new type for class `C` is created, let's call it `C2`. But when we get to the point where we need to attribute again `C.takeC(C.giveC())` invocation `C.takeC` is expecting `C2` but as `C.giveC()` is again considered a poly expression and an entry is found for it at the cache, the compil er reuses that entry which refers to `C1`. And unfortunately `C1 != C2` and thus the error is issued. So the solution I propose is to use a local cache for the speculative attribution of lambda expressions. This is a one liner fix, although an alternative solution could be to scan the lambda body and only use a local cache if a new type is defined inside the lambda, this could be a more optimal solution performance wise as we could save some attributions in some cases. Comments? TIA ------------- Commit messages: - updating test name - 8295019: Cannot call a method with a parameter of a local class declared in a lambda Changes: https://git.openjdk.org/jdk/pull/12303/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12303&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8295019 Stats: 65 lines in 2 files changed: 64 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/12303.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12303/head:pull/12303 PR: https://git.openjdk.org/jdk/pull/12303 From vromero at openjdk.org Tue Jan 31 05:50:56 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 31 Jan 2023 05:50:56 GMT Subject: RFR: 8296010: AssertionError in annotationTargetType [v2] In-Reply-To: References: Message-ID: On Fri, 27 Jan 2023 19:26:18 GMT, Liam Miller-Cushon wrote: > LGTM, thanks! thanks for your feedback! ------------- PR: https://git.openjdk.org/jdk/pull/12241 From duke at openjdk.org Tue Jan 31 06:51:05 2023 From: duke at openjdk.org (ExE Boss) Date: Tue, 31 Jan 2023 06:51:05 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet [v3] In-Reply-To: References: Message-ID: <9ifr0XLxi6tBlCg3vlO3mgVyFH3b7tj5hPXGHE5IVWg=.70aa6be1-7d63-4e50-94f4-afb524596b84@github.com> On Tue, 24 Jan 2023 21:43:04 GMT, Jonathan Gibbons wrote: >> Support for Markdown comments in the standard doclet. >> >> To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. >> >> The work is in 3 parts: >> >> 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. >> 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. >> 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. >> >> There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. >> >> Background info: https://mail.openjdk.org/pipermail/javadoc-dev/2023-January/005563.html > > Jonathan Gibbons has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains eight commits: > > - Merge with upstream/master > - Update copyright years > - Rename FFFC variable > Share Markdown parser and renderer in instance of MarkdownHandler > - Move CommonMark to new internal module. > Add legal header to imported CommonMark source files > Always use Text nodes inside AttributeTree values > Unwrap

    from "simple" paragraphs > - Always use Text nodes inside AttributeTree values > - Update to CommonMark 0.21. > - fix whitespace > - JDK-8298405: Markdown support in the standard doclet There?should probably?be an?option to?make **Markdown** the?default. ------------- PR: https://git.openjdk.org/jdk/pull/11701 From jlahoda at openjdk.org Tue Jan 31 11:52:58 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Tue, 31 Jan 2023 11:52:58 GMT Subject: RFR: 8297158: Suspicious collection method call in Types.isSameTypeVisitor In-Reply-To: References: Message-ID: On Sun, 29 Jan 2023 02:20:10 GMT, Vicente Romero wrote: > As reported there is a code in `com.sun.tools.javac.code.Types` that was basically a no-op. The code in question is: > > > if (tMap.containsKey(ti)) { > throw new AssertionError("Malformed intersection"); > } > tMap.put(ti.tsym, ti); > > where tMap is defined as: `Map`, but `ti` is a type so the condition, `tMap.containsKey(ti)`, is always false. The assertion should be thrown if an intersection type has two or more repeated interfaces. But there are other places in the compiler where this is checked for and an error is issued if necessary. So it shouldn't be possible to get to this point during a compilation. There are several tests, including combo tests, already stressing this condition, intersection types with repeated interfaces, for this reason there is no need to add more regression tests. > > TIA Looks good to me. ------------- Marked as reviewed by jlahoda (Reviewer). PR: https://git.openjdk.org/jdk/pull/12279 From jlahoda at openjdk.org Tue Jan 31 12:00:02 2023 From: jlahoda at openjdk.org (Jan Lahoda) Date: Tue, 31 Jan 2023 12:00:02 GMT Subject: RFR: 8293519: deprecation warnings should be emitted for uses of annotation methods inside other annotations In-Reply-To: References: Message-ID: On Sun, 29 Jan 2023 04:19:49 GMT, Vicente Romero wrote: > Javac is forgetting to double check if the left hand side in an annotation name-value pair is a deprecated method, basically in this case: > > @interface Anno { > @Deprecated > boolean b() default false; > } > > @Anno(b = true) // a warning should be issued here > class Foo {} > > this PR is fixing this oversight, > > TIA Seems sensible. Do we need a CSR for this? ------------- Marked as reviewed by jlahoda (Reviewer). PR: https://git.openjdk.org/jdk/pull/12280 From hannesw at openjdk.org Tue Jan 31 14:58:08 2023 From: hannesw at openjdk.org (Hannes =?UTF-8?B?V2FsbG7DtmZlcg==?=) Date: Tue, 31 Jan 2023 14:58:08 GMT Subject: RFR: JDK-8301201: Allow \n@ inside inline tags using inlineContent In-Reply-To: References: Message-ID: On Fri, 27 Jan 2023 18:41:45 GMT, Jonathan Gibbons wrote: > Please review a simple change to allow the use of _newline_ _whitespace_ `@` inside inline tags that allow rich content (that is, those parsed with `inlineContent`) as compared to those that only allow plain text (that is, those parsed with `inlineText`). > > The fix is to delete the code which recognizes `@` as the beginning of a block tag. Compare to the similar fix in [JDK-8241780](https://bugs.openjdk.org/browse/JDK-8241780) > > The general `TagTest.java` is updated for the new feature. test/langtools/tools/javac/doctree/DocCommentTester.java line 922: > 920: String s2 = s.trim().replaceFirst("\\.\\s*\\n *@", ".\n@"); > 921: StringBuilder sb = new StringBuilder(); > 922: Pattern p = Pattern.compile("(?i)\\{@([a-z][a-z0-9.:-]*)( )?"); Why is this change necessary? I see it is intended to impact the unknown inline tag in `TagTest.java`, but couldn't the test be written without this change? ------------- PR: https://git.openjdk.org/jdk/pull/12264 From duke at openjdk.org Tue Jan 31 15:08:59 2023 From: duke at openjdk.org (Manu Sridharan) Date: Tue, 31 Jan 2023 15:08:59 GMT Subject: RFR: 8296010: AssertionError in annotationTargetType [v2] In-Reply-To: References: Message-ID: On Fri, 27 Jan 2023 05:25:49 GMT, Vicente Romero wrote: >> javac is crashing if a class file is forged so that an annotation can be applicable to an unknown target. It would be equivalent to the following declaration: >> >> >> @Target({ElementType.FIELD, ElementType.NO_SUCH}) >> @interface A {} >> >> if the compiler process this source it would issue a compiler error, indicating that symbol `NO_SUCH` cant be found. Currently our class reader just issues a warning and move on. This is OK as it could be that the loaded class won't be used anyway but if this annotation is actually applied to symbol as in: >> >> >> class B { >> @A Object o; >> } >> >> then this to my understanding should be a compilation error. Currently javac is crashing and this is not acceptable, so this PR is fixing this issue so that a compilation error is issued instead. > > Vicente Romero has updated the pull request incrementally with one additional commit since the last revision: > > updating parameter name test/langtools/tools/javac/annotations/crashOnUnknownAttr/CrashOnUnknownTargetTypeTest.java line 10: > 8: > 9: public class CrashOnUnknownTargetTypeTest { > 10: @A Object o; I wonder if it's worth testing the case where the annotation appears on a method as well? We observed crashes before due to that placement as well. It's possible the relevant code paths are shared so an additional test is unnecessary ------------- PR: https://git.openjdk.org/jdk/pull/12241 From hannesw at openjdk.org Tue Jan 31 15:31:09 2023 From: hannesw at openjdk.org (Hannes =?UTF-8?B?V2FsbG7DtmZlcg==?=) Date: Tue, 31 Jan 2023 15:31:09 GMT Subject: RFR: JDK-8301201: Allow \n@ inside inline tags using inlineContent In-Reply-To: References: Message-ID: On Fri, 27 Jan 2023 18:41:45 GMT, Jonathan Gibbons wrote: > Please review a simple change to allow the use of _newline_ _whitespace_ `@` inside inline tags that allow rich content (that is, those parsed with `inlineContent`) as compared to those that only allow plain text (that is, those parsed with `inlineText`). > > The fix is to delete the code which recognizes `@` as the beginning of a block tag. Compare to the similar fix in [JDK-8241780](https://bugs.openjdk.org/browse/JDK-8241780) > > The general `TagTest.java` is updated for the new feature. There's something wrong with this, several `javac/doctree` tests are failing. ------------- PR: https://git.openjdk.org/jdk/pull/12264 From vromero at openjdk.org Tue Jan 31 17:04:28 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 31 Jan 2023 17:04:28 GMT Subject: RFR: 8297158: Suspicious collection method call in Types.isSameTypeVisitor In-Reply-To: References: Message-ID: On Tue, 31 Jan 2023 11:49:41 GMT, Jan Lahoda wrote: > Looks good to me. thanks! ------------- PR: https://git.openjdk.org/jdk/pull/12279 From vromero at openjdk.org Tue Jan 31 17:04:31 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 31 Jan 2023 17:04:31 GMT Subject: Integrated: 8297158: Suspicious collection method call in Types.isSameTypeVisitor In-Reply-To: References: Message-ID: <0UX2gPzQaUlZkcy1_8NqS3IIQEfg_Wnf4EJbiciPSrE=.d98728e9-60b0-4533-9eef-27cd44ab20ca@github.com> On Sun, 29 Jan 2023 02:20:10 GMT, Vicente Romero wrote: > As reported there is a code in `com.sun.tools.javac.code.Types` that was basically a no-op. The code in question is: > > > if (tMap.containsKey(ti)) { > throw new AssertionError("Malformed intersection"); > } > tMap.put(ti.tsym, ti); > > where tMap is defined as: `Map`, but `ti` is a type so the condition, `tMap.containsKey(ti)`, is always false. The assertion should be thrown if an intersection type has two or more repeated interfaces. But there are other places in the compiler where this is checked for and an error is issued if necessary. So it shouldn't be possible to get to this point during a compilation. There are several tests, including combo tests, already stressing this condition, intersection types with repeated interfaces, for this reason there is no need to add more regression tests. > > TIA This pull request has now been integrated. Changeset: 5744c91b Author: Vicente Romero URL: https://git.openjdk.org/jdk/commit/5744c91bf5742379913a9926a5d70a2d49dbea04 Stats: 9 lines in 4 files changed: 0 ins; 3 del; 6 mod 8297158: Suspicious collection method call in Types.isSameTypeVisitor Reviewed-by: jlahoda ------------- PR: https://git.openjdk.org/jdk/pull/12279 From vromero at openjdk.org Tue Jan 31 17:12:07 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 31 Jan 2023 17:12:07 GMT Subject: RFR: 8293519: deprecation warnings should be emitted for uses of annotation methods inside other annotations In-Reply-To: References: Message-ID: On Tue, 31 Jan 2023 11:56:47 GMT, Jan Lahoda wrote: > Seems sensible. Do we need a CSR for this? not sure, probably in the fence, programs compiled with `-Werror` could see new errors but not sure we should have a CSR for that. If we were generating more errors yes sure a CSR but for a new warning, not so sure TBH. If you think we do I will file one though. ------------- PR: https://git.openjdk.org/jdk/pull/12280 From vromero at openjdk.org Tue Jan 31 17:23:28 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 31 Jan 2023 17:23:28 GMT Subject: RFR: 8296010: AssertionError in annotationTargetType [v2] In-Reply-To: References: Message-ID: On Sat, 28 Jan 2023 17:57:53 GMT, Manu Sridharan wrote: >> Vicente Romero has updated the pull request incrementally with one additional commit since the last revision: >> >> updating parameter name > > test/langtools/tools/javac/annotations/crashOnUnknownAttr/CrashOnUnknownTargetTypeTest.java line 10: > >> 8: >> 9: public class CrashOnUnknownTargetTypeTest { >> 10: @A Object o; > > I wonder if it's worth testing the case where the annotation appears on a method as well? We observed crashes before due to that placement as well. It's possible the relevant code paths are shared so an additional test is unnecessary @msridhar thanks for your feedback. Yes we could do that for completeness, probably won't add too much value as the code path is shared, but will take a look at this. Side: did you file any bug on the issue you found? Could you please try this fix on your code base and see if the issue gets fixed? Thanks! ------------- PR: https://git.openjdk.org/jdk/pull/12241 From duke at openjdk.org Tue Jan 31 17:35:25 2023 From: duke at openjdk.org (Manu Sridharan) Date: Tue, 31 Jan 2023 17:35:25 GMT Subject: RFR: 8296010: AssertionError in annotationTargetType [v2] In-Reply-To: References: Message-ID: On Tue, 31 Jan 2023 17:18:56 GMT, Vicente Romero wrote: >> test/langtools/tools/javac/annotations/crashOnUnknownAttr/CrashOnUnknownTargetTypeTest.java line 10: >> >>> 8: >>> 9: public class CrashOnUnknownTargetTypeTest { >>> 10: @A Object o; >> >> I wonder if it's worth testing the case where the annotation appears on a method as well? We observed crashes before due to that placement as well. It's possible the relevant code paths are shared so an additional test is unnecessary > > @msridhar thanks for your feedback. Yes we could do that for completeness, probably won't add too much value as the code path is shared, but will take a look at this. Side: did you file any bug on the issue you found? Could you please try this fix on your code base and see if the issue gets fixed? Thanks! I originally reported https://bugs.openjdk.org/browse/JDK-8295314, which is a bug on JDK 8 triggered when an annotation targets `MODULE`. Then, through discussions with @cushon we realized the same issue is present on the latest JDK when the annotation target is unknown, at which point he reported https://bugs.openjdk.org/browse/JDK-8296010. Trying this patch on my own example may be a bit tricky, since that was related to JDK 8 and I don't have a lot of cycles to look into it right now. If I get time to try something out, I will report back here. ------------- PR: https://git.openjdk.org/jdk/pull/12241 From vromero at openjdk.org Tue Jan 31 18:20:14 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 31 Jan 2023 18:20:14 GMT Subject: RFR: 8296010: AssertionError in annotationTargetType [v2] In-Reply-To: References: Message-ID: On Tue, 31 Jan 2023 17:25:17 GMT, Manu Sridharan wrote: >> @msridhar thanks for your feedback. Yes we could do that for completeness, probably won't add too much value as the code path is shared, but will take a look at this. Side: did you file any bug on the issue you found? Could you please try this fix on your code base and see if the issue gets fixed? Thanks! > > I originally reported https://bugs.openjdk.org/browse/JDK-8295314, which is a bug on JDK 8 triggered when an annotation targets `MODULE`. Then, through discussions with @cushon we realized the same issue is present on the latest JDK when the annotation target is unknown, at which point he reported https://bugs.openjdk.org/browse/JDK-8296010. > > Trying this patch on my own example may be a bit tricky, since that was related to JDK 8 and I don't have a lot of cycles to look into it right now. If I get time to try something out, I will report back here. I see, thanks, yes https://bugs.openjdk.org/browse/JDK-8295314 is definitely a duplicate of this one ------------- PR: https://git.openjdk.org/jdk/pull/12241 From vromero at openjdk.org Tue Jan 31 18:23:46 2023 From: vromero at openjdk.org (Vicente Romero) Date: Tue, 31 Jan 2023 18:23:46 GMT Subject: Integrated: 8293519: deprecation warnings should be emitted for uses of annotation methods inside other annotations In-Reply-To: References: Message-ID: <5rCIBuprE0t0bnnCekvnO8ZEYtJaoY7oKd9J52GcsWA=.60a7ff25-90c9-41ac-aafa-4cca728d3ddc@github.com> On Sun, 29 Jan 2023 04:19:49 GMT, Vicente Romero wrote: > Javac is forgetting to double check if the left hand side in an annotation name-value pair is a deprecated method, basically in this case: > > @interface Anno { > @Deprecated > boolean b() default false; > } > > @Anno(b = true) // a warning should be issued here > class Foo {} > > this PR is fixing this oversight, > > TIA This pull request has now been integrated. Changeset: 6beadbbe Author: Vicente Romero URL: https://git.openjdk.org/jdk/commit/6beadbbe9f0721fbdfc48e6f2c14aa6dab982be0 Stats: 20 lines in 3 files changed: 20 ins; 0 del; 0 mod 8293519: deprecation warnings should be emitted for uses of annotation methods inside other annotations Reviewed-by: jlahoda ------------- PR: https://git.openjdk.org/jdk/pull/12280 From zjx001202 at gmail.com Tue Jan 31 22:17:44 2023 From: zjx001202 at gmail.com (Glavo) Date: Wed, 1 Feb 2023 06:17:44 +0800 Subject: Request to backport fix of JDK-8278834 to Java 17 Message-ID: We encountered a compiler crash for the same reason as JDK-8278834. It has been fixed in Java 18/19, but has not been backported to Java 17. Can anyone do this work? With best regards, Glavo -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Tue Jan 31 22:41:30 2023 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 31 Jan 2023 14:41:30 -0800 Subject: Request to backport fix of JDK-8278834 to Java 17 In-Reply-To: References: Message-ID: On 1/31/2023 2:17 PM, Glavo wrote: > We encountered a compiler crash for the same reason as JDK-8278834. > It has been fixed in Java 18/19, but has not been backported to Java 17. > Can anyone do this work? I looked at https://openjdk.org/projects/jdk-updates/ ("JDK 17 Updates") which sent me to https://wiki.openjdk.org/display/JDKUpdates/JDK+17u The wiki page says: "Should you not be willing or not be able to drive a fix into JDK 17 updates, you can still suggest changes by dropping a mail to the jdk-updates-dev mailing list. But by only doing that, you are at the grace of the community to pick up your suggestion." Alex From zjx001202 at gmail.com Tue Jan 31 23:00:59 2023 From: zjx001202 at gmail.com (Glavo) Date: Wed, 1 Feb 2023 07:00:59 +0800 Subject: Request to backport fix of JDK-8278834 to Java 17 In-Reply-To: References: Message-ID: Thank you for telling me this. I will go there. On Wed, Feb 1, 2023 at 6:41 AM Alex Buckley wrote: > On 1/31/2023 2:17 PM, Glavo wrote: > > We encountered a compiler crash for the same reason as JDK-8278834. > > It has been fixed in Java 18/19, but has not been backported to Java 17. > > Can anyone do this work? > > I looked at https://openjdk.org/projects/jdk-updates/ ("JDK 17 Updates") > which sent me to https://wiki.openjdk.org/display/JDKUpdates/JDK+17u > > The wiki page says: > > "Should you not be willing or not be able to drive a fix into JDK 17 > updates, you can still suggest changes by dropping a mail to the > jdk-updates-dev mailing list. But by only doing that, you are at the > grace of the community to pick up your suggestion." > > Alex > -------------- next part -------------- An HTML attachment was scrubbed... URL: From prappo at openjdk.org Tue Jan 31 23:29:54 2023 From: prappo at openjdk.org (Pavel Rappo) Date: Tue, 31 Jan 2023 23:29:54 GMT Subject: RFR: JDK-8298405: Support Markdown in the standard doclet [v3] In-Reply-To: References: Message-ID: On Tue, 24 Jan 2023 21:43:04 GMT, Jonathan Gibbons wrote: >> Support for Markdown comments in the standard doclet. >> >> To enable Markdown in a comment, start the comment with `/**md` followed by whitespace. The syntax is as defined for CommonMark. >> >> The work is in 3 parts: >> >> 1. Update the Compiler Tree API to support Markdown tree nodes, containing strings of (uninterpreted) Markdown source code. >> 2. Import commonmark-java into the `jdk.javadoc` module, to be able to convert Markdown strings to HTML. >> 3. Update the standard doclet, to leverage the preceding two parts, to translate Markdown in documentation comments to `Content` nodes. >> >> There are new tests both for the low level work in the Compiler Tree API, and for the overall high-level work in the doclet. >> >> Background info: https://mail.openjdk.org/pipermail/javadoc-dev/2023-January/005563.html > > Jonathan Gibbons has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains eight commits: > > - Merge with upstream/master > - Update copyright years > - Rename FFFC variable > Share Markdown parser and renderer in instance of MarkdownHandler > - Move CommonMark to new internal module. > Add legal header to imported CommonMark source files > Always use Text nodes inside AttributeTree values > Unwrap

    from "simple" paragraphs > - Always use Text nodes inside AttributeTree values > - Update to CommonMark 0.21. > - fix whitespace > - JDK-8298405: Markdown support in the standard doclet @wimdeblauwe, not sure if you've noticed it, but your comment was hidden: https://github.com/openjdk/jdk/pull/11701#issuecomment-1399237029. To make the comment visible and response possible, consider accepting TOU suggested by the bot. Thanks. ------------- PR: https://git.openjdk.org/jdk/pull/11701