Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: Scala 2.10.0-M7
    • Fix Version/s: Scala 2.10.0-M7, Scala 2.10.0
    • Component/s: Compiler Backend
    • Labels:
      None
    • Environment:

      Scala version 2.10.0-20120906-051430-374b780f00

      Description

      Scala incorrectly optimizes away the if statement (without -optimize) in the following:

      scala> val x = if(error("x")) 0d else -0d
      x: Double = 0.0
      
      scala> val x = if(error("x")) 1d else 1d
      x: Double = 1.0
      

      The main problem is that although `0d == -0d` is true, it is wrong to treat them as the same. It seems plausible this kind of constant equality check might be applied elsewhere as well.

      Second, the side-effect in the if statement is discarded, although I don't know if there is a scenario where this could possibly matter.

        Activity

        Hide
        Jason Zaugg added a comment - - edited

        typedIf lubs the branches of the conditional:

        https://github.com/scala/scala/blob/2.10.x/src/compiler/scala/tools/nsc/typechecker/Typers.scala#L4072

        adapt replaces <expr>: ConstantType(x) with x

        https://github.com/scala/scala/blob/2.10.x/src/compiler/scala/tools/nsc/typechecker/Typers.scala#L1067

        Probable fixes:

        1. call .deconst before lubbing the types of the branches; make sure treatment is consistent in other places lubs are taken. (Or maybe: Do this in lub/glb itself)
        2. Update Const#equals to differentiate +-0d (it already has similar handling for NaN). I think we can use Double.doubleToRawLongBits(this.value) == Double.doubleToRawLongBits(that.value) (and the equivalent for Float) to handle all the floating point esoterica correctly.

        Show
        Jason Zaugg added a comment - - edited typedIf lubs the branches of the conditional: https://github.com/scala/scala/blob/2.10.x/src/compiler/scala/tools/nsc/typechecker/Typers.scala#L4072 adapt replaces <expr>: ConstantType(x) with x https://github.com/scala/scala/blob/2.10.x/src/compiler/scala/tools/nsc/typechecker/Typers.scala#L1067 Probable fixes: 1. call .deconst before lubbing the types of the branches; make sure treatment is consistent in other places lubs are taken. (Or maybe: Do this in lub/glb itself) 2. Update Const#equals to differentiate +-0d (it already has similar handling for NaN ). I think we can use Double.doubleToRawLongBits(this.value) == Double.doubleToRawLongBits(that.value) (and the equivalent for Float ) to handle all the floating point esoterica correctly.
        Hide
        Jason Zaugg added a comment -

        https://github.com/scala/scala/pull/1271

        My last comment wasn't accurate: deconst was already called by ptOrLub. The real problem was a new fast path that avoids lubbing, which was added by virtpatmat.

        Show
        Jason Zaugg added a comment - https://github.com/scala/scala/pull/1271 My last comment wasn't accurate: deconst was already called by ptOrLub . The real problem was a new fast path that avoids lubbing, which was added by virtpatmat.

          People

          • Assignee:
            Jason Zaugg
            Reporter:
            Mark Harrah
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development