rust-lang / rust-lang/fls

Incorrect specification of ShiftLeft Expression and ShiftRightExpression

Open
#632 13 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
reStructuredText
Stars
497
Forks
41
Avg merge
3h 52m
Merged PRs (30d)
4

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing FLS clauses 6.5.6:37 and 6.5.6:42 alongside the arithmetic-overflow rules in 6.23:2-4. Compare the specified behavior with the Debug and Release shift behavior described in the issue, then update both clauses so the specification accurately classifies out-of-range shift amounts.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, documentation
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.