Java 7 - Floating point literals drop their sign when converting to constant

Issue #223 resolved
Olivier Hamel created an issue

J4 & J7 modes have different implementations for <F32/F64>.constant(). J4's impl' appears to consider the sign when emitting Constants. (Not tested, just reading the code.) J7's impl' feeds normalizeDigits, which drops the sign, to parseFloat.

Demonstrator:

float f = Double.NEGATIVE_INFINITY;

Const-expr-ness will propagate from Double.NEGATIVE_INFINITY, which will lead to an attempt to parse "Infinity". This constant occurs b/c Double was loaded from a class file; the literal's token was synthesised from the bytecode by toStringing the F64 value.

Suggested hot-fix for this & the other issue I'm about to open regarding POSITIVE_INFINITY:

  eq FloatingPointLiteral.constant() {
    try {
      float value;
      if (getLITERAL().equals(Float.POSITIVE_INFINITY + ""))
        value = Float.POSITIVE_INFINITY;
      else if (getLITERAL().equals(Float.NEGATIVE_INFINITY + ""))
        value = Float.NEGATIVE_INFINITY;
      else if (getLITERAL().equals(Float.NaN + ""))
        value = Float.NaN;
      else
        value = Float.parseFloat((isNegative() ? "-" : "") + normalizedDigits());

      return Constant.create(value);
    } catch (NumberFormatException e) {
      Constant c = Constant.create(0.0f);
      c.error = true;
      return c;
    }
  }

Same general idea for DoubleLiteral.

Comments (7)

  1. Olivier Hamel reporter

    NOTE: You won't generally see this when parsing java source code because there'll be a MinusExpr as the parent to the literal. You'll mostly get kicked by this when loading constant fields from class files.

  2. Jesper Öqvist

    It seems better to just store the bytecode constant value in the literal class and recall it when building a Constant object, instead of having to parse the pretty-printed version of the literal.

  3. Jesper Öqvist

    Thank you for reporting this issue! Numeric bytecode constants will no longer be round-tripped through strings.

  4. Jesper Öqvist

    Avoid redundant constant number string round-trip

    This avoids converting bytecode constant numbers to string and then back. This fixes an error where some input bytecode constants were not correctly propagated to bytecode output.

    fixes #223 (bitbucket)

    → <<cset 53f9cf3e95ad>>

  5. Olivier Hamel reporter
    • edited description

    Minor correction of hot-fix. Generalised to handle NaNs. Does not preserve the exact NaN value.

  6. Log in to comment