7166455: javac doesn't set ACC_STRICT bit on <clinit> for strictfp class
Reviewed-by: mcimadamore
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Feb 07 20:47:06 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Feb 08 09:12:37 2013 +0000
@@ -1099,8 +1099,9 @@
Env<AttrContext> localEnv =
env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
localEnv.info.scope.owner =
- new MethodSymbol(tree.flags | BLOCK, names.empty, null,
- env.info.scope.owner);
+ new MethodSymbol(tree.flags | BLOCK |
+ env.info.scope.owner.flags() & STRICTFP, names.empty, null,
+ env.info.scope.owner);
if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
// Attribute all type annotations in the block
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Feb 07 20:47:06 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Feb 08 09:12:37 2013 +0000
@@ -1023,7 +1023,7 @@
};
/** Check that given modifiers are legal for given symbol and
- * return modifiers together with any implicit modififiers for that symbol.
+ * return modifiers together with any implicit modifiers for that symbol.
* Warning: we can't use flags() here since this method
* is called during class enter, when flags() would cause a premature
* completion.
@@ -1069,7 +1069,7 @@
}
// Imply STRICTFP if owner has STRICTFP set.
if (((flags|implicit) & Flags.ABSTRACT) == 0)
- implicit |= sym.owner.flags_field & STRICTFP;
+ implicit |= sym.owner.flags_field & STRICTFP;
break;
case TYP:
if (sym.isLocal()) {
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Feb 07 20:47:06 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Fri Feb 08 09:12:37 2013 +0000
@@ -513,7 +513,8 @@
// that contains them as its body.
if (clinitCode.length() != 0) {
MethodSymbol clinit = new MethodSymbol(
- STATIC, names.clinit,
+ STATIC | (c.flags() & STRICTFP),
+ names.clinit,
new MethodType(
List.<Type>nil(), syms.voidType,
List.<Type>nil(), syms.methodClass),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java Fri Feb 08 09:12:37 2013 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2013, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 7166455
+ * @summary javac doesn't set ACC_STRICT bit on <clinit> for strictfp class
+ * @run main CheckACC_STRICTFlagOnclinitTest
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.File;
+import java.io.IOException;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Descriptor;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
+import com.sun.tools.classfile.Method;
+
+import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
+
+public strictfp class CheckACC_STRICTFlagOnclinitTest {
+ private static final String AssertionErrorMessage =
+ "All methods should have the ACC_STRICT access flag " +
+ "please check output";
+ private static final String offendingMethodErrorMessage =
+ "Method %s of class %s doesn't have the ACC_STRICT access flag";
+
+ static {
+ class Foo {
+ class Bar {
+ void m11() {}
+ }
+ void m1() {}
+ }
+ }
+ void m2() {
+ class Any {
+ void m21() {}
+ }
+ }
+
+ private List<String> errors = new ArrayList<>();
+
+ public static void main(String[] args)
+ throws IOException, ConstantPoolException, InvalidDescriptor {
+ new CheckACC_STRICTFlagOnclinitTest().run();
+ }
+
+ private void run()
+ throws IOException, ConstantPoolException, InvalidDescriptor {
+ String testClasses = System.getProperty("test.classes");
+ check(testClasses,
+ "CheckACC_STRICTFlagOnclinitTest.class",
+ "CheckACC_STRICTFlagOnclinitTest$1Foo.class",
+ "CheckACC_STRICTFlagOnclinitTest$1Foo$Bar.class",
+ "CheckACC_STRICTFlagOnclinitTest$1Any.class");
+ if (errors.size() > 0) {
+ for (String error: errors) {
+ System.err.println(error);
+ }
+ throw new AssertionError(AssertionErrorMessage);
+ }
+ }
+
+ void check(String dir, String... fileNames)
+ throws
+ IOException,
+ ConstantPoolException,
+ Descriptor.InvalidDescriptor {
+ for (String fileName : fileNames) {
+ ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName));
+
+ for (Method method : classFileToCheck.methods) {
+ if ((method.access_flags.flags & ACC_STRICT) == 0) {
+ errors.add(String.format(offendingMethodErrorMessage,
+ method.getName(classFileToCheck.constant_pool),
+ classFileToCheck.getName()));
+ }
+ }
+ }
+ }
+
+}