8334258: Compiler erronousely allows access to instance variable in argument expression of a constructor invocation
Reviewed-by: mcimadamore
This commit is contained in:
parent
2ce85d9635
commit
e227c7e37d
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2024, 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
|
||||
@ -100,6 +100,7 @@ public class Resolve {
|
||||
DeferredAttr deferredAttr;
|
||||
Check chk;
|
||||
Infer infer;
|
||||
Preview preview;
|
||||
ClassFinder finder;
|
||||
ModuleFinder moduleFinder;
|
||||
Types types;
|
||||
@ -135,7 +136,7 @@ public class Resolve {
|
||||
moduleFinder = ModuleFinder.instance(context);
|
||||
types = Types.instance(context);
|
||||
diags = JCDiagnostic.Factory.instance(context);
|
||||
Preview preview = Preview.instance(context);
|
||||
preview = Preview.instance(context);
|
||||
Source source = Source.instance(context);
|
||||
Options options = Options.instance(context);
|
||||
compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
|
||||
@ -1480,10 +1481,11 @@ public class Resolve {
|
||||
|
||||
/** Find unqualified variable or field with given name.
|
||||
* Synthetic fields always skipped.
|
||||
* @param pos The position to use for error reporting.
|
||||
* @param env The current environment.
|
||||
* @param name The name of the variable or field.
|
||||
*/
|
||||
Symbol findVar(Env<AttrContext> env, Name name) {
|
||||
Symbol findVar(DiagnosticPosition pos, Env<AttrContext> env, Name name) {
|
||||
Symbol bestSoFar = varNotFound;
|
||||
Env<AttrContext> env1 = env;
|
||||
boolean staticOnly = false;
|
||||
@ -1508,7 +1510,7 @@ public class Resolve {
|
||||
(sym.flags() & STATIC) == 0) {
|
||||
if (staticOnly)
|
||||
return new StaticError(sym);
|
||||
if (env1.info.ctorPrologue && !isAllowedEarlyReference(env1, (VarSymbol)sym))
|
||||
if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym))
|
||||
return new RefBeforeCtorCalledError(sym);
|
||||
}
|
||||
return sym;
|
||||
@ -2421,15 +2423,15 @@ public class Resolve {
|
||||
* (a subset of VAL, TYP, PCK).
|
||||
*/
|
||||
Symbol findIdent(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
|
||||
return checkNonExistentType(checkRestrictedType(pos, findIdentInternal(env, name, kind), name));
|
||||
return checkNonExistentType(checkRestrictedType(pos, findIdentInternal(pos, env, name, kind), name));
|
||||
}
|
||||
|
||||
Symbol findIdentInternal(Env<AttrContext> env, Name name, KindSelector kind) {
|
||||
Symbol findIdentInternal(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
|
||||
Symbol bestSoFar = typeNotFound;
|
||||
Symbol sym;
|
||||
|
||||
if (kind.contains(KindSelector.VAL)) {
|
||||
sym = findVar(env, name);
|
||||
sym = findVar(pos, env, name);
|
||||
if (sym.exists()) return sym;
|
||||
else bestSoFar = bestOf(bestSoFar, sym);
|
||||
}
|
||||
@ -3776,7 +3778,7 @@ public class Resolve {
|
||||
if (sym != null) {
|
||||
if (staticOnly)
|
||||
sym = new StaticError(sym);
|
||||
else if (env1.info.ctorPrologue && !isAllowedEarlyReference(env1, (VarSymbol)sym))
|
||||
else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym))
|
||||
sym = new RefBeforeCtorCalledError(sym);
|
||||
return accessBase(sym, pos, env.enclClass.sym.type,
|
||||
name, true);
|
||||
@ -3845,7 +3847,7 @@ public class Resolve {
|
||||
* We also don't verify that the field has no initializer, which is required.
|
||||
* To catch those cases, we rely on similar logic in Attr.checkAssignable().
|
||||
*/
|
||||
private boolean isAllowedEarlyReference(Env<AttrContext> env, VarSymbol v) {
|
||||
private boolean isAllowedEarlyReference(DiagnosticPosition pos, Env<AttrContext> env, VarSymbol v) {
|
||||
|
||||
// Check assumptions
|
||||
Assert.check(env.info.ctorPrologue);
|
||||
@ -3880,6 +3882,9 @@ public class Resolve {
|
||||
if (isEarlyReference(env, base, v) && v.owner != env.enclClass.sym)
|
||||
return false;
|
||||
|
||||
// The flexible constructors feature must be enabled
|
||||
preview.checkSourceLevel(pos, Feature.FLEXIBLE_CONSTRUCTORS);
|
||||
|
||||
// OK
|
||||
return true;
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8334258
|
||||
* @summary Disallow early assignment if FLEXIBLE_CONSTRUCTORS preview feature is not enabled
|
||||
* @compile/fail/ref=EarlyAssignmentNoPreview1.out -XDrawDiagnostics EarlyAssignmentNoPreview1.java
|
||||
*/
|
||||
public class EarlyAssignmentNoPreview1 {
|
||||
|
||||
Runnable r;
|
||||
|
||||
public EarlyAssignmentNoPreview1() {
|
||||
this(r = () -> System.out.println("hello"));
|
||||
}
|
||||
|
||||
public EarlyAssignmentNoPreview1(Runnable r) {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new EarlyAssignmentNoPreview1();
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
EarlyAssignmentNoPreview1.java:12:14: compiler.err.preview.feature.disabled: (compiler.misc.feature.flexible.constructors)
|
||||
1 error
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8334258
|
||||
* @summary Disallow early assignment if FLEXIBLE_CONSTRUCTORS preview feature is not enabled
|
||||
* @compile/fail/ref=EarlyAssignmentNoPreview2.out -XDrawDiagnostics EarlyAssignmentNoPreview2.java
|
||||
*/
|
||||
public class EarlyAssignmentNoPreview2 {
|
||||
|
||||
Runnable r;
|
||||
|
||||
public EarlyAssignmentNoPreview2() {
|
||||
this(this.r = () -> System.out.println("hello"));
|
||||
}
|
||||
|
||||
public EarlyAssignmentNoPreview2(Runnable r) {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new EarlyAssignmentNoPreview2();
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
EarlyAssignmentNoPreview2.java:12:14: compiler.err.preview.feature.disabled: (compiler.misc.feature.flexible.constructors)
|
||||
1 error
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8334258
|
||||
* @summary Disallow early assignment if FLEXIBLE_CONSTRUCTORS preview feature is not enabled
|
||||
* @compile/fail/ref=EarlyAssignmentNoPreview3.out -XDrawDiagnostics EarlyAssignmentNoPreview3.java
|
||||
*/
|
||||
public class EarlyAssignmentNoPreview3 {
|
||||
|
||||
Runnable r;
|
||||
|
||||
public EarlyAssignmentNoPreview3() {
|
||||
this(EarlyAssignmentNoPreview3.this.r = () -> System.out.println("hello"));
|
||||
}
|
||||
|
||||
public EarlyAssignmentNoPreview3(Runnable r) {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new EarlyAssignmentNoPreview3();
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
EarlyAssignmentNoPreview3.java:12:39: compiler.err.preview.feature.disabled: (compiler.misc.feature.flexible.constructors)
|
||||
1 error
|
Loading…
Reference in New Issue
Block a user