7196163: Project Coin: Allow effectively final variables to be used as resources in try-with-resources
Summary: Allowing final variables as operands to try-with-resources; also reviewed by Sergei Pikalev.
Reviewed-by: darcy, mcimadamore, vromero
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java Mon Nov 17 23:11:05 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java Wed Nov 19 13:46:04 2014 +0100
@@ -168,6 +168,7 @@
public static final KindSelector MTH = new KindSelector(0x10);
public static final KindSelector ERR = new KindSelector(0x3f);
public static final KindSelector POLY = new KindSelector(0x20);
+ public static final KindSelector ASG = new KindSelector(0x44);
//common derived selectors
public static final KindSelector TYP_PCK = of(TYP, PCK);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java Mon Nov 17 23:11:05 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java Wed Nov 19 13:46:04 2014 +0100
@@ -140,6 +140,9 @@
public boolean allowTryWithResources() {
return compareTo(JDK1_7) >= 0;
}
+ public boolean allowEffectivelyFinalVariablesInTryWithResources() {
+ return compareTo(JDK1_9) >= 0;
+ }
public boolean allowBinaryLiterals() {
return compareTo(JDK1_7) >= 0;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Mon Nov 17 23:11:05 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Nov 19 13:46:04 2014 +0100
@@ -148,7 +148,7 @@
identifyLambdaCandidate = options.getBoolean("identifyLambdaCandidate", false);
statInfo = new ResultInfo(KindSelector.NIL, Type.noType);
- varInfo = new ResultInfo(KindSelector.VAR, Type.noType);
+ varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType);
unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType);
unknownAnyPolyInfo = new ResultInfo(KindSelector.VAL, Infer.anyPoly);
unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
@@ -498,7 +498,7 @@
}
final ResultInfo statInfo;
- final ResultInfo varInfo;
+ final ResultInfo varAssignmentInfo;
final ResultInfo unknownAnyPolyInfo;
final ResultInfo unknownExprInfo;
final ResultInfo unknownTypeInfo;
@@ -1293,7 +1293,7 @@
}
};
ResultInfo twrResult =
- new ResultInfo(KindSelector.VAL,
+ new ResultInfo(KindSelector.VAR,
syms.autoCloseableType,
twrContext);
if (resource.hasTag(VARDEF)) {
@@ -2942,7 +2942,7 @@
}
public void visitAssign(JCAssign tree) {
- Type owntype = attribTree(tree.lhs, env.dup(tree), varInfo);
+ Type owntype = attribTree(tree.lhs, env.dup(tree), varAssignmentInfo);
Type capturedType = capture(owntype);
attribExpr(tree.rhs, env, owntype);
result = check(tree, capturedType, KindSelector.VAL, resultInfo);
@@ -2950,7 +2950,7 @@
public void visitAssignop(JCAssignOp tree) {
// Attribute arguments.
- Type owntype = attribTree(tree.lhs, env, varInfo);
+ Type owntype = attribTree(tree.lhs, env, varAssignmentInfo);
Type operand = attribExpr(tree.rhs, env);
// Find operator.
Symbol operator = tree.operator = rs.resolveBinaryOperator(
@@ -2976,7 +2976,7 @@
public void visitUnary(JCUnary tree) {
// Attribute arguments.
Type argtype = (tree.getTag().isIncOrDecUnaryOp())
- ? attribTree(tree.arg, env, varInfo)
+ ? attribTree(tree.arg, env, varAssignmentInfo)
: chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
// Find operator.
@@ -3156,7 +3156,7 @@
// If we are expecting a variable (as opposed to a value), check
// that the variable is assignable in the current environment.
- if (pkind() == KindSelector.VAR)
+ if (KindSelector.ASG.subset(pkind()))
checkAssignable(tree.pos(), v, null, env);
}
@@ -3255,7 +3255,7 @@
// If we are expecting a variable (as opposed to a value), check
// that the variable is assignable in the current environment.
- if (pkind() == KindSelector.VAR)
+ if (KindSelector.ASG.subset(pkind()))
checkAssignable(tree.pos(), v, tree.selected, env);
}
@@ -3538,7 +3538,7 @@
// Test (4): if symbol is an instance field of a raw type,
// which is being assigned to, issue an unchecked warning if
// its type changes under erasure.
- if (resultInfo.pkind == KindSelector.VAR &&
+ if (KindSelector.ASG.subset(pkind()) &&
v.owner.kind == TYP &&
(v.flags() & STATIC) == 0 &&
(site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Mon Nov 17 23:11:05 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Wed Nov 19 13:46:04 2014 +0100
@@ -2562,6 +2562,8 @@
* This pass implements the last step of the dataflow analysis, namely
* the effectively-final analysis check. This checks that every local variable
* reference from a lambda body/local inner class is either final or effectively final.
+ * Additional this also checks that every variable that is used as an operand to
+ * try-with-resources is final or effectively final.
* As effectively final variables are marked as such during DA/DU, this pass must run after
* AssignAnalyzer.
*/
@@ -2690,6 +2692,18 @@
}
}
+ public void visitTry(JCTry tree) {
+ for (JCTree resource : tree.resources) {
+ if (!resource.hasTag(VARDEF)) {
+ Symbol var = TreeInfo.symbol(resource);
+ if (var != null && (var.flags() & (FINAL | EFFECTIVELY_FINAL)) == 0) {
+ log.error(resource.pos(), "try.with.resources.expr.effectively.final.var", var);
+ }
+ }
+ }
+ super.visitTry(tree);
+ }
+
/**************************************************************************
* main method
*************************************************************************/
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Nov 17 23:11:05 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Nov 19 13:46:04 2014 +0100
@@ -145,6 +145,8 @@
this.names = fac.names;
this.source = fac.source;
this.allowTWR = source.allowTryWithResources();
+ this.allowEffectivelyFinalVariablesInTWR =
+ source.allowEffectivelyFinalVariablesInTryWithResources();
this.allowDiamond = source.allowDiamond();
this.allowMulticatch = source.allowMulticatch();
this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
@@ -184,6 +186,10 @@
*/
boolean allowTWR;
+ /** Switch: should we allow (effectively) final variables as resources in try-with-resources?
+ */
+ boolean allowEffectivelyFinalVariablesInTWR;
+
/** Switch: should we fold strings?
*/
boolean allowStringFolding;
@@ -3003,14 +3009,28 @@
return defs.toList();
}
- /** Resource = VariableModifiersOpt Type VariableDeclaratorId = Expression
+ /** Resource = VariableModifiersOpt Type VariableDeclaratorId "=" Expression
+ * | Expression
*/
protected JCTree resource() {
- JCModifiers optFinal = optFinal(Flags.FINAL);
- JCExpression type = parseType();
- int pos = token.pos;
- Name ident = ident();
- return variableDeclaratorRest(pos, optFinal, type, ident, true, null);
+ int startPos = token.pos;
+ if (token.kind == FINAL || token.kind == MONKEYS_AT) {
+ JCModifiers mods = optFinal(Flags.FINAL);
+ JCExpression t = parseType();
+ return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
+ }
+ JCExpression t = term(EXPR | TYPE);
+ if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
+ JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL));
+ return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
+ } else {
+ checkVariableInTryWithResources(startPos);
+ if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) {
+ log.error(t.pos(), "try.with.resources.expr.needs.var");
+ }
+
+ return t;
+ }
}
/** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
@@ -3933,6 +3953,12 @@
allowTWR = true;
}
}
+ void checkVariableInTryWithResources(int startPos) {
+ if (!allowEffectivelyFinalVariablesInTWR) {
+ error(startPos, "var.in.try.with.resources.not.supported.in.source", source.name);
+ allowEffectivelyFinalVariablesInTWR = true;
+ }
+ }
void checkLambda() {
if (!allowLambda) {
log.error(token.pos, "lambda.not.supported.in.source", source.name);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Nov 17 23:11:05 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Nov 19 13:46:04 2014 +0100
@@ -252,6 +252,14 @@
compiler.err.cant.ref.non.effectively.final.var=\
local variables referenced from {1} must be final or effectively final
+compiler.err.try.with.resources.expr.needs.var=\
+ the try-with-resources resource must either be a variable declaration or an expression denoting \
+a reference to a final or effectively final variable
+
+# 0: symbol
+compiler.err.try.with.resources.expr.effectively.final.var=\
+ variable {0} used as a try-with-resources resource neither final nor effectively final
+
compiler.misc.lambda=\
a lambda expression
@@ -2262,6 +2270,11 @@
try-with-resources is not supported in -source {0}\n\
(use -source 7 or higher to enable try-with-resources)
+# 0: string
+compiler.err.var.in.try.with.resources.not.supported.in.source=\
+ variables in try-with-resources not supported in -source {0}\n\
+ (use -source 9 or higher to enable variables in try-with-resources)
+
compiler.warn.underscore.as.identifier=\
''_'' used as an identifier\n\
(use of ''_'' as an identifier might not be supported in releases after Java SE 8)
--- a/langtools/test/tools/javac/TryWithResources/BadTwrSyntax.out Mon Nov 17 23:11:05 2014 -0800
+++ b/langtools/test/tools/javac/TryWithResources/BadTwrSyntax.out Wed Nov 19 13:46:04 2014 +0100
@@ -1,2 +1,2 @@
-BadTwrSyntax.java:14:43: compiler.err.illegal.start.of.type
+BadTwrSyntax.java:14:43: compiler.err.illegal.start.of.expr
1 error
--- a/langtools/test/tools/javac/TryWithResources/ResDeclOutsideTry.java Mon Nov 17 23:11:05 2014 -0800
+++ b/langtools/test/tools/javac/TryWithResources/ResDeclOutsideTry.java Wed Nov 19 13:46:04 2014 +0100
@@ -13,6 +13,11 @@
String test1() {
try (tr1 = new ResDeclOutsideTry(); tr2;) {
}
+ return null;
+ }
+
+ @Override
+ public void close() throws Exception {
}
}
--- a/langtools/test/tools/javac/TryWithResources/ResDeclOutsideTry.out Mon Nov 17 23:11:05 2014 -0800
+++ b/langtools/test/tools/javac/TryWithResources/ResDeclOutsideTry.out Wed Nov 19 13:46:04 2014 +0100
@@ -1,3 +1,2 @@
-ResDeclOutsideTry.java:14:17: compiler.err.expected: token.identifier
-ResDeclOutsideTry.java:14:48: compiler.err.expected: token.identifier
-2 errors
+ResDeclOutsideTry.java:14:18: compiler.err.try.with.resources.expr.needs.var
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable1.java Wed Nov 19 13:46:04 2014 +0100
@@ -0,0 +1,69 @@
+/* @test /nodynamiccopyright/
+ * @bug 7196163
+ * @summary Verify that variables can be used as operands to try-with-resources
+ * @compile/fail/ref=TwrForVariable1.out -source 8 -XDrawDiagnostics -Xlint:-options TwrForVariable1.java
+ * @compile TwrForVariable1.java
+ * @run main TwrForVariable1
+ */
+public class TwrForVariable1 implements AutoCloseable {
+ private static int closeCount = 0;
+ public static void main(String... args) {
+ TwrForVariable1 v = new TwrForVariable1();
+
+ try (v) {
+ assertCloseCount(0);
+ }
+ try (/**@deprecated*/v) {
+ assertCloseCount(1);
+ }
+ try (v.finalWrapper.finalField) {
+ assertCloseCount(2);
+ } catch (Exception ex) {
+ }
+ try (new TwrForVariable1() { }.finalWrapper.finalField) {
+ assertCloseCount(3);
+ } catch (Exception ex) {
+ }
+ try ((args.length > 0 ? v : new TwrForVariable1()).finalWrapper.finalField) {
+ assertCloseCount(4);
+ } catch (Exception ex) {
+ }
+ try {
+ throw new CloseableException();
+ } catch (CloseableException ex) {
+ try (ex) {
+ assertCloseCount(5);
+ }
+ }
+
+ assertCloseCount(6);
+ }
+
+ static void assertCloseCount(int expectedCloseCount) {
+ if (closeCount != expectedCloseCount)
+ throw new RuntimeException("bad closeCount: " + closeCount +
+ "; expected: " + expectedCloseCount);
+ }
+
+ public void close() {
+ closeCount++;
+ }
+
+ final FinalWrapper finalWrapper = new FinalWrapper();
+
+ static class FinalWrapper {
+ public final AutoCloseable finalField = new AutoCloseable() {
+ @Override
+ public void close() throws Exception {
+ closeCount++;
+ }
+ };
+ }
+
+ static class CloseableException extends Exception implements AutoCloseable {
+ @Override
+ public void close() {
+ closeCount++;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable1.out Wed Nov 19 13:46:04 2014 +0100
@@ -0,0 +1,2 @@
+TwrForVariable1.java:13:14: compiler.err.var.in.try.with.resources.not.supported.in.source: 1.8
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable2.java Wed Nov 19 13:46:04 2014 +0100
@@ -0,0 +1,39 @@
+/* @test /nodynamiccopyright/
+ * @bug 7196163
+ * @summary Verify that an improper combination of modifiers and variable is rejected
+ * in an operand to try-with-resources
+ * @compile/fail/ref=TwrForVariable2.out -XDrawDiagnostics -Xlint:-options TwrForVariable2.java
+ */
+public class TwrForVariable2 implements AutoCloseable {
+ public static void main(String... args) {
+ TwrForVariable2 v = new TwrForVariable2();
+ TwrForVariable3[] v2 = new TwrForVariable3[1];
+
+ try (final v) {
+ fail("no modifiers before variables");
+ }
+ try (@Deprecated v) {
+ fail("no annotations before variables");
+ }
+ try (v;;) {
+ fail("illegal double semicolon");
+ }
+ try ((v)) {
+ fail("parentheses not allowed");
+ }
+ try (v2[0]) {
+ fail("array access not allowed");
+ }
+ try (args.length == 0 ? v : v) {
+ fail("general expressions not allowed");
+ }
+ }
+
+ static void fail(String reason) {
+ throw new RuntimeException(reason);
+ }
+
+ public void close() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable2.out Wed Nov 19 13:46:04 2014 +0100
@@ -0,0 +1,7 @@
+TwrForVariable2.java:12:21: compiler.err.expected: token.identifier
+TwrForVariable2.java:15:27: compiler.err.expected: token.identifier
+TwrForVariable2.java:18:16: compiler.err.illegal.start.of.expr
+TwrForVariable2.java:21:14: compiler.err.try.with.resources.expr.needs.var
+TwrForVariable2.java:24:16: compiler.err.try.with.resources.expr.needs.var
+TwrForVariable2.java:27:31: compiler.err.try.with.resources.expr.needs.var
+6 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable3.java Wed Nov 19 13:46:04 2014 +0100
@@ -0,0 +1,29 @@
+/* @test /nodynamiccopyright/
+ * @bug 7196163
+ * @summary Verify that improper expressions used as an operand to try-with-resources are rejected.
+ * @compile/fail/ref=TwrForVariable3.out -XDrawDiagnostics -Xlint:-options TwrForVariable3.java
+ */
+public class TwrForVariable3 implements AutoCloseable {
+ public static void main(String... args) {
+ TwrForVariable3 v1 = new TwrForVariable3();
+ Object v2 = new Object();
+
+ try (v2) {
+ fail("no an AutoCloseable");
+ }
+ try (java.lang.Object) {
+ fail("not a variable access");
+ }
+ try (java.lang) {
+ fail("not a variable access");
+ }
+ }
+
+ static void fail(String reason) {
+ throw new RuntimeException(reason);
+ }
+
+ public void close() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable3.out Wed Nov 19 13:46:04 2014 +0100
@@ -0,0 +1,4 @@
+TwrForVariable3.java:11:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.AutoCloseable))
+TwrForVariable3.java:14:18: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null)
+TwrForVariable3.java:17:14: compiler.err.cant.resolve.location: kindname.variable, java, , , (compiler.misc.location: kindname.class, TwrForVariable3, null)
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable4.java Wed Nov 19 13:46:04 2014 +0100
@@ -0,0 +1,45 @@
+/* @test /nodynamiccopyright/
+ * @bug 7196163
+ * @summary Verify that variable used as an operand to try-with-resources is rejected if it is not
+ * definitelly assigned before use and or not final or effectivelly final.
+ * @compile/fail/ref=TwrForVariable4.out -XDrawDiagnostics -Xlint:-options TwrForVariable4.java
+ */
+public class TwrForVariable4 implements AutoCloseable {
+ public static void main(String... args) {
+ TwrForVariable4 uninitialized;
+
+ try (uninitialized) {
+ fail("must be initialized before use");
+ }
+ uninitialized = new TwrForVariable4();
+
+ TwrForVariable4 notEffectivellyFinal1 = new TwrForVariable4();
+
+ notEffectivellyFinal1 = new TwrForVariable4();
+
+ try (notEffectivellyFinal1) {
+ fail("not effectivelly final");
+ }
+
+ TwrForVariable4 notEffectivellyFinal2 = new TwrForVariable4();
+
+ try (notEffectivellyFinal2) {
+ notEffectivellyFinal2 = new TwrForVariable4();
+ fail("not effectivelly final");
+ }
+
+ try (notFinal) {
+ fail("not final");
+ }
+ }
+
+ static TwrForVariable4 notFinal = new TwrForVariable4();
+
+ static void fail(String reason) {
+ throw new RuntimeException(reason);
+ }
+
+ public void close() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable4.out Wed Nov 19 13:46:04 2014 +0100
@@ -0,0 +1,5 @@
+TwrForVariable4.java:11:14: compiler.err.var.might.not.have.been.initialized: uninitialized
+TwrForVariable4.java:20:14: compiler.err.try.with.resources.expr.effectively.final.var: notEffectivellyFinal1
+TwrForVariable4.java:26:14: compiler.err.try.with.resources.expr.effectively.final.var: notEffectivellyFinal2
+TwrForVariable4.java:31:14: compiler.err.try.with.resources.expr.effectively.final.var: notFinal
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TryWithResourcesExprEffectivelyFinalVar.java Wed Nov 19 13:46:04 2014 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.try.with.resources.expr.effectively.final.var
+
+class TryWithResourcesExprEffectivelyFinalVar {
+ void m() {
+ CloseableImpl ac = new CloseableImpl();
+
+ try (ac) {
+ ac = null;
+ }
+ }
+}
+
+class CloseableImpl implements AutoCloseable {
+ @Override
+ public void close() {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TryWithResourcesExprNeedsVar.java Wed Nov 19 13:46:04 2014 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.try.with.resources.expr.needs.var
+
+class TryWithResourcesExprNeedsVar {
+ void m() {
+ try (new CloseableImpl()) {
+ }
+ }
+}
+
+class CloseableImpl implements AutoCloseable {
+ @Override
+ public void close() throws Exception {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/VarInTryWithResourcesNotSupportedInSource.java Wed Nov 19 13:46:04 2014 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.var.in.try.with.resources.not.supported.in.source
+// key: compiler.warn.source.no.bootclasspath
+// options: -source 8
+
+class VarInTryWithResourcesNotSupportedInSource {
+ void m() {
+ AutoCloseable ac = new CloseableImpl();
+
+ try (ac) {
+ }
+ }
+}
+
+class CloseableImpl implements AutoCloseable {
+ @Override
+ public void close() throws Exception {
+ }
+}