summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.xml1
-rw-r--r--lib/fjbg.jar.desired.sha12
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala16
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java2
-rw-r--r--src/library/scala/runtime/BoxesRunTime.java25
-rw-r--r--test/files/run/bugs2087-and-2400.scala20
6 files changed, 36 insertions, 30 deletions
diff --git a/build.xml b/build.xml
index 47e5a679ca..5356fb114c 100644
--- a/build.xml
+++ b/build.xml
@@ -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)
+ }
+}