Skip to content

Incorrect specification of ShiftLeft Expression and ShiftRightExpression #632

@rcseacord

Description

@rcseacord

The following specification:

6.5.6:37 If the types of both operands are integer types, then the shift left expression evaluates to the value of the left operand whose bits are shifted left by the number of positions the right operand evaluates to. Vacated bits are filled with zeros. lhs << rhs evaluates to , casted to the type of the left operand. If the value of the right operand is negative or greater than or equal to the width of the left operand, then the operation results in an arithmetic overflow.

The same problem exists in 6.5.6:42.

The issue in both cases is that these operations are specified to result in arithmetic overflow.

However, arithmetic overflow allows the following behaviors:

6.23:2There are two allowed behaviors for arithmetic overflow:

6.23:3Evaluation of the expression may result in a panic.

6.23:4The resulting value of the expression may be truncated, discarding the most significant bits that do not fit in the target type.

The first is true for Debug, but the second is not true for Release. The value of the operator expression is not truncated. Instead, in performs a masked shift using LLVM semantics, effectively:
shift_amount = right_operand % bit_width

I'm not exactly sure what the actual behavior is, but my theory is that it is implementation defined.
For example:

  • left-shifting a 32-bit one by 32 bits yields 0 on ARM and PowerPC, but 1 on x86;
  • left-shifting a 32-bit one by 64 bits yields 0 on ARM, but 1 on x86 and PowerPC

If it's not implementation defined, it probably should be. There is no reason to emulate portable behavior in software for such an edge case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions