Bug 19402 – specs for promotion rule of shift exp is wrong

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dlang.org
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-11-15T09:46:31Z
Last change time
2020-03-21T03:56:38Z
Keywords
pull, spec
Assigned to
No Owner
Creator
Dennis

Comments

Comment #0 by dkorpel — 2018-11-15T09:46:31Z
https://dlang.org/spec/expression.html#shift_expressions "If the operands are of integral types, they undergo the Usual Arithmetic Conversions, and then are brought to a common type using the Usual Arithmetic Conversions." https://dlang.org/spec/type.html#usual-arithmetic-conversions "If both are signed or both are unsigned, the smaller type is converted to the larger." Yet: ``` long x = 1L; auto a = 1 << x; ``` Compiles to: (-vcg-ast) ``` long x = 1L; int a = 1 << cast(int)x; ``` I expected this: ``` long x = 1L; long a = 1L << x; ``` Which caused a nasty bug in my program.
Comment #1 by b2.temp — 2019-02-14T10:29:25Z
There are changes required in phobos to apply the spec correctly. Maybe even a deprecation required (in which case i would pass my way). Attempt for now: https://github.com/dlang/dmd/pull/9361
Comment #2 by bugzilla — 2019-02-15T08:16:08Z
The spec is simply wrong. We need to follow the C conventions here, otherwise people will get nasty unexpected bugs. The C90 rule is: "The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined." C++98 is pretty much the same: "The operands shall be of integral or enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand." The D behavior is: exp.e1 = integralPromotions(exp.e1, sc); if (exp.e2.type.toBasetype().ty != Tvector) exp.e2 = exp.e2.castTo(sc, Type.tshiftcnt); which matches the C/C++ behavior. The compiler is right, the spec is wrong.
Comment #3 by bugzilla — 2019-02-15T08:37:31Z
Comment #4 by dlang-bot — 2019-07-17T11:02:48Z
@dkorpel created dlang/dlang.org pull request #2682 "fix Issue 19402 - specs for promotion rule of shift exp is wrong (without anything else)" fixing this issue: - fix Issue 19402 - specs for promotion rule of shift exp is wrong https://github.com/dlang/dlang.org/pull/2682
Comment #5 by dlang-bot — 2019-07-25T09:27:05Z
dlang/dlang.org pull request #2682 "fix Issue 19402 - specs for promotion rule of shift exp is wrong (without anything else)" was merged into master: - 67cd903107782b3f9055d40aca61854b590d9482 by dkorpel: fix Issue 19402 - specs for promotion rule of shift exp is wrong https://github.com/dlang/dlang.org/pull/2682