8236005: local records shouldn't capture any non-static state from any enclosing type

Reviewed-by: mcimadamore
This commit is contained in:
Vicente Romero 2020-01-14 07:07:43 -05:00
parent 6d03f918cf
commit 5ff1d72185
2 changed files with 45 additions and 5 deletions

View File

@ -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 @@ public class Resolve {
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

View File

@ -377,10 +377,44 @@ public class RecordCompilationTests extends CompilationTestCase {
" }\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" +
"}");