changeset 71:8a875638e902

meth-cast: remove need for double casting from Object to primitive
author jrose
date Thu, 26 Aug 2010 15:30:00 -0700
parents b733d7c4526e
children 1568fda1153b
files indy-bsm-6964498.patch meth-cast-6979683.patch series
diffstat 3 files changed, 1000 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/indy-bsm-6964498.patch	Thu Aug 26 15:25:16 2010 -0700
+++ b/indy-bsm-6964498.patch	Thu Aug 26 15:30:00 2010 -0700
@@ -555,8 +555,8 @@
 +                    else
 +                        methsel.sym = (MethodSymbol) newSym;
                      expr.type = targetType;
-                     transformedExpr = expr;
                  }
+             }
 diff --git a/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java b/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java
 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java
 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meth-cast-6979683.patch	Thu Aug 26 15:30:00 2010 -0700
@@ -0,0 +1,998 @@
+6979683: inconsistent interaction of reference cast with box/unbox conversions leaves out a useful case
+Summary: Allow casts which narrow and then unbox.
+Reviewed-by: ?
+
+Note:  The only significant test source file is TestCast6979683.java.  All the negative tests are trivially transformed copies of TestCast6979683.java.  The transformation was done by the script MakeNegTests.sh.
+
+diff --git a/src/share/classes/com/sun/tools/javac/code/Types.java b/src/share/classes/com/sun/tools/javac/code/Types.java
+--- a/src/share/classes/com/sun/tools/javac/code/Types.java
++++ b/src/share/classes/com/sun/tools/javac/code/Types.java
+@@ -914,7 +914,7 @@
+             return true;
+ 
+         if (t.isPrimitive() != s.isPrimitive())
+-            return allowBoxing && isConvertible(t, s, warn);
++            return allowBoxing && (isConvertible(t, s, warn) || isConvertible(s, t, warn));
+ 
+         if (warn != warnStack.head) {
+             try {
+diff --git a/src/share/classes/com/sun/tools/javac/comp/Lower.java b/src/share/classes/com/sun/tools/javac/comp/Lower.java
+--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java
++++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java
+@@ -2869,8 +2869,17 @@
+     /** Unbox an object to a primitive value. */
+     JCExpression unbox(JCExpression tree, Type primitive) {
+         Type unboxedType = types.unboxedType(tree.type);
+-        // note: the "primitive" parameter is not used.  There muse be
+-        // a conversion from unboxedType to primitive.
++        if (unboxedType.tag == NONE) {
++            unboxedType = primitive;
++            if (!unboxedType.isPrimitive())
++                throw new AssertionError(unboxedType);
++            make_at(tree.pos());
++            tree = make.TypeCast(types.boxedClass(unboxedType).type, tree);
++        } else {
++            // There must be a conversion from unboxedType to primitive.
++            if (!types.isSubtype(unboxedType, primitive))
++                throw new AssertionError(tree);
++        }
+         make_at(tree.pos());
+         Symbol valueSym = lookupMethod(tree.pos(),
+                                        unboxedType.tsym.name.append(names.Value), // x.intValue()
+diff --git a/test/tools/javac/6979683/MakeNegTests.sh b/test/tools/javac/6979683/MakeNegTests.sh
+new file mode 100644
+--- /dev/null
++++ b/test/tools/javac/6979683/MakeNegTests.sh
+@@ -0,0 +1,98 @@
++#!/bin/sh
++
++#
++# Copyright (c) 2010, 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.
++#
++
++## summary Verify correct rejection of erroneous casts that narrow and unbox at the same time
++## run shell MakeNegTests.sh
++
++default_template=TestCast6979683.java
++javacflags=''
++javac=${1-''}
++# the rest of this file is a generic "//BAD"-line tester
++
++: ${TESTSRC=.} ${TESTCLASSES=.}
++: ${javac:="${TESTJAVA+${TESTJAVA}/bin/}javac"}
++
++verbose=false quiet=false
++
++main() {
++  case "${@-}" in
++  *.java*)
++    for template in "$@"; do
++      expand_and_test "$template"
++    done;;
++  *) expand_and_test "${TESTSRC}/$default_template";;
++  esac
++}
++
++expand_and_test() {
++  template=$1
++  expand "$@"
++  testneg "$@"
++}
++
++expand() {
++  template=$1
++  badlines=` grep -n < "$template" '//BAD' `
++  badcount=` echo "$badlines" | wc -l `
++  [ $badcount -gt 0 ] || { echo "No negative test cases in $template"; exit 1; }
++  $quiet || echo "Expanding $badcount negative test cases from $template:"
++  $quiet || echo "$badlines"
++  badnums=` echo "$badlines" | sed 's/:.*//' `
++  casestem=` getcasestem "$template" `
++  tclassname=` basename "$template" .java `
++  rm -f "$casestem"*.java
++  for badnum in $badnums; do
++    casefile="$casestem"${badnum}.java
++    cclassname=` basename "$casefile" .java `
++    sed < "$template" > "$casefile" "
++      s|@compile|@compile/fail|
++      s|@run.*||
++      #/ @[a-z]/s|@|##|
++      ${badnum}s:^ *[/*]*:    :
++      s/${tclassname}/${cclassname}/g
++    "
++    $verbose && diff -u "$template" "$casefile"
++  done
++}
++
++getcasestem() {
++  echo `basename $1` | sed 's/\.java$//;s/_BAD[0-9]*$//;s/$/_BAD/'
++}
++
++testneg() {
++  template=$1
++  for casefile in ` getcasestem "$template" `*.java; do
++    $quiet || echo -------- $javac $javacflags "$casefile"
++    $javac $javacflags "$casefile" > "$casefile".errlog 2>&1 && {
++      echo "*** Compilation unexpectedly succeeded:  $casefile"
++      exit 1
++    }
++    $quiet || echo "Compilation failed as expected"
++    $quiet || head ` $verbose || echo -3 ` < "$casefile".errlog
++    rm "$casefile".errlog
++  done
++}
++
++main "$@"
+diff --git a/test/tools/javac/6979683/TestCast6979683.java b/test/tools/javac/6979683/TestCast6979683.java
+new file mode 100644
+--- /dev/null
++++ b/test/tools/javac/6979683/TestCast6979683.java
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (c) 2010, 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.
++ */
++
++/*
++ * @test
++ * @bug 6979683
++ * @summary Verify that casts can narrow and unbox at the same time
++ * @author jrose
++ *
++ * @compile TestCast6979683.java
++ * @run main TestCast6979683
++ */
++
++public class TestCast6979683 {
++    public static void main(String... av) {
++        bugReportExample();
++        for (int x = -1; x <= 2; x++) {
++            zconvTests(x != 0);
++            iconvTests(x);
++            bconvTests((byte)x);
++            cconvTests((char)x);
++        }
++        System.out.println("Successfully ran "+tests+" tests.");
++    }
++
++    static int tests;
++    static void assertEquals(Object x, Object y) {
++        if (!x.equals(y)) {
++            throw new RuntimeException("assertEquals: "+x+" != "+y);
++        }
++        ++tests;
++    }
++
++    static void bugReportExample() {
++  {} // example in bug report:
++  Object x = (Object)1;
++  int y = (int)x;
++  {} // end example
++    }
++
++    static boolean zconv1(Boolean o) { return o; }
++    static boolean zconv2(Object o) { return (boolean)o; }
++    static boolean zconv3(Comparable<Boolean> o) { return (boolean)o; }
++    //static boolean zconvBAD1(Number o) { return o; } //BAD
++
++    static void zconvTests(boolean x) {
++        assertEquals(x, zconv1(x));
++        assertEquals(x, zconv2(x));
++        assertEquals(x, zconv3(x));
++    }
++
++    static int iconv1(Integer o) { return o; }
++    static int iconv2(Object o) { return (int)o; }
++    static int iconv3(java.io.Serializable o) { return (int)o; }
++    static int iconv4(Number o) { return (int)o; }
++    static int iconv5(Comparable<Integer> o) { return (int)o; }
++    //static int iconvBAD1(Number o) { return o; } //BAD: cast needed
++    //static int iconvBAD2(Comparable<Integer> o) { return o; } //BAD: cast needed
++    //static int iconvBAD3(Comparable<Short> o) { return (int)o; } //BAD: wrong instance
++
++    static void iconvTests(int x) {
++        assertEquals(x, iconv1(x));
++        assertEquals(x, iconv2(x));
++        assertEquals(x, iconv3(x));
++        assertEquals(x, iconv4(x));
++        assertEquals(x, iconv5(x));
++    }
++
++    static float bconv1(Byte o) { return o; }  // note type "float"
++    static float bconv2(Object o) { return (byte)o; }
++    static float bconv3(java.io.Serializable o) { return (byte)o; }
++    static float bconv4(Number o) { return (byte)o; }
++
++    static void bconvTests(byte x) {
++        float xf = x;
++        assertEquals(xf, bconv1(x));
++        assertEquals(xf, bconv2(x));
++        assertEquals(xf, bconv3(x));
++        assertEquals(xf, bconv4(x));
++    }
++
++    static float cconv1(Character o) { return o; }  // note type "float"
++    static float cconv2(Object o) { return (char)o; }
++    static float cconv3(java.io.Serializable o) { return (char)o; }
++    static float cconv4(Comparable<Character> o) { return (char)o; }
++    //static float cconvBAD1(Comparable<Character> o) { return o; } //BAD
++    //static float cconvBAD2(Number o) { return (char)o; } //BAD
++
++    static void cconvTests(char x) {
++        float xf = x;
++        assertEquals(xf, cconv1(x));
++        assertEquals(xf, cconv2(x));
++        assertEquals(xf, cconv3(x));
++        assertEquals(xf, cconv4(x));
++    }
++
++}
+diff --git a/test/tools/javac/6979683/TestCast6979683_BAD106.java b/test/tools/javac/6979683/TestCast6979683_BAD106.java
+new file mode 100644
+--- /dev/null
++++ b/test/tools/javac/6979683/TestCast6979683_BAD106.java
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (c) 2010, 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.
++ */
++
++/*
++ * @test
++ * @bug 6979683
++ * @summary Verify that casts can narrow and unbox at the same time
++ * @author jrose
++ *
++ * @compile/fail TestCast6979683_BAD106.java
++ * 
++ */
++
++public class TestCast6979683_BAD106 {
++    public static void main(String... av) {
++        bugReportExample();
++        for (int x = -1; x <= 2; x++) {
++            zconvTests(x != 0);
++            iconvTests(x);
++            bconvTests((byte)x);
++            cconvTests((char)x);
++        }
++        System.out.println("Successfully ran "+tests+" tests.");
++    }
++
++    static int tests;
++    static void assertEquals(Object x, Object y) {
++        if (!x.equals(y)) {
++            throw new RuntimeException("assertEquals: "+x+" != "+y);
++        }
++        ++tests;
++    }
++
++    static void bugReportExample() {
++  {} // example in bug report:
++  Object x = (Object)1;
++  int y = (int)x;
++  {} // end example
++    }
++
++    static boolean zconv1(Boolean o) { return o; }
++    static boolean zconv2(Object o) { return (boolean)o; }
++    static boolean zconv3(Comparable<Boolean> o) { return (boolean)o; }
++    //static boolean zconvBAD1(Number o) { return o; } //BAD
++
++    static void zconvTests(boolean x) {
++        assertEquals(x, zconv1(x));
++        assertEquals(x, zconv2(x));
++        assertEquals(x, zconv3(x));
++    }
++
++    static int iconv1(Integer o) { return o; }
++    static int iconv2(Object o) { return (int)o; }
++    static int iconv3(java.io.Serializable o) { return (int)o; }
++    static int iconv4(Number o) { return (int)o; }
++    static int iconv5(Comparable<Integer> o) { return (int)o; }
++    //static int iconvBAD1(Number o) { return o; } //BAD: cast needed
++    //static int iconvBAD2(Comparable<Integer> o) { return o; } //BAD: cast needed
++    //static int iconvBAD3(Comparable<Short> o) { return (int)o; } //BAD: wrong instance
++
++    static void iconvTests(int x) {
++        assertEquals(x, iconv1(x));
++        assertEquals(x, iconv2(x));
++        assertEquals(x, iconv3(x));
++        assertEquals(x, iconv4(x));
++        assertEquals(x, iconv5(x));
++    }
++
++    static float bconv1(Byte o) { return o; }  // note type "float"
++    static float bconv2(Object o) { return (byte)o; }
++    static float bconv3(java.io.Serializable o) { return (byte)o; }
++    static float bconv4(Number o) { return (byte)o; }
++
++    static void bconvTests(byte x) {
++        float xf = x;
++        assertEquals(xf, bconv1(x));
++        assertEquals(xf, bconv2(x));
++        assertEquals(xf, bconv3(x));
++        assertEquals(xf, bconv4(x));
++    }
++
++    static float cconv1(Character o) { return o; }  // note type "float"
++    static float cconv2(Object o) { return (char)o; }
++    static float cconv3(java.io.Serializable o) { return (char)o; }
++    static float cconv4(Comparable<Character> o) { return (char)o; }
++    static float cconvBAD1(Comparable<Character> o) { return o; } //BAD
++    //static float cconvBAD2(Number o) { return (char)o; } //BAD
++
++    static void cconvTests(char x) {
++        float xf = x;
++        assertEquals(xf, cconv1(x));
++        assertEquals(xf, cconv2(x));
++        assertEquals(xf, cconv3(x));
++        assertEquals(xf, cconv4(x));
++    }
++
++}
+diff --git a/test/tools/javac/6979683/TestCast6979683_BAD107.java b/test/tools/javac/6979683/TestCast6979683_BAD107.java
+new file mode 100644
+--- /dev/null
++++ b/test/tools/javac/6979683/TestCast6979683_BAD107.java
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (c) 2010, 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.
++ */
++
++/*
++ * @test
++ * @bug 6979683
++ * @summary Verify that casts can narrow and unbox at the same time
++ * @author jrose
++ *
++ * @compile/fail TestCast6979683_BAD107.java
++ * 
++ */
++
++public class TestCast6979683_BAD107 {
++    public static void main(String... av) {
++        bugReportExample();
++        for (int x = -1; x <= 2; x++) {
++            zconvTests(x != 0);
++            iconvTests(x);
++            bconvTests((byte)x);
++            cconvTests((char)x);
++        }
++        System.out.println("Successfully ran "+tests+" tests.");
++    }
++
++    static int tests;
++    static void assertEquals(Object x, Object y) {
++        if (!x.equals(y)) {
++            throw new RuntimeException("assertEquals: "+x+" != "+y);
++        }
++        ++tests;
++    }
++
++    static void bugReportExample() {
++  {} // example in bug report:
++  Object x = (Object)1;
++  int y = (int)x;
++  {} // end example
++    }
++
++    static boolean zconv1(Boolean o) { return o; }
++    static boolean zconv2(Object o) { return (boolean)o; }
++    static boolean zconv3(Comparable<Boolean> o) { return (boolean)o; }
++    //static boolean zconvBAD1(Number o) { return o; } //BAD
++
++    static void zconvTests(boolean x) {
++        assertEquals(x, zconv1(x));
++        assertEquals(x, zconv2(x));
++        assertEquals(x, zconv3(x));
++    }
++
++    static int iconv1(Integer o) { return o; }
++    static int iconv2(Object o) { return (int)o; }
++    static int iconv3(java.io.Serializable o) { return (int)o; }
++    static int iconv4(Number o) { return (int)o; }
++    static int iconv5(Comparable<Integer> o) { return (int)o; }
++    //static int iconvBAD1(Number o) { return o; } //BAD: cast needed
++    //static int iconvBAD2(Comparable<Integer> o) { return o; } //BAD: cast needed
++    //static int iconvBAD3(Comparable<Short> o) { return (int)o; } //BAD: wrong instance
++
++    static void iconvTests(int x) {
++        assertEquals(x, iconv1(x));
++        assertEquals(x, iconv2(x));
++        assertEquals(x, iconv3(x));
++        assertEquals(x, iconv4(x));
++        assertEquals(x, iconv5(x));
++    }
++
++    static float bconv1(Byte o) { return o; }  // note type "float"
++    static float bconv2(Object o) { return (byte)o; }
++    static float bconv3(java.io.Serializable o) { return (byte)o; }
++    static float bconv4(Number o) { return (byte)o; }
++
++    static void bconvTests(byte x) {
++        float xf = x;
++        assertEquals(xf, bconv1(x));
++        assertEquals(xf, bconv2(x));
++        assertEquals(xf, bconv3(x));
++        assertEquals(xf, bconv4(x));
++    }
++
++    static float cconv1(Character o) { return o; }  // note type "float"
++    static float cconv2(Object o) { return (char)o; }
++    static float cconv3(java.io.Serializable o) { return (char)o; }
++    static float cconv4(Comparable<Character> o) { return (char)o; }
++    //static float cconvBAD1(Comparable<Character> o) { return o; } //BAD
++    static float cconvBAD2(Number o) { return (char)o; } //BAD
++
++    static void cconvTests(char x) {
++        float xf = x;
++        assertEquals(xf, cconv1(x));
++        assertEquals(xf, cconv2(x));
++        assertEquals(xf, cconv3(x));
++        assertEquals(xf, cconv4(x));
++    }
++
++}
+diff --git a/test/tools/javac/6979683/TestCast6979683_BAD64.java b/test/tools/javac/6979683/TestCast6979683_BAD64.java
+new file mode 100644
+--- /dev/null
++++ b/test/tools/javac/6979683/TestCast6979683_BAD64.java
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (c) 2010, 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.
++ */
++
++/*
++ * @test
++ * @bug 6979683
++ * @summary Verify that casts can narrow and unbox at the same time
++ * @author jrose
++ *
++ * @compile/fail TestCast6979683_BAD64.java
++ * 
++ */
++
++public class TestCast6979683_BAD64 {
++    public static void main(String... av) {
++        bugReportExample();
++        for (int x = -1; x <= 2; x++) {
++            zconvTests(x != 0);
++            iconvTests(x);
++            bconvTests((byte)x);
++            cconvTests((char)x);
++        }
++        System.out.println("Successfully ran "+tests+" tests.");
++    }
++
++    static int tests;
++    static void assertEquals(Object x, Object y) {
++        if (!x.equals(y)) {
++            throw new RuntimeException("assertEquals: "+x+" != "+y);
++        }
++        ++tests;
++    }
++
++    static void bugReportExample() {
++  {} // example in bug report:
++  Object x = (Object)1;
++  int y = (int)x;
++  {} // end example
++    }
++
++    static boolean zconv1(Boolean o) { return o; }
++    static boolean zconv2(Object o) { return (boolean)o; }
++    static boolean zconv3(Comparable<Boolean> o) { return (boolean)o; }
++    static boolean zconvBAD1(Number o) { return o; } //BAD
++
++    static void zconvTests(boolean x) {
++        assertEquals(x, zconv1(x));
++        assertEquals(x, zconv2(x));
++        assertEquals(x, zconv3(x));
++    }
++
++    static int iconv1(Integer o) { return o; }
++    static int iconv2(Object o) { return (int)o; }
++    static int iconv3(java.io.Serializable o) { return (int)o; }
++    static int iconv4(Number o) { return (int)o; }
++    static int iconv5(Comparable<Integer> o) { return (int)o; }
++    //static int iconvBAD1(Number o) { return o; } //BAD: cast needed
++    //static int iconvBAD2(Comparable<Integer> o) { return o; } //BAD: cast needed
++    //static int iconvBAD3(Comparable<Short> o) { return (int)o; } //BAD: wrong instance
++
++    static void iconvTests(int x) {
++        assertEquals(x, iconv1(x));
++        assertEquals(x, iconv2(x));
++        assertEquals(x, iconv3(x));
++        assertEquals(x, iconv4(x));
++        assertEquals(x, iconv5(x));
++    }
++
++    static float bconv1(Byte o) { return o; }  // note type "float"
++    static float bconv2(Object o) { return (byte)o; }
++    static float bconv3(java.io.Serializable o) { return (byte)o; }
++    static float bconv4(Number o) { return (byte)o; }
++
++    static void bconvTests(byte x) {
++        float xf = x;
++        assertEquals(xf, bconv1(x));
++        assertEquals(xf, bconv2(x));
++        assertEquals(xf, bconv3(x));
++        assertEquals(xf, bconv4(x));
++    }
++
++    static float cconv1(Character o) { return o; }  // note type "float"
++    static float cconv2(Object o) { return (char)o; }
++    static float cconv3(java.io.Serializable o) { return (char)o; }
++    static float cconv4(Comparable<Character> o) { return (char)o; }
++    //static float cconvBAD1(Comparable<Character> o) { return o; } //BAD
++    //static float cconvBAD2(Number o) { return (char)o; } //BAD
++
++    static void cconvTests(char x) {
++        float xf = x;
++        assertEquals(xf, cconv1(x));
++        assertEquals(xf, cconv2(x));
++        assertEquals(xf, cconv3(x));
++        assertEquals(xf, cconv4(x));
++    }
++
++}
+diff --git a/test/tools/javac/6979683/TestCast6979683_BAD77.java b/test/tools/javac/6979683/TestCast6979683_BAD77.java
+new file mode 100644
+--- /dev/null
++++ b/test/tools/javac/6979683/TestCast6979683_BAD77.java
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (c) 2010, 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.
++ */
++
++/*
++ * @test
++ * @bug 6979683
++ * @summary Verify that casts can narrow and unbox at the same time
++ * @author jrose
++ *
++ * @compile/fail TestCast6979683_BAD77.java
++ * 
++ */
++
++public class TestCast6979683_BAD77 {
++    public static void main(String... av) {
++        bugReportExample();
++        for (int x = -1; x <= 2; x++) {
++            zconvTests(x != 0);
++            iconvTests(x);
++            bconvTests((byte)x);
++            cconvTests((char)x);
++        }
++        System.out.println("Successfully ran "+tests+" tests.");
++    }
++
++    static int tests;
++    static void assertEquals(Object x, Object y) {
++        if (!x.equals(y)) {
++            throw new RuntimeException("assertEquals: "+x+" != "+y);
++        }
++        ++tests;
++    }
++
++    static void bugReportExample() {
++  {} // example in bug report:
++  Object x = (Object)1;
++  int y = (int)x;
++  {} // end example
++    }
++
++    static boolean zconv1(Boolean o) { return o; }
++    static boolean zconv2(Object o) { return (boolean)o; }
++    static boolean zconv3(Comparable<Boolean> o) { return (boolean)o; }
++    //static boolean zconvBAD1(Number o) { return o; } //BAD
++
++    static void zconvTests(boolean x) {
++        assertEquals(x, zconv1(x));
++        assertEquals(x, zconv2(x));
++        assertEquals(x, zconv3(x));
++    }
++
++    static int iconv1(Integer o) { return o; }
++    static int iconv2(Object o) { return (int)o; }
++    static int iconv3(java.io.Serializable o) { return (int)o; }
++    static int iconv4(Number o) { return (int)o; }
++    static int iconv5(Comparable<Integer> o) { return (int)o; }
++    static int iconvBAD1(Number o) { return o; } //BAD: cast needed
++    //static int iconvBAD2(Comparable<Integer> o) { return o; } //BAD: cast needed
++    //static int iconvBAD3(Comparable<Short> o) { return (int)o; } //BAD: wrong instance
++
++    static void iconvTests(int x) {
++        assertEquals(x, iconv1(x));
++        assertEquals(x, iconv2(x));
++        assertEquals(x, iconv3(x));
++        assertEquals(x, iconv4(x));
++        assertEquals(x, iconv5(x));
++    }
++
++    static float bconv1(Byte o) { return o; }  // note type "float"
++    static float bconv2(Object o) { return (byte)o; }
++    static float bconv3(java.io.Serializable o) { return (byte)o; }
++    static float bconv4(Number o) { return (byte)o; }
++
++    static void bconvTests(byte x) {
++        float xf = x;
++        assertEquals(xf, bconv1(x));
++        assertEquals(xf, bconv2(x));
++        assertEquals(xf, bconv3(x));
++        assertEquals(xf, bconv4(x));
++    }
++
++    static float cconv1(Character o) { return o; }  // note type "float"
++    static float cconv2(Object o) { return (char)o; }
++    static float cconv3(java.io.Serializable o) { return (char)o; }
++    static float cconv4(Comparable<Character> o) { return (char)o; }
++    //static float cconvBAD1(Comparable<Character> o) { return o; } //BAD
++    //static float cconvBAD2(Number o) { return (char)o; } //BAD
++
++    static void cconvTests(char x) {
++        float xf = x;
++        assertEquals(xf, cconv1(x));
++        assertEquals(xf, cconv2(x));
++        assertEquals(xf, cconv3(x));
++        assertEquals(xf, cconv4(x));
++    }
++
++}
+diff --git a/test/tools/javac/6979683/TestCast6979683_BAD78.java b/test/tools/javac/6979683/TestCast6979683_BAD78.java
+new file mode 100644
+--- /dev/null
++++ b/test/tools/javac/6979683/TestCast6979683_BAD78.java
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (c) 2010, 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.
++ */
++
++/*
++ * @test
++ * @bug 6979683
++ * @summary Verify that casts can narrow and unbox at the same time
++ * @author jrose
++ *
++ * @compile/fail TestCast6979683_BAD78.java
++ * 
++ */
++
++public class TestCast6979683_BAD78 {
++    public static void main(String... av) {
++        bugReportExample();
++        for (int x = -1; x <= 2; x++) {
++            zconvTests(x != 0);
++            iconvTests(x);
++            bconvTests((byte)x);
++            cconvTests((char)x);
++        }
++        System.out.println("Successfully ran "+tests+" tests.");
++    }
++
++    static int tests;
++    static void assertEquals(Object x, Object y) {
++        if (!x.equals(y)) {
++            throw new RuntimeException("assertEquals: "+x+" != "+y);
++        }
++        ++tests;
++    }
++
++    static void bugReportExample() {
++  {} // example in bug report:
++  Object x = (Object)1;
++  int y = (int)x;
++  {} // end example
++    }
++
++    static boolean zconv1(Boolean o) { return o; }
++    static boolean zconv2(Object o) { return (boolean)o; }
++    static boolean zconv3(Comparable<Boolean> o) { return (boolean)o; }
++    //static boolean zconvBAD1(Number o) { return o; } //BAD
++
++    static void zconvTests(boolean x) {
++        assertEquals(x, zconv1(x));
++        assertEquals(x, zconv2(x));
++        assertEquals(x, zconv3(x));
++    }
++
++    static int iconv1(Integer o) { return o; }
++    static int iconv2(Object o) { return (int)o; }
++    static int iconv3(java.io.Serializable o) { return (int)o; }
++    static int iconv4(Number o) { return (int)o; }
++    static int iconv5(Comparable<Integer> o) { return (int)o; }
++    //static int iconvBAD1(Number o) { return o; } //BAD: cast needed
++    static int iconvBAD2(Comparable<Integer> o) { return o; } //BAD: cast needed
++    //static int iconvBAD3(Comparable<Short> o) { return (int)o; } //BAD: wrong instance
++
++    static void iconvTests(int x) {
++        assertEquals(x, iconv1(x));
++        assertEquals(x, iconv2(x));
++        assertEquals(x, iconv3(x));
++        assertEquals(x, iconv4(x));
++        assertEquals(x, iconv5(x));
++    }
++
++    static float bconv1(Byte o) { return o; }  // note type "float"
++    static float bconv2(Object o) { return (byte)o; }
++    static float bconv3(java.io.Serializable o) { return (byte)o; }
++    static float bconv4(Number o) { return (byte)o; }
++
++    static void bconvTests(byte x) {
++        float xf = x;
++        assertEquals(xf, bconv1(x));
++        assertEquals(xf, bconv2(x));
++        assertEquals(xf, bconv3(x));
++        assertEquals(xf, bconv4(x));
++    }
++
++    static float cconv1(Character o) { return o; }  // note type "float"
++    static float cconv2(Object o) { return (char)o; }
++    static float cconv3(java.io.Serializable o) { return (char)o; }
++    static float cconv4(Comparable<Character> o) { return (char)o; }
++    //static float cconvBAD1(Comparable<Character> o) { return o; } //BAD
++    //static float cconvBAD2(Number o) { return (char)o; } //BAD
++
++    static void cconvTests(char x) {
++        float xf = x;
++        assertEquals(xf, cconv1(x));
++        assertEquals(xf, cconv2(x));
++        assertEquals(xf, cconv3(x));
++        assertEquals(xf, cconv4(x));
++    }
++
++}
+diff --git a/test/tools/javac/6979683/TestCast6979683_BAD79.java b/test/tools/javac/6979683/TestCast6979683_BAD79.java
+new file mode 100644
+--- /dev/null
++++ b/test/tools/javac/6979683/TestCast6979683_BAD79.java
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (c) 2010, 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.
++ */
++
++/*
++ * @test
++ * @bug 6979683
++ * @summary Verify that casts can narrow and unbox at the same time
++ * @author jrose
++ *
++ * @compile/fail TestCast6979683_BAD79.java
++ * 
++ */
++
++public class TestCast6979683_BAD79 {
++    public static void main(String... av) {
++        bugReportExample();
++        for (int x = -1; x <= 2; x++) {
++            zconvTests(x != 0);
++            iconvTests(x);
++            bconvTests((byte)x);
++            cconvTests((char)x);
++        }
++        System.out.println("Successfully ran "+tests+" tests.");
++    }
++
++    static int tests;
++    static void assertEquals(Object x, Object y) {
++        if (!x.equals(y)) {
++            throw new RuntimeException("assertEquals: "+x+" != "+y);
++        }
++        ++tests;
++    }
++
++    static void bugReportExample() {
++  {} // example in bug report:
++  Object x = (Object)1;
++  int y = (int)x;
++  {} // end example
++    }
++
++    static boolean zconv1(Boolean o) { return o; }
++    static boolean zconv2(Object o) { return (boolean)o; }
++    static boolean zconv3(Comparable<Boolean> o) { return (boolean)o; }
++    //static boolean zconvBAD1(Number o) { return o; } //BAD
++
++    static void zconvTests(boolean x) {
++        assertEquals(x, zconv1(x));
++        assertEquals(x, zconv2(x));
++        assertEquals(x, zconv3(x));
++    }
++
++    static int iconv1(Integer o) { return o; }
++    static int iconv2(Object o) { return (int)o; }
++    static int iconv3(java.io.Serializable o) { return (int)o; }
++    static int iconv4(Number o) { return (int)o; }
++    static int iconv5(Comparable<Integer> o) { return (int)o; }
++    //static int iconvBAD1(Number o) { return o; } //BAD: cast needed
++    //static int iconvBAD2(Comparable<Integer> o) { return o; } //BAD: cast needed
++    static int iconvBAD3(Comparable<Short> o) { return (int)o; } //BAD: wrong instance
++
++    static void iconvTests(int x) {
++        assertEquals(x, iconv1(x));
++        assertEquals(x, iconv2(x));
++        assertEquals(x, iconv3(x));
++        assertEquals(x, iconv4(x));
++        assertEquals(x, iconv5(x));
++    }
++
++    static float bconv1(Byte o) { return o; }  // note type "float"
++    static float bconv2(Object o) { return (byte)o; }
++    static float bconv3(java.io.Serializable o) { return (byte)o; }
++    static float bconv4(Number o) { return (byte)o; }
++
++    static void bconvTests(byte x) {
++        float xf = x;
++        assertEquals(xf, bconv1(x));
++        assertEquals(xf, bconv2(x));
++        assertEquals(xf, bconv3(x));
++        assertEquals(xf, bconv4(x));
++    }
++
++    static float cconv1(Character o) { return o; }  // note type "float"
++    static float cconv2(Object o) { return (char)o; }
++    static float cconv3(java.io.Serializable o) { return (char)o; }
++    static float cconv4(Comparable<Character> o) { return (char)o; }
++    //static float cconvBAD1(Comparable<Character> o) { return o; } //BAD
++    //static float cconvBAD2(Number o) { return (char)o; } //BAD
++
++    static void cconvTests(char x) {
++        float xf = x;
++        assertEquals(xf, cconv1(x));
++        assertEquals(xf, cconv2(x));
++        assertEquals(xf, cconv3(x));
++        assertEquals(xf, cconv4(x));
++    }
++
++}
--- a/series	Thu Aug 26 15:25:16 2010 -0700
+++ b/series	Thu Aug 26 15:30:00 2010 -0700
@@ -8,6 +8,7 @@
 
 # non-pushed files are under review or development, or merely experimental:
 meth.patch                      #-/meth #+d3564f381c7c
+meth-cast-6979683.patch         #-/meth #+d3564f381c7c
 meth-edrfix-6979327.patch       #-/meth #+d3564f381c7c
 indy-bsm-6964498.patch          #-/meth #+d3564f381c7c
 meth-ldc-6939203.patch          #-/meth #+d3564f381c7c #-/experimental #-testable