From 7ac8bf6c751ee7e902a6024d30b8a28ff9b047d3 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Tue, 18 Oct 2016 16:00:32 +0200 Subject: [PATCH 01/79] 8167461: jshell tool: Scanner#next() hangs tool PipeInputStream.read(byte[]...) should only read available bytes; properly resending exceptions for snippet's System.in and properly closing it; more reliable way to cancel user input while waiting in System.in. Reviewed-by: rfield --- .../jshell/tool/ConsoleIOContext.java | 9 +-- .../jdk/internal/jshell/tool/IOContext.java | 2 +- .../share/classes/jdk/jshell/JShell.java | 5 ++ .../jdk/jshell/execution/PipeInputStream.java | 28 +++++++- .../classes/jdk/jshell/execution/Util.java | 60 +++++++++++++++- langtools/test/jdk/jshell/KullaTesting.java | 31 ++++++-- .../test/jdk/jshell/PipeInputStreamTest.java | 71 +++++++++++++++++++ langtools/test/jdk/jshell/UserInputTest.java | 62 +++++++++++++++- 8 files changed, 251 insertions(+), 17 deletions(-) create mode 100644 langtools/test/jdk/jshell/PipeInputStreamTest.java diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java index b4df8efbe54..f11c1beb7cc 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java @@ -31,6 +31,7 @@ import jdk.jshell.SourceCodeAnalysis.Suggestion; import java.awt.event.ActionListener; import java.io.IOException; import java.io.InputStream; +import java.io.InterruptedIOException; import java.io.PrintStream; import java.io.UncheckedIOException; import java.lang.reflect.Method; @@ -390,7 +391,7 @@ class ConsoleIOContext extends IOContext { private int inputBytesPointer; @Override - public synchronized int readUserInput() { + public synchronized int readUserInput() throws IOException { while (inputBytes == null || inputBytes.length <= inputBytesPointer) { boolean prevHandleUserInterrupt = in.getHandleUserInterrupt(); History prevHistory = in.getHistory(); @@ -401,12 +402,8 @@ class ConsoleIOContext extends IOContext { in.setHistory(userInputHistory); inputBytes = (in.readLine("") + System.getProperty("line.separator")).getBytes(); inputBytesPointer = 0; - } catch (IOException ex) { - ex.printStackTrace(); - return -1; } catch (UserInterruptException ex) { - repl.state.stop(); - return -1; + throw new InterruptedIOException(); } finally { in.setHistory(prevHistory); in.setHandleUserInterrupt(prevHandleUserInterrupt); diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java index 4f4a51a44b0..91a2169fcf0 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java @@ -54,7 +54,7 @@ abstract class IOContext implements AutoCloseable { public abstract void replaceLastHistoryEntry(String source); - public abstract int readUserInput(); + public abstract int readUserInput() throws IOException; class InputInterruptedException extends Exception { private static final long serialVersionUID = 1L; diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java index e45ec1b35fd..aa2dfeef901 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java @@ -28,6 +28,7 @@ package jdk.jshell; import jdk.jshell.spi.ExecutionControl; import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.io.InterruptedIOException; import java.io.PrintStream; import java.text.MessageFormat; import java.util.ArrayList; @@ -167,6 +168,10 @@ public class JShell implements AutoCloseable { * user input cannot use {@code System.in} as the input stream for * the remote process. *

+ * The {@code read} method of the {@code InputStream} may throw the {@link InterruptedIOException} + * to signal the user canceled the input. The currently running snippet will be automatically + * {@link JShell#stop() stopped}. + *

* The default, if this is not set, is to provide an empty input stream * -- {@code new ByteArrayInputStream(new byte[0])}. * diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java index 1b582fa9b10..c0553305119 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java @@ -42,7 +42,7 @@ class PipeInputStream extends InputStream { @Override public synchronized int read() throws IOException { - if (start == end) { + if (start == end && !closed) { inputNeeded(); } while (start == end) { @@ -62,6 +62,32 @@ class PipeInputStream extends InputStream { } } + @Override + public synchronized int read(byte[] b, int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (off < 0 || len < 0 || len > b.length - off) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return 0; + } + + int c = read(); + if (c == -1) { + return -1; + } + b[off] = (byte)c; + + int totalRead = 1; + while (totalRead < len && start != end) { + int r = read(); + if (r == (-1)) + break; + b[off + totalRead++] = (byte) r; + } + return totalRead; + } + protected void inputNeeded() throws IOException {} private synchronized void write(int b) { diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java index da8decab065..3ea2975ca56 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java @@ -28,6 +28,7 @@ import jdk.jshell.spi.ExecutionEnv; import java.io.IOException; import java.io.InputStream; +import java.io.InterruptedIOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; @@ -42,6 +43,7 @@ import java.util.function.Consumer; import com.sun.jdi.VirtualMachine; import jdk.jshell.spi.ExecutionControl; +import jdk.jshell.spi.ExecutionControl.ExecutionControlException; /** @@ -54,6 +56,10 @@ import jdk.jshell.spi.ExecutionControl; */ public class Util { + private static final int TAG_DATA = 0; + private static final int TAG_CLOSED = 1; + private static final int TAG_EXCEPTION = 2; + // never instanciated private Util() {} @@ -131,6 +137,25 @@ public class Util { inputSignal.write('1'); inputSignal.flush(); } + @Override + public synchronized int read() throws IOException { + int tag = super.read(); + switch (tag) { + case TAG_DATA: return super.read(); + case TAG_CLOSED: close(); return -1; + case TAG_EXCEPTION: + int len = (super.read() << 0) + (super.read() << 8) + (super.read() << 16) + (super.read() << 24); + byte[] message = new byte[len]; + for (int i = 0; i < len; i++) { + message[i] = (byte) super.read(); + } + throw new IOException(new String(message, "UTF-8")); + case -1: + return -1; + default: + throw new IOException("Internal error: unrecognized message tag: " + tag); + } + } }; inputs.put(e.getKey(), inputPipe.createOutput()); e.getValue().accept(inputPipe); @@ -163,6 +188,7 @@ public class Util { public static ExecutionControl remoteInputOutput(InputStream input, OutputStream output, Map outputStreamMap, Map inputStreamMap, BiFunction factory) throws IOException { + ExecutionControl[] result = new ExecutionControl[1]; Map augmentedStreamMap = new HashMap<>(outputStreamMap); ObjectOutput commandOut = new ObjectOutputStream(Util.multiplexingOutputStream("$command", output)); for (Entry e : inputStreamMap.entrySet()) { @@ -172,7 +198,28 @@ public class Util { @Override public void write(int b) throws IOException { //value ignored, just a trigger to read from the input - inTarget.write(in.read()); + try { + int r = in.read(); + if (r == (-1)) { + inTarget.write(TAG_CLOSED); + } else { + inTarget.write(new byte[] {TAG_DATA, (byte) r}); + } + } catch (InterruptedIOException exc) { + try { + result[0].stop(); + } catch (ExecutionControlException ex) { + debug(ex, "$" + e.getKey() + "-input-requested.write"); + } + } catch (IOException exc) { + byte[] message = exc.getMessage().getBytes("UTF-8"); + inTarget.write(TAG_EXCEPTION); + inTarget.write((message.length >> 0) & 0xFF); + inTarget.write((message.length >> 8) & 0xFF); + inTarget.write((message.length >> 16) & 0xFF); + inTarget.write((message.length >> 24) & 0xFF); + inTarget.write(message); + } } }); } @@ -180,7 +227,7 @@ public class Util { OutputStream commandInTarget = commandIn.createOutput(); augmentedStreamMap.put("$command", commandInTarget); new DemultiplexInput(input, augmentedStreamMap, Arrays.asList(commandInTarget)).start(); - return factory.apply(new ObjectInputStream(commandIn), commandOut); + return result[0] = factory.apply(new ObjectInputStream(commandIn), commandOut); } /** @@ -198,4 +245,13 @@ public class Util { } } + /** + * Log a serious unexpected internal exception. + * + * @param ex the exception + * @param where a description of the context of the exception + */ + private static void debug(Throwable ex, String where) { + // Reserved for future logging + } } diff --git a/langtools/test/jdk/jshell/KullaTesting.java b/langtools/test/jdk/jshell/KullaTesting.java index 1cf81441acb..9e73bd7fcf0 100644 --- a/langtools/test/jdk/jshell/KullaTesting.java +++ b/langtools/test/jdk/jshell/KullaTesting.java @@ -21,7 +21,10 @@ * questions. */ +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; import java.io.PrintStream; import java.io.StringWriter; import java.lang.reflect.Method; @@ -83,7 +86,7 @@ public class KullaTesting { private SourceCodeAnalysis analysis = null; private JShell state = null; - private TestingInputStream inStream = null; + private InputStream inStream = null; private ByteArrayOutputStream outStream = null; private ByteArrayOutputStream errStream = null; @@ -106,7 +109,11 @@ public class KullaTesting { } public void setInput(String s) { - inStream.setInput(s); + setInput(new ByteArrayInputStream(s.getBytes())); + } + + public void setInput(InputStream in) { + inStream = in; } public String getOutput() { @@ -159,11 +166,27 @@ public class KullaTesting { } public void setUp(Consumer bc) { - inStream = new TestingInputStream(); + InputStream in = new InputStream() { + @Override + public int read() throws IOException { + assertNotNull(inStream); + return inStream.read(); + } + @Override + public int read(byte[] b) throws IOException { + assertNotNull(inStream); + return inStream.read(b); + } + @Override + public int read(byte[] b, int off, int len) throws IOException { + assertNotNull(inStream); + return inStream.read(b, off, len); + } + }; outStream = new ByteArrayOutputStream(); errStream = new ByteArrayOutputStream(); JShell.Builder builder = JShell.builder() - .in(inStream) + .in(in) .out(new PrintStream(outStream)) .err(new PrintStream(errStream)); bc.accept(builder); diff --git a/langtools/test/jdk/jshell/PipeInputStreamTest.java b/langtools/test/jdk/jshell/PipeInputStreamTest.java new file mode 100644 index 00000000000..c062028e3ba --- /dev/null +++ b/langtools/test/jdk/jshell/PipeInputStreamTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test 8167461 + * @summary Verify PipeInputStream works. + * @modules jdk.compiler/com.sun.tools.javac.util + * jdk.jshell + * @run testng PipeInputStreamTest + */ + +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +import org.testng.annotations.Test; + +import com.sun.tools.javac.util.Pair; + +import static org.testng.Assert.*; + +@Test +public class PipeInputStreamTest { + + public void testReadArrayNotBlocking() throws Exception { + Pair streams = createPipeStream(); + InputStream in = streams.fst; + OutputStream out = streams.snd; + out.write('a'); + byte[] data = new byte[12]; + assertEquals(in.read(data), 1); + assertEquals(data[0], 'a'); + out.write('a'); out.write('b'); out.write('c'); + assertEquals(in.read(data), 3); + assertEquals(data[0], 'a'); + assertEquals(data[1], 'b'); + assertEquals(data[2], 'c'); + } + + private Pair createPipeStream() throws Exception { + Class pipeStreamClass = Class.forName("jdk.jshell.execution.PipeInputStream"); + Constructor c = pipeStreamClass.getDeclaredConstructor(); + c.setAccessible(true); + Object pipeStream = c.newInstance(); + Method createOutputStream = pipeStreamClass.getDeclaredMethod("createOutput"); + createOutputStream.setAccessible(true); + return Pair.of((InputStream) pipeStream, (OutputStream) createOutputStream.invoke(pipeStream)); + } + +} diff --git a/langtools/test/jdk/jshell/UserInputTest.java b/langtools/test/jdk/jshell/UserInputTest.java index 5289ab7c56b..41221c009dc 100644 --- a/langtools/test/jdk/jshell/UserInputTest.java +++ b/langtools/test/jdk/jshell/UserInputTest.java @@ -23,12 +23,15 @@ /* * @test - * @bug 8131023 + * @bug 8131023 8167461 * @summary Verify that the user's code can read System.in * @build KullaTesting TestingInputStream * @run testng UserInputTest */ +import java.io.IOException; +import java.io.InputStream; + import org.testng.annotations.Test; @Test @@ -37,8 +40,61 @@ public class UserInputTest extends KullaTesting { public void testReadInput() { setInput("AB\n"); assertEval("System.in.read()", "65"); - setInput("BC\n"); - assertEval("System.in.read()", "66"); + setInput("CD\n"); + assertEval("System.in.read()", "67"); } + public void testScanner() { + assertEval("import java.util.Scanner;"); + assertEval("Scanner s = new Scanner(System.in);"); + setInput("12\n"); + assertEval("s.nextInt();", "12"); + } + + public void testClose() { + setInput(new InputStream() { + private final byte[] data = new byte[] {0, 1, 2}; + private int cursor; + @Override public int read() throws IOException { + if (cursor < data.length) { + return data[cursor++]; + } else { + return -1; + } + } + }); + assertEval("int read;", "0"); + assertEval("System.in.read();", "0"); + assertEval("System.in.read();", "1"); + assertEval("System.in.read();", "2"); + assertEval("System.in.read();", "-1"); + assertEval("System.in.read();", "-1"); + assertEval("System.in.read();", "-1"); + } + + public void testException() { + setInput(new InputStream() { + private final int[] data = new int[] {0, 1, -2, 2}; + private int cursor; + @Override public int read() throws IOException { + if (cursor < data.length) { + int d = data[cursor++]; + if (d == (-2)) { + throw new IOException("Crashed"); + } + return d; + } else { + return -1; + } + } + }); + assertEval("int read;", "0"); + assertEval("System.in.read();", "0"); + assertEval("System.in.read();", "1"); + assertEval("java.io.IOException e;"); + assertEval("try { System.in.read(); } catch (java.io.IOException exc) { e = exc; }"); + assertEval("e", "java.io.IOException: Crashed"); + assertEval("System.in.read();", "2"); + assertEval("System.in.read();", "-1"); + } } From d13040370481e50572140498c8d7292040b1b94e Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Wed, 2 Mar 2016 18:25:01 -0500 Subject: [PATCH 02/79] 8026721: Enhance Lambda serialization Reviewed-by: jjg, briangoetz --- .../com/sun/tools/javac/comp/Attr.java | 7 +- .../com/sun/tools/javac/comp/AttrContext.java | 10 ++- .../com/sun/tools/javac/comp/Check.java | 32 ++++++++-- .../tools/javac/resources/compiler.properties | 8 ++- .../tools/javac/resources/javac.properties | 3 +- ....java => WarnSerializableElementTest.java} | 64 +++++++++---------- .../T8029102/WarnSerializableElementTest.out | 35 ++++++++++ .../T8029102/WarnSerializableLambdaTest.out | 57 ----------------- .../T8029102/WarnSerializableLambdaTestb.java | 2 +- .../T8029102/WarnSerializableLambdaTestb.out | 8 +-- .../T8029102/WarnSerializableLambdaTestc.java | 20 ++++++ .../T8029102/WarnSerializableLambdaTestc.out | 4 ++ .../tools/javac/diags/CheckResourceKeys.java | 2 + .../tools/javac/diags/examples.not-yet.txt | 1 + .../examples/WarnSerializableLambda.java | 21 +++--- 15 files changed, 155 insertions(+), 119 deletions(-) rename langtools/test/tools/javac/T8029102/{WarnSerializableLambdaTest.java => WarnSerializableElementTest.java} (71%) create mode 100644 langtools/test/tools/javac/T8029102/WarnSerializableElementTest.out delete mode 100644 langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out create mode 100644 langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.java create mode 100644 langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.out diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 2743702d11d..3aee3c44504 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2398,6 +2398,7 @@ public class Attr extends JCTree.Visitor { try { if (needsRecovery && isSerializable(pt())) { localEnv.info.isSerializable = true; + localEnv.info.isLambda = true; } List explicitParamTypes = null; if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) { @@ -2969,7 +2970,7 @@ public class Attr extends JCTree.Visitor { } if (isTargetSerializable) { - chk.checkElemAccessFromSerializableLambda(that); + chk.checkAccessFromSerializableElement(that, true); } } @@ -3364,7 +3365,7 @@ public class Attr extends JCTree.Visitor { } if (env.info.isSerializable) { - chk.checkElemAccessFromSerializableLambda(tree); + chk.checkAccessFromSerializableElement(tree, env.info.isLambda); } result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo); @@ -3507,7 +3508,7 @@ public class Attr extends JCTree.Visitor { } if (env.info.isSerializable) { - chk.checkElemAccessFromSerializableLambda(tree); + chk.checkAccessFromSerializableElement(tree, env.info.isLambda); } env.info.selectSuper = selectSuperPrev; diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java index 368efd19db1..573e8948136 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,10 +56,15 @@ public class AttrContext { */ boolean selectSuper = false; - /** Is the current target of lambda expression or method reference serializable? + /** Is the current target of lambda expression or method reference serializable or is this a + * serializable class? */ boolean isSerializable = false; + /** Is this a lambda environment? + */ + boolean isLambda = false; + /** Is this a speculative attribution environment? */ boolean isSpeculative = false; @@ -117,6 +122,7 @@ public class AttrContext { info.returnResult = returnResult; info.defaultSuperCallSite = defaultSuperCallSite; info.isSerializable = isSerializable; + info.isLambda = isLambda; info.isSpeculative = isSpeculative; info.isAnonymousDiamond = isAnonymousDiamond; info.isNewClass = isNewClass; diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java index 1a774450eac..038326f974f 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java @@ -87,7 +87,7 @@ public class Check { private final JavaFileManager fileManager; private final Source source; private final Profile profile; - private final boolean warnOnAccessToSensitiveMembers; + private final boolean warnOnAnyAccessToMembers; // The set of lint options currently in effect. It is initialized // from the context, and then is set/reset as needed by Attr as it @@ -131,7 +131,7 @@ public class Check { allowStrictMethodClashCheck = source.allowStrictMethodClashCheck(); allowPrivateSafeVarargs = source.allowPrivateSafeVarargs(); allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation(); - warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers"); + warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers"); Target target = Target.instance(context); syntheticNameChar = target.syntheticNameChar(); @@ -2605,8 +2605,11 @@ public class Check { } } - void checkElemAccessFromSerializableLambda(final JCTree tree) { - if (warnOnAccessToSensitiveMembers) { + void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) { + if (warnOnAnyAccessToMembers || + (lint.isEnabled(LintCategory.SERIAL) && + !lint.isSuppressed(LintCategory.SERIAL) && + isLambda)) { Symbol sym = TreeInfo.symbol(tree); if (!sym.kind.matches(KindSelector.VAL_MTH)) { return; @@ -2622,9 +2625,16 @@ public class Check { } if (!types.isSubtype(sym.owner.type, syms.serializableType) && - isEffectivelyNonPublic(sym)) { - log.warning(tree.pos(), - "access.to.sensitive.member.from.serializable.element", sym); + isEffectivelyNonPublic(sym)) { + if (isLambda) { + if (belongsToRestrictedPackage(sym)) { + log.warning(LintCategory.SERIAL, tree.pos(), + "access.to.member.from.serializable.lambda", sym); + } + } else { + log.warning(tree.pos(), + "access.to.member.from.serializable.element", sym); + } } } } @@ -2643,6 +2653,14 @@ public class Check { return false; } + private boolean belongsToRestrictedPackage(Symbol sym) { + String fullName = sym.packge().fullname.toString(); + return fullName.startsWith("java.") || + fullName.startsWith("javax.") || + fullName.startsWith("sun.") || + fullName.contains(".internal."); + } + /** Report a conflict between a user symbol and a synthetic symbol. */ private void syntheticError(DiagnosticPosition pos, Symbol sym) { diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index f183212aa70..152c94d0f5a 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1712,8 +1712,12 @@ compiler.warn.varargs.redundant.trustme.anno=\ Redundant {0} annotation. {1} # 0: symbol -compiler.warn.access.to.sensitive.member.from.serializable.element=\ - access to sensitive member {0} from serializable element can be publicly accessible to untrusted code +compiler.warn.access.to.member.from.serializable.element=\ + access to member {0} from serializable element can be publicly accessible to untrusted code + +# 0: symbol +compiler.warn.access.to.member.from.serializable.lambda=\ + access to member {0} from serializable lambda can be publicly accessible to untrusted code ##### diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties index 44634e703e0..93f34ce7d1e 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties @@ -220,7 +220,8 @@ javac.opt.Xlint.desc.rawtypes=\ Warn about use of raw types. javac.opt.Xlint.desc.serial=\ - Warn about Serializable classes that do not provide a serial version ID. + Warn about Serializable classes that do not provide a serial version ID. \n\ +\ Also warn about access to non-public members from a serializable element. javac.opt.Xlint.desc.static=\ Warn about accessing a static member using an instance. diff --git a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java b/langtools/test/tools/javac/T8029102/WarnSerializableElementTest.java similarity index 71% rename from langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java rename to langtools/test/tools/javac/T8029102/WarnSerializableElementTest.java index ac377a93c3c..7f190fca10f 100644 --- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java +++ b/langtools/test/tools/javac/T8029102/WarnSerializableElementTest.java @@ -4,36 +4,36 @@ * @summary Enhance compiler warnings for Lambda * Checks that the warning for accessing non public members of a class is * fired correctly. - * @compile/fail/ref=WarnSerializableLambdaTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTest.java + * @compile/fail/ref=WarnSerializableElementTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToMembers WarnSerializableElementTest.java */ import java.io.Serializable; -public class WarnSerializableLambdaTest { +public class WarnSerializableElementTest { void warnLambda() throws Exception { - SAM t3 = (SAM & Serializable)WarnSerializableLambdaTest::packageClassMethod; - SAM t4 = (SAM & Serializable)WarnSerializableLambdaTest::protectedClassMethod; - SAM t5 = (SAM & Serializable)WarnSerializableLambdaTest::privateClassMethod; + SAM t3 = (SAM & Serializable)WarnSerializableElementTest::packageClassMethod; + SAM t4 = (SAM & Serializable)WarnSerializableElementTest::protectedClassMethod; + SAM t5 = (SAM & Serializable)WarnSerializableElementTest::privateClassMethod; - WarnSerializableLambdaTest test = new WarnSerializableLambdaTest(); + WarnSerializableElementTest test = new WarnSerializableElementTest(); SAM t6 = (SAM & Serializable)test::packageInstanceMethod; SAM t7 = (SAM & Serializable)test::protectedInstanceMethod; SAM t8 = (SAM & Serializable)test::privateInstanceMethod; SAM t9 = (SAM & Serializable) c -> { - WarnSerializableLambdaTest.staticPackageField = ""; - WarnSerializableLambdaTest.staticProtectedField = ""; - WarnSerializableLambdaTest.staticPrivateField = ""; + WarnSerializableElementTest.staticPackageField = ""; + WarnSerializableElementTest.staticProtectedField = ""; + WarnSerializableElementTest.staticPrivateField = ""; packageField = ""; protectedField = ""; privateField = ""; - WarnSerializableLambdaTest.packageClassMethod(null); - WarnSerializableLambdaTest.protectedClassMethod(null); - WarnSerializableLambdaTest.privateClassMethod(null); + WarnSerializableElementTest.packageClassMethod(null); + WarnSerializableElementTest.protectedClassMethod(null); + WarnSerializableElementTest.privateClassMethod(null); packageInstanceMethod(null); protectedInstanceMethod(null); @@ -53,17 +53,17 @@ public class WarnSerializableLambdaTest { private void warnAnoInnerClass() throws Exception { new SerializableDesc() { public void m(Object param) throws Exception { - WarnSerializableLambdaTest.staticPackageField = ""; - WarnSerializableLambdaTest.staticProtectedField = ""; - WarnSerializableLambdaTest.staticPrivateField = ""; + WarnSerializableElementTest.staticPackageField = ""; + WarnSerializableElementTest.staticProtectedField = ""; + WarnSerializableElementTest.staticPrivateField = ""; packageField = ""; protectedField = ""; privateField = ""; - WarnSerializableLambdaTest.packageClassMethod(null); - WarnSerializableLambdaTest.protectedClassMethod(null); - WarnSerializableLambdaTest.privateClassMethod(null); + WarnSerializableElementTest.packageClassMethod(null); + WarnSerializableElementTest.protectedClassMethod(null); + WarnSerializableElementTest.privateClassMethod(null); packageInstanceMethod(null); protectedInstanceMethod(null); @@ -80,9 +80,9 @@ public class WarnSerializableLambdaTest { } void dontWarnLambda() throws Exception { - SAM t1 = (SAM & Serializable)WarnSerializableLambdaTest::publicClassMethod; + SAM t1 = (SAM & Serializable)WarnSerializableElementTest::publicClassMethod; - WarnSerializableLambdaTest test = new WarnSerializableLambdaTest(); + WarnSerializableElementTest test = new WarnSerializableElementTest(); SAM t2 = (SAM & Serializable)test::publicInstanceMethod; int[] buffer = {0}; @@ -92,9 +92,9 @@ public class WarnSerializableLambdaTest { localVar = null; param = null; - WarnSerializableLambdaTest.staticPublicField = ""; + WarnSerializableElementTest.staticPublicField = ""; publicField = ""; - WarnSerializableLambdaTest.publicClassMethod(null); + WarnSerializableElementTest.publicClassMethod(null); publicInstanceMethod(null); PublicClass.effectivelyPublicStaticField = ""; @@ -118,9 +118,9 @@ public class WarnSerializableLambdaTest { localVar = null; param = null; - WarnSerializableLambdaTest.staticPublicField = ""; + WarnSerializableElementTest.staticPublicField = ""; publicField = ""; - WarnSerializableLambdaTest.publicClassMethod(null); + WarnSerializableElementTest.publicClassMethod(null); publicInstanceMethod(null); PublicClass.effectivelyPublicStaticField = ""; @@ -138,20 +138,20 @@ public class WarnSerializableLambdaTest { enum WarnEnum { A { public void m() throws Exception { - WarnSerializableLambdaTest.staticPackageField = ""; - WarnSerializableLambdaTest.staticProtectedField = ""; - WarnSerializableLambdaTest.staticPrivateField = ""; + WarnSerializableElementTest.staticPackageField = ""; + WarnSerializableElementTest.staticProtectedField = ""; + WarnSerializableElementTest.staticPrivateField = ""; - WarnSerializableLambdaTest test = - new WarnSerializableLambdaTest(); + WarnSerializableElementTest test = + new WarnSerializableElementTest(); test.packageField = ""; test.protectedField = ""; test.privateField = ""; - WarnSerializableLambdaTest.packageClassMethod(null); - WarnSerializableLambdaTest.protectedClassMethod(null); - WarnSerializableLambdaTest.privateClassMethod(null); + WarnSerializableElementTest.packageClassMethod(null); + WarnSerializableElementTest.protectedClassMethod(null); + WarnSerializableElementTest.privateClassMethod(null); test.packageInstanceMethod(null); test.protectedInstanceMethod(null); diff --git a/langtools/test/tools/javac/T8029102/WarnSerializableElementTest.out b/langtools/test/tools/javac/T8029102/WarnSerializableElementTest.out new file mode 100644 index 00000000000..3328e4a0e3c --- /dev/null +++ b/langtools/test/tools/javac/T8029102/WarnSerializableElementTest.out @@ -0,0 +1,35 @@ +WarnSerializableElementTest.java:56:44: compiler.warn.access.to.member.from.serializable.element: staticPackageField +WarnSerializableElementTest.java:57:44: compiler.warn.access.to.member.from.serializable.element: staticProtectedField +WarnSerializableElementTest.java:58:44: compiler.warn.access.to.member.from.serializable.element: staticPrivateField +WarnSerializableElementTest.java:60:17: compiler.warn.access.to.member.from.serializable.element: packageField +WarnSerializableElementTest.java:61:17: compiler.warn.access.to.member.from.serializable.element: protectedField +WarnSerializableElementTest.java:62:17: compiler.warn.access.to.member.from.serializable.element: privateField +WarnSerializableElementTest.java:64:44: compiler.warn.access.to.member.from.serializable.element: packageClassMethod(java.lang.String) +WarnSerializableElementTest.java:65:44: compiler.warn.access.to.member.from.serializable.element: protectedClassMethod(java.lang.String) +WarnSerializableElementTest.java:66:44: compiler.warn.access.to.member.from.serializable.element: privateClassMethod(java.lang.String) +WarnSerializableElementTest.java:68:17: compiler.warn.access.to.member.from.serializable.element: packageInstanceMethod(java.lang.String) +WarnSerializableElementTest.java:69:17: compiler.warn.access.to.member.from.serializable.element: protectedInstanceMethod(java.lang.String) +WarnSerializableElementTest.java:70:17: compiler.warn.access.to.member.from.serializable.element: privateInstanceMethod(java.lang.String) +WarnSerializableElementTest.java:72:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicStaticField +WarnSerializableElementTest.java:73:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicClassMethod() +WarnSerializableElementTest.java:76:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceField +WarnSerializableElementTest.java:77:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceMethod() +WarnSerializableElementTest.java:141:44: compiler.warn.access.to.member.from.serializable.element: staticPackageField +WarnSerializableElementTest.java:142:44: compiler.warn.access.to.member.from.serializable.element: staticProtectedField +WarnSerializableElementTest.java:143:44: compiler.warn.access.to.member.from.serializable.element: staticPrivateField +WarnSerializableElementTest.java:148:21: compiler.warn.access.to.member.from.serializable.element: packageField +WarnSerializableElementTest.java:149:21: compiler.warn.access.to.member.from.serializable.element: protectedField +WarnSerializableElementTest.java:150:21: compiler.warn.access.to.member.from.serializable.element: privateField +WarnSerializableElementTest.java:152:44: compiler.warn.access.to.member.from.serializable.element: packageClassMethod(java.lang.String) +WarnSerializableElementTest.java:153:44: compiler.warn.access.to.member.from.serializable.element: protectedClassMethod(java.lang.String) +WarnSerializableElementTest.java:154:44: compiler.warn.access.to.member.from.serializable.element: privateClassMethod(java.lang.String) +WarnSerializableElementTest.java:156:21: compiler.warn.access.to.member.from.serializable.element: packageInstanceMethod(java.lang.String) +WarnSerializableElementTest.java:157:21: compiler.warn.access.to.member.from.serializable.element: protectedInstanceMethod(java.lang.String) +WarnSerializableElementTest.java:158:21: compiler.warn.access.to.member.from.serializable.element: privateInstanceMethod(java.lang.String) +WarnSerializableElementTest.java:160:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicStaticField +WarnSerializableElementTest.java:161:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicClassMethod() +WarnSerializableElementTest.java:164:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceField +WarnSerializableElementTest.java:165:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceMethod() +- compiler.err.warnings.and.werror +1 error +32 warnings diff --git a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out deleted file mode 100644 index 4b1e75430fd..00000000000 --- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out +++ /dev/null @@ -1,57 +0,0 @@ -WarnSerializableLambdaTest.java:15:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:16:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:17:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:20:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:21:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:22:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:26:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField -WarnSerializableLambdaTest.java:27:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField -WarnSerializableLambdaTest.java:28:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField -WarnSerializableLambdaTest.java:30:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField -WarnSerializableLambdaTest.java:31:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField -WarnSerializableLambdaTest.java:32:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField -WarnSerializableLambdaTest.java:34:39: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:35:39: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:36:39: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:38:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:39:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:40:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:42:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField -WarnSerializableLambdaTest.java:43:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod() -WarnSerializableLambdaTest.java:46:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField -WarnSerializableLambdaTest.java:47:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod() -WarnSerializableLambdaTest.java:56:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField -WarnSerializableLambdaTest.java:57:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField -WarnSerializableLambdaTest.java:58:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField -WarnSerializableLambdaTest.java:60:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField -WarnSerializableLambdaTest.java:61:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField -WarnSerializableLambdaTest.java:62:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField -WarnSerializableLambdaTest.java:64:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:65:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:66:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:68:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:69:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:70:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:72:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField -WarnSerializableLambdaTest.java:73:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod() -WarnSerializableLambdaTest.java:76:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField -WarnSerializableLambdaTest.java:77:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod() -WarnSerializableLambdaTest.java:141:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField -WarnSerializableLambdaTest.java:142:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField -WarnSerializableLambdaTest.java:143:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField -WarnSerializableLambdaTest.java:148:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField -WarnSerializableLambdaTest.java:149:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField -WarnSerializableLambdaTest.java:150:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField -WarnSerializableLambdaTest.java:152:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:153:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:154:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String) -WarnSerializableLambdaTest.java:156:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:157:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:158:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String) -WarnSerializableLambdaTest.java:160:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField -WarnSerializableLambdaTest.java:161:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod() -WarnSerializableLambdaTest.java:164:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField -WarnSerializableLambdaTest.java:165:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod() -- compiler.err.warnings.and.werror -1 error -54 warnings diff --git a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java index 6a8a4ab664a..a18fe07a2bf 100644 --- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java +++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java @@ -4,7 +4,7 @@ * @summary Enhance compiler warnings for Lambda * Checks that the warning for accessing non public members of a class is * fired correctly. - * @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTestb.java + * @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToMembers WarnSerializableLambdaTestb.java */ import java.io.Serializable; diff --git a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out index 1aaf1e11072..e672baf6db6 100644 --- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out +++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out @@ -1,7 +1,5 @@ -WarnSerializableLambdaTestb.java:14:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test() -WarnSerializableLambdaTestb.java:18:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test() -WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.sensitive.member.from.serializable.element: j -WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.sensitive.member.from.serializable.element: r +WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.member.from.serializable.element: j +WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.member.from.serializable.element: r - compiler.err.warnings.and.werror 1 error -4 warnings +2 warnings diff --git a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.java b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.java new file mode 100644 index 00000000000..7e1985cacbf --- /dev/null +++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.java @@ -0,0 +1,20 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8026721 + * @summary Enhance Lambda serialization + * Checks that the warning for accessing non public members of a class is fired correctly. + * @compile -Xlint:serial -Werror WarnSerializableLambdaTestc.java + */ + +import javax.tools.SimpleJavaFileObject; +import java.io.Serializable; + +public class WarnSerializableLambdaTestc { + public interface SerializableIntf extends Serializable { + String get(T o); + } + + private void dontWarn() { + SerializableIntf s = SimpleJavaFileObject::getName; + } +} diff --git a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.out b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.out new file mode 100644 index 00000000000..d618d566c5e --- /dev/null +++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.out @@ -0,0 +1,4 @@ +WarnSerializableLambdaTestc.java:18:52: compiler.warn.access.to.member.from.serializable.lambda +- compiler.err.warnings.and.werror +1 error +1 warning diff --git a/langtools/test/tools/javac/diags/CheckResourceKeys.java b/langtools/test/tools/javac/diags/CheckResourceKeys.java index dde2681054b..2c96e3f2fdd 100644 --- a/langtools/test/tools/javac/diags/CheckResourceKeys.java +++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java @@ -257,6 +257,8 @@ public class CheckResourceKeys { // ignore package and class names if (cs.matches("(com|java|javax|jdk|sun)\\.[A-Za-z.]+")) continue; + if (cs.matches("(java|javax|sun)\\.")) + continue; // ignore debug flag names if (cs.startsWith("debug.")) continue; diff --git a/langtools/test/tools/javac/diags/examples.not-yet.txt b/langtools/test/tools/javac/diags/examples.not-yet.txt index fbce60ff50c..a2018762ca8 100644 --- a/langtools/test/tools/javac/diags/examples.not-yet.txt +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt @@ -111,6 +111,7 @@ compiler.warn.file.from.future # warning for future mod compiler.err.cant.inherit.from.anon # error for subclass of anonymous class compiler.misc.bad.class.file # class file is malformed compiler.misc.bad.const.pool.entry # constant pool entry has wrong type +compiler.warn.access.to.member.from.serializable.lambda # in order to generate it we need to modify a restricted package # The following module-related messages will have to stay on the not-yet list for various reasons: compiler.warn.locn.unknown.file.on.module.path # Never issued ATM (short circuited with an if (false)) diff --git a/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java b/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java index a1a63d5cd68..1fc49a1c175 100644 --- a/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java +++ b/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,21 +21,24 @@ * questions. */ -// key: compiler.warn.access.to.sensitive.member.from.serializable.element -// options: -XDwarnOnAccessToSensitiveMembers +// key: compiler.warn.access.to.member.from.serializable.element +// options: -XDwarnOnAccessToMembers import java.io.Serializable; public class WarnSerializableLambda { - interface SAM { - void apply(String s); - } - private void m1() { - SAM s = (SAM & Serializable) c -> { - packageField = ""; + new SerializableClass() { + @Override + public void m() { + packageField = ""; + } }; } String packageField; + + class SerializableClass implements Serializable { + public void m() {} + } } From 065f9a3a4eb8a5081ae2175e5bca5eaf9681fb74 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Thu, 12 May 2016 17:37:45 -0400 Subject: [PATCH 03/79] 8156794: Extend data sharing Reviewed-by: iklam, hseigel, acorn, mschoene --- hotspot/src/share/vm/runtime/arguments.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 8017e73a4ea..5b3e570e425 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -3899,6 +3899,13 @@ jint Arguments::parse_options_buffer(const char* name, char* buffer, const size_ void Arguments::set_shared_spaces_flags() { if (DumpSharedSpaces) { + if (FailOverToOldVerifier) { + // Don't fall back to the old verifier on verification failure. If a + // class fails verification with the split verifier, it might fail the + // CDS runtime verifier constraint check. In that case, we don't want + // to share the class. We only archive classes that pass the split verifier. + FLAG_SET_DEFAULT(FailOverToOldVerifier, false); + } if (RequireSharedSpaces) { warning("Cannot dump shared archive while using shared archive"); From 656510aa27f80256e03de71fe5d5e678ab0ee813 Mon Sep 17 00:00:00 2001 From: Gerard Ziemski Date: Thu, 9 Jun 2016 13:47:15 -0500 Subject: [PATCH 04/79] 8155968: Update command line options Reviewed-by: gthornbr, hseigel, mschoene --- hotspot/src/share/vm/runtime/arguments.cpp | 43 ++++++++++++---------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 5b3e570e425..cdd3559fda1 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -794,9 +794,10 @@ static bool append_to_string_flag(const char* name, const char* new_value, Flag: } else if (new_len == 0) { value = old_value; } else { - char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1, mtArguments); + size_t length = old_len + 1 + new_len + 1; + char* buf = NEW_C_HEAP_ARRAY(char, length, mtArguments); // each new setting adds another LINE to the switch: - sprintf(buf, "%s\n%s", old_value, new_value); + jio_snprintf(buf, length, "%s\n%s", old_value, new_value); value = buf; free_this_too = buf; } @@ -1014,15 +1015,17 @@ const char* Arguments::build_resource_string(char** args, int count) { if (args == NULL || count == 0) { return NULL; } - size_t length = strlen(args[0]) + 1; // add 1 for the null terminator - for (int i = 1; i < count; i++) { - length += strlen(args[i]) + 1; // add 1 for a space + size_t length = 0; + for (int i = 0; i < count; i++) { + length += strlen(args[i]) + 1; // add 1 for a space or NULL terminating character } char* s = NEW_RESOURCE_ARRAY(char, length); - strcpy(s, args[0]); - for (int j = 1; j < count; j++) { - strcat(s, " "); - strcat(s, args[j]); + char* dst = s; + for (int j = 0; j < count; j++) { + size_t offset = strlen(args[j]) + 1; // add 1 for a space or NULL terminating character + jio_snprintf(dst, length, "%s ", args[j]); // jio_snprintf will replace the last space character with NULL character + dst += offset; + length -= offset; } return (const char*) s; } @@ -1106,9 +1109,8 @@ bool Arguments::process_argument(const char* arg, // Only make the obsolete check for valid arguments. if (arg_len <= BUFLEN) { // Construct a string which consists only of the argument name without '+', '-', or '='. - char stripped_argname[BUFLEN+1]; - strncpy(stripped_argname, argname, arg_len); - stripped_argname[arg_len] = '\0'; // strncpy may not null terminate. + char stripped_argname[BUFLEN+1]; // +1 for '\0' + jio_snprintf(stripped_argname, arg_len+1, "%s", argname); // +1 for '\0' if (is_obsolete_flag(stripped_argname, &since)) { char version[256]; since.to_string(version, sizeof(version)); @@ -1260,8 +1262,7 @@ bool Arguments::add_property(const char* prop, PropertyWriteable writeable, Prop size_t key_len = eq - prop; char* tmp_key = AllocateHeap(key_len + 1, mtArguments); - strncpy(tmp_key, prop, key_len); - tmp_key[key_len] = '\0'; + jio_snprintf(tmp_key, key_len + 1, "%s", prop); key = tmp_key; value = &prop[key_len + 1]; @@ -2256,7 +2257,7 @@ jint Arguments::set_aggressive_opts_flags() { // Feed the cache size setting into the JDK char buffer[1024]; - sprintf(buffer, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax); + jio_snprintf(buffer, 1024, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax); if (!add_property(buffer)) { return JNI_ENOMEM; } @@ -2777,8 +2778,8 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m if (tail != NULL) { const char* pos = strchr(tail, ':'); size_t len = (pos == NULL) ? strlen(tail) : pos - tail; - char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len); - name[len] = '\0'; + char* name = NEW_C_HEAP_ARRAY(char, len + 1, mtArguments); + jio_snprintf(name, len + 1, "%s", tail); char *options = NULL; if(pos != NULL) { @@ -2854,7 +2855,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m return JNI_ERR; #else if (tail != NULL) { - char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtArguments), tail); + size_t length = strlen(tail) + 1; + char *options = NEW_C_HEAP_ARRAY(char, length, mtArguments); + jio_snprintf(options, length, "%s", tail); add_init_agent("instrument", options, false); // java agents need module java.instrument if (!create_numbered_property("jdk.module.addmods", "java.instrument", addmods_count++)) { @@ -3512,7 +3515,7 @@ jint Arguments::finalize_vm_init_args() { // check if the default lib/endorsed directory exists; if so, error char path[JVM_MAXPATHLEN]; const char* fileSep = os::file_separator(); - sprintf(path, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep); + jio_snprintf(path, JVM_MAXPATHLEN, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep); if (CheckEndorsedAndExtDirs) { int nonEmptyDirs = 0; @@ -3534,7 +3537,7 @@ jint Arguments::finalize_vm_init_args() { return JNI_ERR; } - sprintf(path, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep); + jio_snprintf(path, JVM_MAXPATHLEN, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep); dir = os::opendir(path); if (dir != NULL) { jio_fprintf(defaultStream::output_stream(), From c6d2422f35600e8575a3077108f883c7202d830c Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 29 Jun 2016 11:52:27 -0400 Subject: [PATCH 05/79] 8159515: Improve indy validation Reviewed-by: jrose, hseigel, vlivanov, bmoloden, ctornqvi, mschoene --- hotspot/src/share/vm/prims/jvm.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index 23575de98a8..f4816e63230 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -2524,7 +2524,6 @@ JVM_ENTRY(const char*, JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cls, jint cp_i switch (cp->tag_at(cp_index).value()) { case JVM_CONSTANT_InterfaceMethodref: case JVM_CONSTANT_Methodref: - case JVM_CONSTANT_NameAndType: // for invokedynamic return cp->uncached_name_ref_at(cp_index)->as_utf8(); default: fatal("JVM_GetCPMethodNameUTF: illegal constant"); @@ -2542,7 +2541,6 @@ JVM_ENTRY(const char*, JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cls, jint switch (cp->tag_at(cp_index).value()) { case JVM_CONSTANT_InterfaceMethodref: case JVM_CONSTANT_Methodref: - case JVM_CONSTANT_NameAndType: // for invokedynamic return cp->uncached_signature_ref_at(cp_index)->as_utf8(); default: fatal("JVM_GetCPMethodSignatureUTF: illegal constant"); From 5f49daa2c47548de83ec165188435bb113aed3e6 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Thu, 30 Jun 2016 08:11:30 -0400 Subject: [PATCH 06/79] 8159511: Stack map validation Reviewed-by: acorn, mschoene --- .../vm/classfile/stackMapTableFormat.hpp | 39 ++++++++++++++++++- hotspot/src/share/vm/classfile/verifier.cpp | 11 ++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp b/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp index 8bfa625ca3f..469a6b5adca 100644 --- a/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp +++ b/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -203,6 +203,7 @@ class stack_map_frame { inline bool verify(address start, address end) const; inline void print_on(outputStream* st, int current_offset) const; + inline void print_truncated(outputStream* st, int current_offset) const; // Create as_xxx and is_xxx methods for the subtypes #define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \ @@ -263,6 +264,10 @@ class same_frame : public stack_map_frame { void print_on(outputStream* st, int current_offset = -1) const { st->print("same_frame(@%d)", offset_delta() + current_offset); } + + void print_truncated(outputStream* st, int current_offset = -1) const { + print_on(st, current_offset); + } }; class same_frame_extended : public stack_map_frame { @@ -309,6 +314,10 @@ class same_frame_extended : public stack_map_frame { void print_on(outputStream* st, int current_offset = -1) const { st->print("same_frame_extended(@%d)", offset_delta() + current_offset); } + + void print_truncated(outputStream* st, int current_offset = -1) const { + print_on(st, current_offset); + } }; class same_locals_1_stack_item_frame : public stack_map_frame { @@ -381,6 +390,11 @@ class same_locals_1_stack_item_frame : public stack_map_frame { types()->print_on(st); st->print(")"); } + + void print_truncated(outputStream* st, int current_offset = -1) const { + st->print("same_locals_1_stack_item_frame(@%d), output truncated, Stackmap exceeds table size.", + offset_delta() + current_offset); + } }; class same_locals_1_stack_item_extended : public stack_map_frame { @@ -446,6 +460,11 @@ class same_locals_1_stack_item_extended : public stack_map_frame { types()->print_on(st); st->print(")"); } + + void print_truncated(outputStream* st, int current_offset = -1) const { + st->print("same_locals_1_stack_item_extended(@%d), output truncated, Stackmap exceeds table size.", + offset_delta() + current_offset); + } }; class chop_frame : public stack_map_frame { @@ -511,6 +530,10 @@ class chop_frame : public stack_map_frame { void print_on(outputStream* st, int current_offset = -1) const { st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops()); } + + void print_truncated(outputStream* st, int current_offset = -1) const { + print_on(st, current_offset); + } }; class append_frame : public stack_map_frame { @@ -619,6 +642,11 @@ class append_frame : public stack_map_frame { } st->print(")"); } + + void print_truncated(outputStream* st, int current_offset = -1) const { + st->print("append_frame(@%d), output truncated, Stackmap exceeds table size.", + offset_delta() + current_offset); + } }; class full_frame : public stack_map_frame { @@ -784,6 +812,11 @@ class full_frame : public stack_map_frame { } st->print("})"); } + + void print_truncated(outputStream* st, int current_offset = -1) const { + st->print("full_frame(@%d), output truncated, Stackmap exceeds table size.", + offset_delta() + current_offset); + } }; #define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \ @@ -841,6 +874,10 @@ void stack_map_frame::print_on(outputStream* st, int offs = -1) const { FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs)); } +void stack_map_frame::print_truncated(outputStream* st, int offs = -1) const { + FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_truncated, (st, offs)); +} + #undef VIRTUAL_DISPATCH #undef VOID_VIRTUAL_DISPATCH diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index ba58b175305..93392009cc9 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -541,8 +541,19 @@ void ErrorContext::stackmap_details(outputStream* ss, const Method* method) cons stack_map_frame* sm_frame = sm_table->entries(); streamIndentor si2(ss); int current_offset = -1; + // Subtract two from StackMapAttribute length because the length includes + // two bytes for number of table entries. + size_t sm_table_space = method->stackmap_data()->length() - 2; for (u2 i = 0; i < sm_table->number_of_entries(); ++i) { ss->indent(); + size_t sm_frame_size = sm_frame->size(); + // If the size of the next stackmap exceeds the length of the entire + // stackmap table then print a truncated message and return. + if (sm_frame_size > sm_table_space) { + sm_frame->print_truncated(ss, current_offset); + return; + } + sm_table_space -= sm_frame_size; sm_frame->print_on(ss, current_offset); ss->cr(); current_offset += sm_frame->offset_delta(); From 154d568eddff8f17d48499ad06d92f0881fec328 Mon Sep 17 00:00:00 2001 From: Zoltan Majo Date: Fri, 1 Jul 2016 09:33:34 +0200 Subject: [PATCH 07/79] 8160591: Improve internal array handling Co-authored-by: Xiang Yuan Reviewed-by: kvn --- .../cpu/sparc/vm/c1_LIRAssembler_sparc.cpp | 21 ++++++ .../src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 17 +++++ .../c1/TestArrayCopyToFromObject.java | 64 +++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 hotspot/test/compiler/c1/TestArrayCopyToFromObject.java diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp index 8a9ef34eb46..a0f1982bbd7 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -2034,6 +2034,27 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { __ delayed()->nop(); } + // If the compiler was not able to prove that exact type of the source or the destination + // of the arraycopy is an array type, check at runtime if the source or the destination is + // an instance type. + if (flags & LIR_OpArrayCopy::type_check) { + if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) { + __ load_klass(dst, tmp); + __ lduw(tmp, in_bytes(Klass::layout_helper_offset()), tmp2); + __ cmp(tmp2, Klass::_lh_neutral_value); + __ br(Assembler::greaterEqual, false, Assembler::pn, *stub->entry()); + __ delayed()->nop(); + } + + if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) { + __ load_klass(src, tmp); + __ lduw(tmp, in_bytes(Klass::layout_helper_offset()), tmp2); + __ cmp(tmp2, Klass::_lh_neutral_value); + __ br(Assembler::greaterEqual, false, Assembler::pn, *stub->entry()); + __ delayed()->nop(); + } + } + if (flags & LIR_OpArrayCopy::src_pos_positive_check) { // test src_pos register __ cmp_zero_and_br(Assembler::less, src_pos, *stub->entry()); diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index 3adff833033..afc815c6739 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -3146,6 +3146,23 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { __ jcc(Assembler::zero, *stub->entry()); } + // If the compiler was not able to prove that exact type of the source or the destination + // of the arraycopy is an array type, check at runtime if the source or the destination is + // an instance type. + if (flags & LIR_OpArrayCopy::type_check) { + if (!(flags & LIR_OpArrayCopy::dst_objarray)) { + __ load_klass(tmp, dst); + __ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value); + __ jcc(Assembler::greaterEqual, *stub->entry()); + } + + if (!(flags & LIR_OpArrayCopy::src_objarray)) { + __ load_klass(tmp, src); + __ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value); + __ jcc(Assembler::greaterEqual, *stub->entry()); + } + } + // check if negative if (flags & LIR_OpArrayCopy::src_pos_positive_check) { __ testl(src_pos, src_pos); diff --git a/hotspot/test/compiler/c1/TestArrayCopyToFromObject.java b/hotspot/test/compiler/c1/TestArrayCopyToFromObject.java new file mode 100644 index 00000000000..e875bd5f7c9 --- /dev/null +++ b/hotspot/test/compiler/c1/TestArrayCopyToFromObject.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8160591 + * @summary C1-generated code for System.arraycopy() does not throw an ArrayStoreException if 'dst' is no a "proper" array (i.e., it is java.lang.Object) + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xcomp -XX:-UseCompressedClassPointers -XX:CompileOnly=TestArrayCopyToFromObject.test TestArrayCopyToFromObject + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xcomp -XX:+UseCompressedClassPointers -XX:CompileOnly=TestArrayCopyToFromObject.test TestArrayCopyToFromObject + */ +public class TestArrayCopyToFromObject { + + public void test(Object aArray[]) { + Object a = new Object(); + + try { + System.arraycopy(aArray, 0, a, 0, 1); + throw new RuntimeException ("FAILED: Expected ArrayStoreException " + + "(due to destination not being an array) " + + "was not thrown"); + } catch (ArrayStoreException e) { + System.out.println("PASSED: Expected ArrayStoreException was thrown"); + } + + try { + System.arraycopy(a, 0, aArray, 0, 1); + throw new RuntimeException ("FAILED: Expected ArrayStoreException " + + "(due to source not being an array) " + + "was not thrown"); + } catch (ArrayStoreException e) { + System.out.println("PASSED: Expected ArrayStoreException was thrown"); + } + + } + + public static void main(String args[]) { + System.out.println("TestArrayCopyToFromObject"); + Object aArray[] = new Object[10]; + for (int i = 0; i < 10; i++) { + aArray[i] = new Object(); + } + new TestArrayCopyToFromObject().test(aArray); + } +} From 53164dd53219f49e0dda0b7e73a1d8582603a5ca Mon Sep 17 00:00:00 2001 From: Rachel Protacio Date: Fri, 1 Jul 2016 15:11:38 -0400 Subject: [PATCH 08/79] 8159503: Amend Annotation Actions Reviewed-by: coleenp, hseigel, mschoene, acorn, ctornqvi --- hotspot/src/share/vm/classfile/classFileParser.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 5f0b1ca442a..9daa5e38769 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -5859,6 +5859,11 @@ void ClassFileParser::post_process_parsed_stream(const ClassFileStream* const st assert(cp != NULL, "invariant"); assert(_loader_data != NULL, "invariant"); + if (_class_name == vmSymbols::java_lang_Object()) { + check_property(_local_interfaces == Universe::the_empty_klass_array(), + "java.lang.Object cannot implement an interface in class file %s", + CHECK); + } // We check super class after class file is parsed and format is checked if (_super_class_index > 0 && NULL ==_super_klass) { Symbol* const super_class_name = cp->klass_name_at(_super_class_index); From 9d898bb3e08c11ca84ac8e182ff80d3790110b82 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Mon, 27 Jun 2016 15:26:08 -0400 Subject: [PATCH 09/79] 8157176: Improved classfile parsing Reviewed-by: acorn, mschoene, ctornqvi, bmoloden --- .../src/share/vm/runtime/sharedRuntime.cpp | 4 +- hotspot/src/share/vm/runtime/signature.cpp | 44 ++++++++++++++++++- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index cd517806273..ed70e62ba75 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -2881,8 +2881,6 @@ VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, char *s = sig->as_C_string(); int len = (int)strlen(s); s++; len--; // Skip opening paren - char *t = s+len; - while (*(--t) != ')'); // Find close paren BasicType *sig_bt = NEW_RESOURCE_ARRAY(BasicType, 256); VMRegPair *regs = NEW_RESOURCE_ARRAY(VMRegPair, 256); @@ -2891,7 +2889,7 @@ VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, sig_bt[cnt++] = T_OBJECT; // Receiver is argument 0; not in signature } - while (s < t) { + while (*s != ')') { // Find closing right paren switch (*s++) { // Switch on signature character case 'B': sig_bt[cnt++] = T_BYTE; break; case 'C': sig_bt[cnt++] = T_CHAR; break; diff --git a/hotspot/src/share/vm/runtime/signature.cpp b/hotspot/src/share/vm/runtime/signature.cpp index 937c1ff7edc..f92f355495f 100644 --- a/hotspot/src/share/vm/runtime/signature.cpp +++ b/hotspot/src/share/vm/runtime/signature.cpp @@ -224,7 +224,49 @@ void SignatureIterator::iterate_returntype() { _index = 0; expect('('); Symbol* sig = _signature; - while (sig->byte_at(_index) != ')') _index++; + // Need to skip over each type in the signature's argument list until a + // closing ')' is found., then get the return type. We cannot just scan + // for the first ')' because ')' is a legal character in a type name. + while (sig->byte_at(_index) != ')') { + switch(sig->byte_at(_index)) { + case 'B': + case 'C': + case 'D': + case 'F': + case 'I': + case 'J': + case 'S': + case 'Z': + case 'V': + { + _index++; + } + break; + case 'L': + { + while (sig->byte_at(_index++) != ';') ; + } + break; + case '[': + { + int begin = ++_index; + skip_optional_size(); + while (sig->byte_at(_index) == '[') { + _index++; + skip_optional_size(); + } + if (sig->byte_at(_index) == 'L') { + while (sig->byte_at(_index++) != ';') ; + } else { + _index++; + } + } + break; + default: + ShouldNotReachHere(); + break; + } + } expect(')'); // Parse return type _parameter_index = -1; From af3d6a84090f47edf65a1af4c1794ffdb67b1411 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Thu, 14 Jul 2016 13:35:35 -0700 Subject: [PATCH 10/79] 8151921: Improved page resolution Reviewed-by: jjg, ksrini, ahgross --- .../doclets/formats/html/markup/HtmlWriter.java | 11 ++++++----- .../doclets/formats/html/markup/HtmlWriter.java | 11 ++++++----- .../sun/javadoc/testJavascript/TestJavascript.java | 13 +++++++------ .../doclet/testJavascript/TestJavascript.java | 13 +++++++------ 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java index 27bb1182fee..eebc537ffcd 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java @@ -353,11 +353,12 @@ public class HtmlWriter { protected Content getFramesJavaScript() { HtmlTree script = HtmlTree.SCRIPT(); String scriptCode = DocletConstants.NL + - " targetPage = \"\" + window.location.search;" + DocletConstants.NL + - " if (targetPage != \"\" && targetPage != \"undefined\")" + DocletConstants.NL + - " targetPage = targetPage.substring(1);" + DocletConstants.NL + - " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + DocletConstants.NL + - " targetPage = \"undefined\";" + DocletConstants.NL + + " tmpTargetPage = \"\" + window.location.search;" + DocletConstants.NL + + " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")" + DocletConstants.NL + + " tmpTargetPage = tmpTargetPage.substring(1);" + DocletConstants.NL + + " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))" + DocletConstants.NL + + " tmpTargetPage = \"undefined\";" + DocletConstants.NL + + " targetPage = tmpTargetPage;" + DocletConstants.NL + " function validURL(url) {" + DocletConstants.NL + " try {" + DocletConstants.NL + " url = decodeURIComponent(url);" + DocletConstants.NL + diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java index 2e90af8eba9..59de3f0bb1c 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java @@ -234,11 +234,12 @@ public class HtmlWriter { protected Content getFramesJavaScript() { HtmlTree scriptTree = HtmlTree.SCRIPT(); String scriptCode = "\n" + - " targetPage = \"\" + window.location.search;\n" + - " if (targetPage != \"\" && targetPage != \"undefined\")\n" + - " targetPage = targetPage.substring(1);\n" + - " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n" + - " targetPage = \"undefined\";\n" + + " tmpTargetPage = \"\" + window.location.search;\n" + + " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n" + + " tmpTargetPage = tmpTargetPage.substring(1);\n" + + " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n" + + " tmpTargetPage = \"undefined\";\n" + + " targetPage = tmpTargetPage;\n" + " function validURL(url) {\n" + " try {\n" + " url = decodeURIComponent(url);\n" + diff --git a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java index 652ef6690fe..7ce84428383 100644 --- a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java +++ b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 + * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8151921 * @summary Verify that the output has the right javascript. * @author jamieh * @library ../lib @@ -54,11 +54,12 @@ public class TestJavascript extends JavadocTester { checkOutput("index.html", true, "