OpenJDK / jdk / jdk
changeset 57590:59e74aa436b9
8236692: static final fields without initializer are accepted by javac
Reviewed-by: mcimadamore
author | vromero |
---|---|
date | Wed, 08 Jan 2020 15:18:58 -0500 |
parents | decd3d2953b6 |
children | 2383b1a86007 |
files | src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java test/langtools/tools/javac/records/RecordCompilationTests.java |
diffstat | 2 files changed, 36 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Wed Jan 08 19:12:20 2020 +0100 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Wed Jan 08 15:18:58 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 @@ -1855,21 +1855,17 @@ /** Check that trackable variable is initialized. */ - boolean checkInit(DiagnosticPosition pos, VarSymbol sym, boolean compactConstructor) { - return checkInit(pos, sym, Errors.VarMightNotHaveBeenInitialized(sym), compactConstructor); + void checkInit(DiagnosticPosition pos, VarSymbol sym) { + checkInit(pos, sym, Errors.VarMightNotHaveBeenInitialized(sym)); } - boolean checkInit(DiagnosticPosition pos, VarSymbol sym, Error errkey, boolean compactConstructor) { + void checkInit(DiagnosticPosition pos, VarSymbol sym, Error errkey) { if ((sym.adr >= firstadr || sym.owner.kind != TYP) && trackable(sym) && !inits.isMember(sym.adr)) { - if (sym.owner.kind != TYP || !compactConstructor || !uninits.isMember(sym.adr)) { log.error(pos, errkey); - } inits.incl(sym.adr); - return false; } - return true; } /** Utility method to reset several Bits instances. @@ -2099,15 +2095,27 @@ // the ctor is default(synthesized) or not if (isSynthesized && !isCompactConstructor) { checkInit(TreeInfo.diagnosticPositionFor(var, vardecl), - var, Errors.VarNotInitializedInDefaultConstructor(var), isCompactConstructor); - } else { - boolean wasInitialized = checkInit(TreeInfo.diagEndPos(tree.body), var, isCompactConstructor && tree.completesNormally); - if (!wasInitialized && var.owner.kind == TYP && isCompactConstructor && uninits.isMember(var.adr) && tree.completesNormally) { + var, Errors.VarNotInitializedInDefaultConstructor(var)); + } else if (isCompactConstructor) { + boolean isInstanceRecordField = var.enclClass().isRecord() && + (var.flags_field & (Flags.PRIVATE | Flags.FINAL | Flags.GENERATED_MEMBER | Flags.RECORD)) != 0 && + !var.isStatic() && + var.owner.kind == TYP; + if (isInstanceRecordField) { + boolean notInitialized = !inits.isMember(var.adr); + if (notInitialized && uninits.isMember(var.adr) && tree.completesNormally) { /* this way we indicate Lower that it should generate an initialization for this field * in the compact constructor */ - var.flags_field |= UNINITIALIZED_FIELD; + var.flags_field |= UNINITIALIZED_FIELD; + } else { + checkInit(TreeInfo.diagEndPos(tree.body), var); + } + } else { + checkInit(TreeInfo.diagnosticPositionFor(var, vardecl), var); } + } else { + checkInit(TreeInfo.diagEndPos(tree.body), var); } } } @@ -2124,7 +2132,7 @@ Assert.check(exit instanceof AssignPendingExit); inits.assign(((AssignPendingExit) exit).exit_inits); for (int i = firstadr; i < nextadr; i++) { - checkInit(exit.tree.pos(), vardecls[i].sym, isCompactConstructor); + checkInit(exit.tree.pos(), vardecls[i].sym); } } } @@ -2666,7 +2674,7 @@ super.visitSelect(tree); if (TreeInfo.isThisQualifier(tree.selected) && tree.sym.kind == VAR) { - checkInit(tree.pos(), (VarSymbol)tree.sym, false); + checkInit(tree.pos(), (VarSymbol)tree.sym); } } @@ -2727,7 +2735,7 @@ public void visitIdent(JCIdent tree) { if (tree.sym.kind == VAR) { - checkInit(tree.pos(), (VarSymbol)tree.sym, false); + checkInit(tree.pos(), (VarSymbol)tree.sym); referenced(tree.sym); } }
--- a/test/langtools/tools/javac/records/RecordCompilationTests.java Wed Jan 08 19:12:20 2020 +0100 +++ b/test/langtools/tools/javac/records/RecordCompilationTests.java Wed Jan 08 15:18:58 2020 -0500 @@ -406,6 +406,18 @@ // x is not DA nor DU in the body of the constructor hence error assertFail("compiler.err.var.might.not.have.been.initialized", "record R(int x) { # }", "public R { if (x < 0) { this.x = -x; } }"); + + // if static fields are not DA then error + assertFail("compiler.err.var.might.not.have.been.initialized", + "record R() { # }", "static final String x;"); + + // ditto + assertFail("compiler.err.var.might.not.have.been.initialized", + "record R() { # }", "static final String x; public R {}"); + + // ditto + assertFail("compiler.err.var.might.not.have.been.initialized", + "record R(int i) { # }", "static final String x; public R {}"); } public void testReturnInCanonical_Compact() {