diff options
-rw-r--r-- | build.xml | 1 | ||||
-rw-r--r-- | lib/fjbg.jar.desired.sha1 | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala | 16 | ||||
-rw-r--r-- | src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java | 2 | ||||
-rw-r--r-- | src/library/scala/runtime/BoxesRunTime.java | 25 | ||||
-rw-r--r-- | test/files/run/bugs2087-and-2400.scala | 20 |
6 files changed, 36 insertions, 30 deletions
@@ -1128,6 +1128,7 @@ LIBRARIES (MSIL, FJBG maybe later) destdir="${build-libs.dir}/classes/fjbg" classpath="${build-libs.dir}/classes/fjbg" includes="**/*.java" + debug="true" target="1.5" source="1.4"> <compilerarg line="${javac.args}"/> </javac> diff --git a/lib/fjbg.jar.desired.sha1 b/lib/fjbg.jar.desired.sha1 index f7bb459d8a..059817251c 100644 --- a/lib/fjbg.jar.desired.sha1 +++ b/lib/fjbg.jar.desired.sha1 @@ -1 +1 @@ -3ddd34e6fda096e9624306b9fba8a1ee8e2ba97d ?fjbg.jar +6ef6a21997d01d64a3ff8447a0e110d04b3d6c7d ?fjbg.jar diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala index 8ed2b04045..2d586ba7ea 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala @@ -162,28 +162,36 @@ trait TypeKinds { self: ICodes => case object BYTE extends TypeKind { override def maxType(other: TypeKind): TypeKind = other match { - case BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE => other + case CHAR => INT + case BYTE | SHORT | INT | LONG | FLOAT | DOUBLE => other case REFERENCE(NothingClass) => BYTE case _ => abort("Uncomparable type kinds: BYTE with " + other) } } + /** Note that the max of Char/Byte and Char/Short is Int, because + * neither strictly encloses the other due to unsignedness. + * See ticket #2087 for a consequence. + */ + /** A 2-byte signed integer */ case object SHORT extends TypeKind { override def maxType(other: TypeKind): TypeKind = other match { - case BYTE | SHORT | CHAR => SHORT + case CHAR => INT + case BYTE | SHORT => SHORT case REFERENCE(NothingClass) => SHORT case INT | LONG | FLOAT | DOUBLE => other case _ => abort("Uncomparable type kinds: SHORT with " + other) } } - /** A 2-byte signed integer */ + /** A 2-byte UNSIGNED integer */ case object CHAR extends TypeKind { override def maxType(other: TypeKind): TypeKind = other match { - case BYTE | SHORT | CHAR => CHAR + case CHAR => CHAR + case BYTE | SHORT => INT case REFERENCE(NothingClass) => CHAR case INT | LONG | FLOAT | DOUBLE => other case _ => abort("Uncomparable type kinds: CHAR with " + other) diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java b/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java index b8f29a6a2b..6ee18a59df 100644 --- a/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java +++ b/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java @@ -74,7 +74,7 @@ public class JExtendedCode extends JCode { }, { /* T_SHORT -> T_BOOLEAN */ forbidden, - /* T_SHORT -> T_CHAR */ nothingToDo, + /* T_SHORT -> T_CHAR */ {JOpcode.I2C}, /* T_SHORT -> T_FLOAT */ {JOpcode.I2F}, /* T_SHORT -> T_DOUBLE */ {JOpcode.I2D}, /* T_SHORT -> T_BYTE */ {JOpcode.I2B}, diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java index 869eb375ac..b1cc464513 100644 --- a/src/library/scala/runtime/BoxesRunTime.java +++ b/src/library/scala/runtime/BoxesRunTime.java @@ -54,30 +54,7 @@ public class BoxesRunTime } public static Character boxToCharacter(char c) { - // !!! Temporarily working around the "impossible" (?) fact that - // c can have a negative value here. In any revision since r17461 try: - // def foo = new (Short => Char) { def apply(x: Short) = x.toChar } - // foo(-100) - // and the -100 will get to Character, which will duly crash. - // The bug was masked before because the Characters were created - // with "new Character(c)", but now the static method uses the argument - // as an index into a cache array, which can't be negative. - // - // It appears to be Short-specific; I can't get anything similar - // out of Byte or Int. - Character ret; - - // straightforward workarounds like bitmasking do not seem to - // work here; is java optimizing out "impossible" tests/ops? I - // don't know, but this is the safe way: - try { - ret = Character.valueOf(c); - } - catch (ArrayIndexOutOfBoundsException e) { - ret = new Character(c); - } - - return ret; + return Character.valueOf(c); } public static Byte boxToByte(byte b) { diff --git a/test/files/run/bugs2087-and-2400.scala b/test/files/run/bugs2087-and-2400.scala new file mode 100644 index 0000000000..19a5df26e3 --- /dev/null +++ b/test/files/run/bugs2087-and-2400.scala @@ -0,0 +1,20 @@ +object Test +{ + def negativeCharMaker = new (Short => Char) { def apply(x: Short) = x.toChar } + def main(args: Array[String]): Unit = { + // throws exception if -100 gets to Character.valueOf + val x = negativeCharMaker(-100) + + // chars are unsigned, they should never be equal to negative values + assert((-100).toShort != (-100).toChar) + assert((-100).toChar != (-100).toShort) + assert((-100).toChar != (-100).toByte) + assert((-100).toByte != (-100).toChar) + + // BoxesRunTime must agree as well + assert(((-100).toShort: Any) != (-100).toChar) + assert(((-100).toChar: Any) != (-100).toShort) + assert(((-100).toChar: Any) != (-100).toByte) + assert(((-100).toByte: Any) != (-100).toChar) + } +} |