Mon, 23 Jun 2014 13:14:32 -0700
8046060: Different results of floating point multiplication for lambda code block
Summary: propogate strictfp into lambda body
Reviewed-by: vromero, jlahoda
1.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Fri Jun 20 10:56:31 2014 -0600 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Jun 23 13:14:32 2014 -0700 1.3 @@ -1994,7 +1994,11 @@ 1.4 // If instance access isn't needed, make it static. 1.5 // Interface instance methods must be default methods. 1.6 // Lambda methods are private synthetic. 1.7 + // Inherit ACC_STRICT from the enclosing method, or, for clinit, 1.8 + // from the class. 1.9 translatedSym.flags_field = SYNTHETIC | LAMBDA_METHOD | 1.10 + owner.flags_field & STRICTFP | 1.11 + owner.owner.flags_field & STRICTFP | 1.12 PRIVATE | 1.13 (thisReferenced? (inInterface? DEFAULT : 0) : STATIC); 1.14
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/lambda/LambdaTestStrictFP.java Mon Jun 23 13:14:32 2014 -0700 2.3 @@ -0,0 +1,70 @@ 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. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +/* 2.28 + * @test 2.29 + * @bug 8046060 2.30 + * @summary Different results of floating point multiplication for lambda code block 2.31 + */ 2.32 + 2.33 +strictfp 2.34 +public class LambdaTestStrictFP { 2.35 + 2.36 + static double fld = eval(() -> { 2.37 + double x = Double.longBitsToDouble(0x1e7ee00000000000L); 2.38 + double y = Double.longBitsToDouble(0x2180101010101010L); 2.39 + 2.40 + return x * y; 2.41 + }); 2.42 + 2.43 + public static void main(String args[]) { 2.44 + double result = eval(() -> { 2.45 + double x = Double.longBitsToDouble(0x1e7ee00000000000L); 2.46 + double y = Double.longBitsToDouble(0x2180101010101010L); 2.47 + 2.48 + return x * y; 2.49 + }); 2.50 + { 2.51 + double x = Double.longBitsToDouble(0x1e7ee00000000000L); 2.52 + double y = Double.longBitsToDouble(0x2180101010101010L); 2.53 + 2.54 + double z = x * y; 2.55 + check(z, result, "method"); 2.56 + check(z, fld, "field"); 2.57 + } 2.58 + } 2.59 + 2.60 + private static void check(double expected, double got, String where) { 2.61 + if (got != expected) { 2.62 + throw new AssertionError(where + ": Non-strictfp " + got + " != " + expected); 2.63 + } 2.64 + } 2.65 + 2.66 + private static double eval(Face arg) { 2.67 + return arg.m(); 2.68 + } 2.69 + 2.70 + private interface Face { 2.71 + double m(); 2.72 + } 2.73 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/tools/javac/lambda/LambdaTestStrictFPFlag.java Mon Jun 23 13:14:32 2014 -0700 3.3 @@ -0,0 +1,76 @@ 3.4 +/* 3.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.23 + * or visit www.oracle.com if you need additional information or have any 3.24 + * questions. 3.25 + */ 3.26 + 3.27 +/* 3.28 + * @test 3.29 + * @bug 8046060 3.30 + * @summary Different results of floating point multiplication for lambda code block 3.31 + */ 3.32 + 3.33 +import java.io.*; 3.34 +import java.net.URL; 3.35 +import com.sun.tools.classfile.*; 3.36 +import static com.sun.tools.classfile.AccessFlags.ACC_STRICT; 3.37 + 3.38 +public class LambdaTestStrictFPFlag { 3.39 + public static void main(String[] args) throws Exception { 3.40 + new LambdaTestStrictFPFlag().run(); 3.41 + } 3.42 + 3.43 + void run() throws Exception { 3.44 + ClassFile cf = getClassFile("LambdaTestStrictFPFlag$Test.class"); 3.45 + ConstantPool cp = cf.constant_pool; 3.46 + boolean found = false; 3.47 + for (Method meth: cf.methods) { 3.48 + if (meth.getName(cp).startsWith("lambda$")) { 3.49 + if ((meth.access_flags.flags & ACC_STRICT) == 0) { 3.50 + throw new Exception("strict flag missing from lambda"); 3.51 + } 3.52 + found = true; 3.53 + } 3.54 + } 3.55 + if (!found) { 3.56 + throw new Exception("did not find lambda method"); 3.57 + } 3.58 + } 3.59 + 3.60 + ClassFile getClassFile(String name) throws IOException, ConstantPoolException { 3.61 + URL url = getClass().getResource(name); 3.62 + InputStream in = url.openStream(); 3.63 + try { 3.64 + return ClassFile.read(in); 3.65 + } finally { 3.66 + in.close(); 3.67 + } 3.68 + } 3.69 + 3.70 + class Test { 3.71 + strictfp void test() { 3.72 + Face itf = () -> { }; 3.73 + } 3.74 + } 3.75 + 3.76 + interface Face { 3.77 + void m(); 3.78 + } 3.79 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/lambda/LambdaTestStrictFPMethod.java Mon Jun 23 13:14:32 2014 -0700 4.3 @@ -0,0 +1,65 @@ 4.4 +/* 4.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + */ 4.26 + 4.27 +/* 4.28 + * @test 4.29 + * @bug 8046060 4.30 + * @summary Different results of floating point multiplication for lambda code block 4.31 + */ 4.32 + 4.33 +public class LambdaTestStrictFPMethod { 4.34 + 4.35 + public static void main(String args[]) { 4.36 + new LambdaTestStrictFPMethod().test(); 4.37 + } 4.38 + 4.39 + strictfp void test() { 4.40 + double result = eval(() -> { 4.41 + double x = Double.longBitsToDouble(0x1e7ee00000000000L); 4.42 + double y = Double.longBitsToDouble(0x2180101010101010L); 4.43 + 4.44 + return x * y; 4.45 + }); 4.46 + { 4.47 + double x = Double.longBitsToDouble(0x1e7ee00000000000L); 4.48 + double y = Double.longBitsToDouble(0x2180101010101010L); 4.49 + 4.50 + double z = x * y; 4.51 + check(z, result, "method"); 4.52 + } 4.53 + } 4.54 + 4.55 + strictfp void check(double expected, double got, String where) { 4.56 + if (got != expected) { 4.57 + throw new AssertionError(where + ": Non-strictfp " + got + " != " + expected); 4.58 + } 4.59 + } 4.60 + 4.61 + static double eval(Face arg) { 4.62 + return arg.m(); 4.63 + } 4.64 + 4.65 + interface Face { 4.66 + double m(); 4.67 + } 4.68 +}