diff options
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scala/tools/scalac/typechecker/ConstantFolder.scala | 42 | ||||
-rw-r--r-- | sources/scalac/typechecker/ConstantFolder.java | 42 |
2 files changed, 70 insertions, 14 deletions
diff --git a/sources/scala/tools/scalac/typechecker/ConstantFolder.scala b/sources/scala/tools/scalac/typechecker/ConstantFolder.scala index 6f63dddf90..36855193cb 100644 --- a/sources/scala/tools/scalac/typechecker/ConstantFolder.scala +++ b/sources/scala/tools/scalac/typechecker/ConstantFolder.scala @@ -25,13 +25,41 @@ class ConstantFolder(ana: Analyzer) { */ def foldBinary(pos: int, left: Type$ConstantType, right: Type$ConstantType, op: Name): Type = { try { - var optype: Type = left.deconst(); - if (optype.symbol() == ana.definitions.BYTE_CLASS || - optype.symbol() == ana.definitions.CHAR_CLASS || - optype.symbol() == ana.definitions.SHORT_CLASS) - optype = ana.definitions.INT_TYPE(); - if (optype.isSubType(right.deconst())) - optype = right.deconst(); + var ltype: Type = left.deconst(); + var lsymbol: Symbol = left.symbol(); + if (lsymbol == ana.definitions.BYTE_CLASS || + lsymbol == ana.definitions.CHAR_CLASS || + lsymbol == ana.definitions.SHORT_CLASS) { + ltype = ana.definitions.INT_TYPE(); + lsymbol = ana.definitions.INT_CLASS; + } + var rtype: Type = right.deconst(); + var rsymbol: Symbol = right.symbol(); + if (rsymbol == ana.definitions.BYTE_CLASS || + rsymbol == ana.definitions.CHAR_CLASS || + rsymbol == ana.definitions.SHORT_CLASS) { + rtype = ana.definitions.INT_TYPE(); + rsymbol = ana.definitions.INT_CLASS; + } + val optype: Type = + if (ltype.isSameAs(rtype)) { + ltype; + } else { + if (lsymbol == ana.definitions.INT_CLASS) + rtype; + else if (rsymbol == ana.definitions.INT_CLASS) + ltype; + else if (lsymbol == ana.definitions.LONG_CLASS) + rtype; + else if (rsymbol == ana.definitions.LONG_CLASS) + ltype; + else if (lsymbol == ana.definitions.FLOAT_CLASS) + rtype; + else if (rsymbol == ana.definitions.FLOAT_CLASS) + ltype; + else + throw Debug.abort("illegal case", ltype.toString() +" - "+ rtype); + } var value: Object = null; optype.unbox() match { case Type$UnboxedType(INT) => diff --git a/sources/scalac/typechecker/ConstantFolder.java b/sources/scalac/typechecker/ConstantFolder.java index 125253a1b0..10738bb47d 100644 --- a/sources/scalac/typechecker/ConstantFolder.java +++ b/sources/scalac/typechecker/ConstantFolder.java @@ -29,13 +29,41 @@ class ConstantFolder implements /*imports*/ TypeTags { */ Type foldBinary(int pos, ConstantType left, ConstantType right, Name op) { try { - Type optype = left.deconst(); - if (optype.symbol() == ana.definitions.BYTE_CLASS || - optype.symbol() == ana.definitions.CHAR_CLASS || - optype.symbol() == ana.definitions.SHORT_CLASS) - optype = ana.definitions.INT_TYPE(); - if (optype.isSubType(right.deconst())) - optype = right.deconst(); + Type ltype = left.deconst(); + Symbol lsymbol = left.symbol(); + if (lsymbol == ana.definitions.BYTE_CLASS || + lsymbol == ana.definitions.CHAR_CLASS || + lsymbol == ana.definitions.SHORT_CLASS) { + ltype = ana.definitions.INT_TYPE(); + lsymbol = ana.definitions.INT_CLASS; + } + Type rtype = right.deconst(); + Symbol rsymbol = right.symbol(); + if (rsymbol == ana.definitions.BYTE_CLASS || + rsymbol == ana.definitions.CHAR_CLASS || + rsymbol == ana.definitions.SHORT_CLASS) { + rtype = ana.definitions.INT_TYPE(); + rsymbol = ana.definitions.INT_CLASS; + } + Type optype; + if (ltype.isSameAs(rtype)) { + optype = ltype; + } else { + if (lsymbol == ana.definitions.INT_CLASS) + optype = rtype; + else if (rsymbol == ana.definitions.INT_CLASS) + optype = ltype; + else if (lsymbol == ana.definitions.LONG_CLASS) + optype = rtype; + else if (rsymbol == ana.definitions.LONG_CLASS) + optype = ltype; + else if (lsymbol == ana.definitions.FLOAT_CLASS) + optype = rtype; + else if (rsymbol == ana.definitions.FLOAT_CLASS) + optype = ltype; + else + throw Debug.abort("illegal case", ltype + " - " + rtype); + } Object value = null; switch (optype.unbox()) { case UnboxedType(INT): |