7041730: Regression: compiler accepts invalid cast from int to Byte

Wed, 11 May 2011 13:12:11 +0200

author
mcimadamore
date
Wed, 11 May 2011 13:12:11 +0200
changeset 1007
95fc7fd39be2
parent 1006
a2d422d480cb
child 1008
bdfa48f80c82

7041730: Regression: compiler accepts invalid cast from int to Byte
Summary: Implementation of cast conversion rules between primitive and boxed types is too liberal
Reviewed-by: jjg

src/share/classes/com/sun/tools/javac/code/Types.java file | annotate | diff | comparison | revisions
test/tools/javac/types/BoxingConversionTest.java file | annotate | diff | comparison | revisions
test/tools/javac/types/CastTest.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Wed May 11 13:10:57 2011 +0200
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Wed May 11 13:12:11 2011 +0200
     1.3 @@ -955,7 +955,9 @@
     1.4          if (t.isPrimitive() != s.isPrimitive())
     1.5              return allowBoxing && (
     1.6                      isConvertible(t, s, warn)
     1.7 -                    || (allowObjectToPrimitiveCast && isConvertible(s, t, warn)));
     1.8 +                    || (allowObjectToPrimitiveCast &&
     1.9 +                        s.isPrimitive() &&
    1.10 +                        isSubtype(boxedClass(s).type, t)));
    1.11          if (warn != warnStack.head) {
    1.12              try {
    1.13                  warnStack = warnStack.prepend(warn);
     2.1 --- a/test/tools/javac/types/BoxingConversionTest.java	Wed May 11 13:10:57 2011 +0200
     2.2 +++ b/test/tools/javac/types/BoxingConversionTest.java	Wed May 11 13:12:11 2011 +0200
     2.3 @@ -118,7 +118,6 @@
     2.4      static final Result T = Result.OK_BOTH;
     2.5      static final Result F = Result.FAIL_BOTH;
     2.6      static final Result A = Result.OK_ASSIGN_ONLY;
     2.7 -    static final Result X = Result.FAIL_BOTH.FAIL_BOTH;
     2.8  
     2.9      Result[][] results1 = {
    2.10                     //byte, short, int, long, float, double, char, bool, Byte, Short, Integer, Long, Float, Double, Character, Boolean
     3.1 --- a/test/tools/javac/types/CastTest.java	Wed May 11 13:10:57 2011 +0200
     3.2 +++ b/test/tools/javac/types/CastTest.java	Wed May 11 13:12:11 2011 +0200
     3.3 @@ -42,12 +42,13 @@
     3.4   */
     3.5  public class CastTest extends TypeHarness {
     3.6  
     3.7 -    Type[] allTypes;
     3.8 +    Type[] types_no_boxing;
     3.9 +    Type[] types_boxing;
    3.10  
    3.11      static final boolean T = true;
    3.12      static final boolean F = false;
    3.13  
    3.14 -    boolean[][] cast_result = {
    3.15 +    boolean[][] cast_result_no_boxing = {
    3.16                  //byte, short, int, long, float, double, char, bool, C, +C, I, T, byte[], short[], int[], long[], float[], double[], char[], bool[], C[], +C[], I[], T[]
    3.17      /*byte*/    { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
    3.18      /*short*/   { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
    3.19 @@ -74,6 +75,25 @@
    3.20      /*I[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , F   , T  , T },
    3.21      /*T[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , T   , T  , T }};
    3.22  
    3.23 +    boolean[][] cast_result_boxing = {
    3.24 +                   //byte, short, int, long, float, double, char, bool, Byte, Short, Integer, Long, Float, Double, Character, Boolean, Object
    3.25 +    /*byte*/       { T   , T    , T  , T   , T    , T     , T   , F   , T   , F    , F      , F   , F    , F     , F        , F ,      T },
    3.26 +    /*short*/      { T   , T    , T  , T   , T    , T     , T   , F   , F   , T    , F      , F   , F    , F     , F        , F ,      T  },
    3.27 +    /*int*/        { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , T      , F   , F    , F     , F        , F ,      T  },
    3.28 +    /*long*/       { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , T   , F    , F     , F        , F ,      T  },
    3.29 +    /*float*/      { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , T    , F     , F        , F ,      T  },
    3.30 +    /*double*/     { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , T     , F        , F ,      T  },
    3.31 +    /*char*/       { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , F     , T        , F ,      T  },
    3.32 +    /*bool*/       { F   , F    , F  , F   , F    , F     , F   , T   , F   , F    , F      , F   , F    , F     , F        , T ,      T  },
    3.33 +    /*Byte*/       { T   , T    , T  , T   , T    , T     , F   , F   , T   , F    , F      , F   , F    , F     , F        , F ,      T  },
    3.34 +    /*Short*/      { F   , T    , T  , T   , T    , T     , F   , F   , F   , T    , F      , F   , F    , F     , F        , F ,      T  },
    3.35 +    /*Integer*/    { F   , F    , T  , T   , T    , T     , F   , F   , F   , F    , T      , F   , F    , F     , F        , F ,      T  },
    3.36 +    /*Long*/       { F   , F    , F  , T   , T    , T     , F   , F   , F   , F    , F      , T   , F    , F     , F        , F ,      T  },
    3.37 +    /*Float*/      { F   , F    , F  , F   , T    , T     , F   , F   , F   , F    , F      , F   , T    , F     , F        , F ,      T  },
    3.38 +    /*Double*/     { F   , F    , F  , F   , F    , T     , F   , F   , F   , F    , F      , F   , F    , T     , F        , F ,      T  },
    3.39 +    /*Character*/  { F   , F    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , F     , T        , F ,      T  },
    3.40 +    /*Boolean*/    { F   , F    , F  , F   , F    , F     , F   , T   , F   , F    , F      , F   , F    , F     , F        , T ,      T  },
    3.41 +    /*Object*/     { T   , T    , T  , T   , T    , T     , T   , T   , T   , T    , T      , T   , T    , T     , T        , T ,      T  }};
    3.42      CastTest() {
    3.43          Type[] primitiveTypes = {
    3.44              predef.byteType,
    3.45 @@ -85,6 +105,15 @@
    3.46              predef.charType,
    3.47              predef.booleanType };
    3.48  
    3.49 +        Type[] boxedTypes = new Type[primitiveTypes.length + 1];
    3.50 +        for (int i = 0 ; i < primitiveTypes.length ; i++) {
    3.51 +            boxedTypes[i] = box(primitiveTypes[i]);
    3.52 +        }
    3.53 +
    3.54 +        boxedTypes[primitiveTypes.length] = predef.objectType;
    3.55 +
    3.56 +        types_boxing = join(Type.class, primitiveTypes, boxedTypes);
    3.57 +
    3.58          Type[] referenceTypes = {
    3.59              fac.Class(),
    3.60              fac.Class(FINAL),
    3.61 @@ -97,17 +126,22 @@
    3.62              arrayTypes[idx++] = fac.Array(t);
    3.63          }
    3.64  
    3.65 -        allTypes = join(Type.class, primitiveTypes, referenceTypes, arrayTypes);
    3.66 +        types_no_boxing = join(Type.class, primitiveTypes, referenceTypes, arrayTypes);
    3.67      }
    3.68  
    3.69 -    void test() {
    3.70 -        for (int i = 0; i < allTypes.length ; i++) {
    3.71 -            for (int j = 0; j < allTypes.length ; j++) {
    3.72 -                assertCastable(allTypes[i], allTypes[j], cast_result[i][j]);
    3.73 +    void test(Type[] all_types, boolean[][] cast_result) {
    3.74 +        for (int i = 0; i < all_types.length ; i++) {
    3.75 +            for (int j = 0; j < all_types.length ; j++) {
    3.76 +                assertCastable(all_types[i], all_types[j], cast_result[i][j]);
    3.77              }
    3.78          }
    3.79      }
    3.80  
    3.81 +    void runTests() {
    3.82 +        test(types_no_boxing, cast_result_no_boxing);
    3.83 +        test(types_boxing, cast_result_boxing);
    3.84 +    }
    3.85 +
    3.86      @SuppressWarnings("unchecked")
    3.87      <T> T[] join(Class<T> type, T[]... args) {
    3.88          int totalLength = 0;
    3.89 @@ -124,6 +158,6 @@
    3.90      }
    3.91  
    3.92      public static void main(String[] args) {
    3.93 -        new CastTest().test();
    3.94 +        new CastTest().runTests();
    3.95      }
    3.96  }

mercurial