提交 2ce80ac6 编写于 作者: P pgovereau

8039026: Definitely unassigned field can be accessed

Reviewed-by: vromero, jlahoda
上级 6e6e66ef
......@@ -191,6 +191,9 @@ public enum Source {
public boolean allowObjectToPrimitiveCast() {
return compareTo(JDK1_7) >= 0;
}
public boolean enforceThisDotInit() {
return compareTo(JDK1_7) >= 0;
}
public boolean allowPoly() {
return compareTo(JDK1_8) >= 0;
}
......
......@@ -197,6 +197,7 @@ public class Flow {
private final boolean allowImprovedRethrowAnalysis;
private final boolean allowImprovedCatchAnalysis;
private final boolean allowEffectivelyFinalInInnerClasses;
private final boolean enforceThisDotInit;
public static Flow instance(Context context) {
Flow instance = context.get(flowKey);
......@@ -207,7 +208,7 @@ public class Flow {
public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
new AliveAnalyzer().analyzeTree(env, make);
new AssignAnalyzer(log, syms, lint, names).analyzeTree(env);
new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env);
new FlowAnalyzer().analyzeTree(env, make);
new CaptureAnalyzer().analyzeTree(env, make);
}
......@@ -239,7 +240,7 @@ public class Flow {
//related errors, which will allow for more errors to be detected
Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
try {
new AssignAnalyzer(log, syms, lint, names).analyzeTree(env);
new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env);
LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
flowAnalyzer.analyzeTree(env, that, make);
return flowAnalyzer.inferredThrownTypes;
......@@ -289,6 +290,7 @@ public class Flow {
allowImprovedRethrowAnalysis = source.allowImprovedRethrowAnalysis();
allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis();
allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses();
enforceThisDotInit = source.enforceThisDotInit();
}
/**
......@@ -1427,6 +1429,8 @@ public class Flow {
protected Names names;
final boolean enforceThisDotInit;
public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
final Bits inits;
......@@ -1449,7 +1453,7 @@ public class Flow {
}
}
public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names) {
public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names, boolean enforceThisDotInit) {
this.inits = inits;
uninits = new Bits();
uninitsTry = new Bits();
......@@ -1459,6 +1463,7 @@ public class Flow {
uninitsWhenFalse = new Bits(true);
this.syms = syms;
this.names = names;
this.enforceThisDotInit = enforceThisDotInit;
}
private boolean isInitialConstructor = false;
......@@ -2280,12 +2285,34 @@ public class Flow {
public void visitAssign(JCAssign tree) {
JCTree lhs = TreeInfo.skipParens(tree.lhs);
if (!(lhs instanceof JCIdent)) {
if (!isIdentOrThisDotIdent(lhs))
scanExpr(lhs);
}
scanExpr(tree.rhs);
letInit(lhs);
}
private boolean isIdentOrThisDotIdent(JCTree lhs) {
if (lhs.hasTag(IDENT))
return true;
if (!lhs.hasTag(SELECT))
return false;
JCFieldAccess fa = (JCFieldAccess)lhs;
return fa.selected.hasTag(IDENT) &&
((JCIdent)fa.selected).name == names._this;
}
// check fields accessed through this.<field> are definitely
// assigned before reading their value
public void visitSelect(JCFieldAccess tree) {
super.visitSelect(tree);
if (enforceThisDotInit &&
tree.selected.hasTag(IDENT) &&
((JCIdent)tree.selected).name == names._this &&
tree.sym.kind == VAR)
{
checkInit(tree.pos(), (VarSymbol)tree.sym);
}
}
public void visitAssignop(JCAssignOp tree) {
scanExpr(tree.lhs);
......@@ -2419,8 +2446,8 @@ public class Flow {
}
}
public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names) {
super(new Bits(), syms, names);
public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names, boolean enforceThisDotInit) {
super(new Bits(), syms, names, enforceThisDotInit);
this.log = log;
this.lint = lint;
}
......
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2014, 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
......@@ -2818,7 +2818,7 @@ public class Gen extends JCTree.Visitor {
}
private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) {
super(new LVTBits(), syms, names);
super(new LVTBits(), syms, names, false);
lvtInits = (LVTBits)inits;
this.lvtRanges = lvtRanges;
}
......
/*
* @test /nodynamiccopyright/
* @bug 8039026
* @summary Definitely unassigned field can be accessed
* @compile/fail/ref=T8039026.out -XDrawDiagnostics T8039026.java
*/
public class T8039026 {
final int x,y,z;
final int a = this.y; // <- error
{
int b = true ? this.x : 0; // <- error
System.out.println(this.x); // <- error
this.y = 1;
}
T8039026() {
this.x = 1; // <- no error!
this.y = 1; // <- error
this.z = this.x; // <- no error
}
}
T8039026.java:10:23: compiler.err.var.might.not.have.been.initialized: y
T8039026.java:12:28: compiler.err.var.might.not.have.been.initialized: x
T8039026.java:18:13: compiler.err.var.might.already.be.assigned: y
3 errors
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册