Thread overview
[Issue 23618] Right Shift equals expressions on unsigned shorts don't behave the same as regular shifts
Jan 13, 2023
mhh
Jan 14, 2023
Iain Buclaw
Jan 14, 2023
Walter Bright
Jan 14, 2023
Salih Dincer
[Issue 23618] Right Shift equals expressions on unsigned shorts should be unsigned right shift
Jan 14, 2023
Walter Bright
Jan 14, 2023
Dlang Bot
Jan 14, 2023
Walter Bright
Jan 14, 2023
Dlang Bot
Jan 14, 2023
Dlang Bot
January 13, 2023
https://issues.dlang.org/show_bug.cgi?id=23618

mhh <maxhaton@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|enhancement                 |blocker

--
January 14, 2023
https://issues.dlang.org/show_bug.cgi?id=23618

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |backend
                 CC|                            |ibuclaw@gdcproject.org

--- Comment #1 from Iain Buclaw <ibuclaw@gdcproject.org> ---
Only affects dmd.

--
January 14, 2023
https://issues.dlang.org/show_bug.cgi?id=23618

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #2 from Walter Bright <bugzilla@digitalmars.com> ---
The issue comes up because (ee >>= 5) is done as a signed right shift, even though ee is an unsigned type.

Step by step:

https://dlang.org/spec/expression.html#assignment_operator_expressions says:

    a op= b
    are semantically equivalent to:
    a = cast(typeof(a))(a op b)

so, (ee >>= 5) is rewritten to:

    ee = cast(ushort)(ee >> b);

https://dlang.org/spec/expression.html#shift_expressions says:

    the operands undergo integral promotions

    ee = cast(ushort)(cast(int)ee >> b)

or:

    ee = cast(ushort)((ee & 0x0000_FFFF) >> b)

then:

    >> is a signed right shift

but the sign bit is 0, so it is, in effect, an unsigned right shift. The compiler generates a signed right shift, though.

--
January 14, 2023
https://issues.dlang.org/show_bug.cgi?id=23618

Salih Dincer <salihdb@hotmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |salihdb@hotmail.com

--- Comment #3 from Salih Dincer <salihdb@hotmail.com> ---
The problem is also seen when the sign extension is not done.

Here is the test code:

struct TestType(T)
{
  import std.traits : Unsigned;
  alias U = Unsigned!T;

  T t = T.min;       // sample: -128 for byte
  U u = U.max/2 + 1; // sample: 128 for ubyte
}

void main()
{
  alias T = long; // int, short, byte

  TestType!T v1, v2;
  enum bits = T.sizeof * 8 - 1;

  v1.t >>= bits;
  assert(v1.t == -1); // okay, because signed type

  v1.u >>= bits;
  assert(v1.u == 1); // okay, because unsigned type

  v2.t >>>= bits;
  assert(v2.t == 1); /* okay, no sign extension
                        but  -1 for byte, short, int */
  v2.u >>>= bits;
  assert(v2.u == 1); // okay, no sign extension
}

SDB@79

--
January 14, 2023
https://issues.dlang.org/show_bug.cgi?id=23618

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Right Shift equals          |Right Shift equals
                   |expressions on unsigned     |expressions on unsigned
                   |shorts don't behave the     |shorts should be unsigned
                   |same as regular shifts      |right shift

--
January 14, 2023
https://issues.dlang.org/show_bug.cgi?id=23618

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #4 from Dlang Bot <dlang-bot@dlang.rocks> ---
@WalterBright created dlang/dmd pull request #14814 "fix Issue 23618 - Right Shift equals expressions on unsigned shorts s…" fixing this issue:

- fix Issue 23618 - Right Shift equals expressions on unsigned shorts should be unsigned right shift

https://github.com/dlang/dmd/pull/14814

--
January 14, 2023
https://issues.dlang.org/show_bug.cgi?id=23618

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Hardware|x86_64                      |All
                 OS|Linux                       |All

--
January 14, 2023
https://issues.dlang.org/show_bug.cgi?id=23618

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #5 from Dlang Bot <dlang-bot@dlang.rocks> ---
dlang/dmd pull request #14814 "fix Issue 23618 - Right Shift equals expressions on unsigned shorts s…" was merged into stable:

- 1a7eebc1a52954a56173f098ee5128bfbfe6b746 by Walter Bright:
  fix Issue 23618 - Right Shift equals expressions on unsigned shorts should be
unsigned right shift

https://github.com/dlang/dmd/pull/14814

--
January 14, 2023
https://issues.dlang.org/show_bug.cgi?id=23618

--- Comment #6 from Dlang Bot <dlang-bot@dlang.rocks> ---
dlang/dmd pull request #14815 "Merge stable" was merged into master:

- 579c97ab66ddc2c6a8f3db177937bb4c94353120 by Walter Bright:
  fix Issue 23618 - Right Shift equals expressions on unsigned shorts should be
unsigned right shift (#14814)

https://github.com/dlang/dmd/pull/14815

--