changeset 57671:2939d1a460ed

8236005: local records shouldn't capture any non-static state from any enclosing type Reviewed-by: mcimadamore
author vromero
date Tue, 14 Jan 2020 07:07:43 -0500
parents 247b7fe0c11d
children d30ad4758d52
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java test/langtools/tools/javac/records/RecordCompilationTests.java
diffstat 2 files changed, 45 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Jan 14 18:07:45 2020 +0800
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Jan 14 07:07:43 2020 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, 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
@@ -1489,7 +1489,13 @@
             if (sym.exists()) {
                 if (staticOnly &&
                     sym.kind == VAR &&
-                    sym.owner.kind == TYP &&
+                        // if it is a field
+                        (sym.owner.kind == TYP ||
+                        // or it is a local variable but it is not declared inside of the static local type
+                        // only records so far, then error
+                        (sym.owner.kind == MTH) &&
+                        (env.enclClass.sym.flags() & STATIC) != 0 &&
+                        sym.enclClass() != env.enclClass.sym) &&
                     (sym.flags() & STATIC) == 0)
                     return new StaticError(sym);
                 else
--- a/test/langtools/tools/javac/records/RecordCompilationTests.java	Tue Jan 14 18:07:45 2020 +0800
+++ b/test/langtools/tools/javac/records/RecordCompilationTests.java	Tue Jan 14 07:07:43 2020 -0500
@@ -377,10 +377,44 @@
                 "    }\n" +
                 "}");
 
-        // Capture locals from local record
+        // Cant capture locals
+        assertFail("compiler.err.non-static.cant.be.ref",
+                "class R { \n" +
+                        "    void m(int y) { \n" +
+                        "        record RR(int x) { public int x() { return y; }};\n" +
+                        "    }\n" +
+                        "}");
+
+        assertFail("compiler.err.non-static.cant.be.ref",
+                "class R { \n" +
+                        "    void m() {\n" +
+                        "        int y;\n" +
+                        "        record RR(int x) { public int x() { return y; }};\n" +
+                        "    }\n" +
+                        "}");
+
+        // instance fields
+        assertFail("compiler.err.non-static.cant.be.ref",
+                "class R { \n" +
+                        "    int z = 0;\n" +
+                        "    void m() { \n" +
+                        "        record RR(int x) { public int x() { return z; }};\n" +
+                        "    }\n" +
+                        "}");
+
+        // or type variables
+        assertFail("compiler.err.non-static.cant.be.ref",
+                "class R<T> { \n" +
+                        "    void m() { \n" +
+                        "        record RR(T t) {};\n" +
+                        "    }\n" +
+                        "}");
+
+        // but static fields are OK
         assertOK("class R { \n" +
-                "    void m(int y) { \n" +
-                "        record RR(int x) { public int x() { return y; }};\n" +
+                "    static int z = 0;\n" +
+                "    void m() { \n" +
+                "        record RR(int x) { public int x() { return z; }};\n" +
                 "    }\n" +
                 "}");