Thu, 01 May 2014 11:35:02 -0700
8036942: javac generates incorrect exception table for multi-catch statements inside a lambda
Summary: Union type info lost and also union type is not processed by TreeMaker.Type -- address by using existing tree, thus by-passing such issues.
Reviewed-by: vromero, jlahoda
1.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Wed Apr 30 23:59:45 2014 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu May 01 11:35:02 2014 -0700 1.3 @@ -438,13 +438,9 @@ 1.4 public void visitVarDef(JCVariableDecl tree) { 1.5 LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context; 1.6 if (context != null && lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) { 1.7 - JCExpression init = translate(tree.init); 1.8 - int prevPos = make.pos; 1.9 - try { 1.10 - result = make.at(tree).VarDef((VarSymbol)lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym), init); 1.11 - } finally { 1.12 - make.at(prevPos); 1.13 - } 1.14 + tree.init = translate(tree.init); 1.15 + tree.sym = (VarSymbol) lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym); 1.16 + result = tree; 1.17 } else if (context != null && lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) { 1.18 JCExpression init = translate(tree.init); 1.19 VarSymbol xsym = (VarSymbol)lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym); 1.20 @@ -1895,7 +1891,7 @@ 1.21 }; 1.22 break; 1.23 case LOCAL_VAR: 1.24 - ret = new VarSymbol(sym.flags() & FINAL, name, types.erasure(sym.type), translatedSym); 1.25 + ret = new VarSymbol(sym.flags() & FINAL, name, sym.type, translatedSym); 1.26 ((VarSymbol) ret).pos = ((VarSymbol) sym).pos; 1.27 break; 1.28 case PARAM:
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/lambda/LambdaMultiCatchTest.java Thu May 01 11:35:02 2014 -0700 2.3 @@ -0,0 +1,58 @@ 2.4 +/* 2.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. Oracle designates this 2.11 + * particular file as subject to the "Classpath" exception as provided 2.12 + * by Oracle in the LICENSE file that accompanied this code. 2.13 + * 2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.17 + * version 2 for more details (a copy is included in the LICENSE file that 2.18 + * accompanied this code). 2.19 + * 2.20 + * You should have received a copy of the GNU General Public License version 2.21 + * 2 along with this work; if not, write to the Free Software Foundation, 2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.23 + * 2.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.25 + * or visit www.oracle.com if you need additional information or have any 2.26 + * questions. 2.27 + */ 2.28 + 2.29 +/** 2.30 + * @test 2.31 + * @bug 8036942 2.32 + * @summary javac generates incorrect exception table for multi-catch statements inside a lambda 2.33 + * @run main LambdaMultiCatchTest 2.34 + */ 2.35 + 2.36 +import java.io.IOException; 2.37 +import java.util.function.Function; 2.38 + 2.39 +public class LambdaMultiCatchTest { 2.40 + public static void main(String[] args) { 2.41 + Function<String,String> fi = x -> { 2.42 + String result = "nada"; 2.43 + try { 2.44 + switch (x) { 2.45 + case "IO": throw new IOException(); 2.46 + case "Illegal": throw new IllegalArgumentException(); 2.47 + case "Run": throw new RuntimeException(); 2.48 + } 2.49 + } catch (IOException|IllegalArgumentException ex) { 2.50 + result = "IO/Illegal"; 2.51 + } catch (Exception ex) { 2.52 + result = "Any"; 2.53 + }; 2.54 + return result; 2.55 + }; 2.56 + String val = fi.apply("Run"); 2.57 + if (!val.equals("Any")) { 2.58 + throw new AssertionError("Fail: Expected 'Any' but got '" + val + "'"); 2.59 + } 2.60 + } 2.61 +}