phobos's circle CI runs a busted version of DMD

jmh530 john.michael.hall at gmail.com
Wed Jan 11 16:59:01 UTC 2023


On Wednesday, 11 January 2023 at 13:51:43 UTC, jmh530 wrote:
> On Wednesday, 11 January 2023 at 13:26:57 UTC, Dukc wrote:
>> On Wednesday, 11 January 2023 at 01:03:33 UTC, deadalnix wrote:
>>> Sample code:
>>> ```d
>>>     ushort ee = 1028;
>>>     ee <<= 5U;
>>>     ee >>= 5U;
>>>     writeln(ee);
>>> ```
>>>
>>> Regular compiler: https://godbolt.org/z/TcbjP76fW (prints 
>>> 1028)
>>> Circle CI: 64516 .
>>>
>>> Someone, the compiler manages to do a signed arithmetic shift 
>>> on an unsigned.
>>
>> [The spec 
>> says](https://dlang.org/spec/expression.html#shift_expressions) that `>>` means *signed* shift right. `>>>` is for unsigned shifts. So pedantically speaking, 64516 is the correct result.
>>
>> It's another issue whether that's good design though. For one, 
>> it breaks the rule "do what C does, or don't compile". It'd be 
>> more reasonable if `>>` was type-dependant shift right (as in 
>> C) IMO.
>
> Not really. If you just do `>>` (i.e. not `>>=`), then you get 
> 1028.
>
> ```d
> import core.stdc.stdio: printf;
> void main() {
>     ushort ee = 32896; //starting from the second shift
>     ushort ee_result = ee >> 5u;
>     printf("the value of ee_result is %d\n", ee_result); //the 
> value of ee_result is 1028
> }
> ```
>
> The problem is the combination with assignment, which is what 
> makes it seem like a bug. According to [1], "the right operand 
> is implicitly converted to the type of the left operand, and 
> assigned to it." So what should happen is that `5U` is 
> implicitly converted to `5` and a signed conversion should 
> happen. The result should be 1028. 64516 seems like a weird 
> result.
>
> [1] 
> https://dlang.org/spec/expression.html#simple_assignment_expressions

Upon further investigation, the problem goes away when you cast 
`5u` to ushort (since `5u` is a uint and not a ushort).

```d
import core.stdc.stdio: printf;
void main() {
     ushort ee = 32896; //starting from the second shift
     ee >>= (cast(ushort) 5u);
     printf("the value of ee is %d\n", ee); //the value of ee is 
1028
}
```

Not quite sure why the problem is there for the uint and not the 
ushort, but it could be related to the sequence of integer 
promotion and the casting. What happens seems inconsistent with 
the spec. One weird thing is that if you change the cast from 
ushort to ulong, then we don't have the problem. It is only uint 
where we get the weird result.


More information about the Digitalmars-d mailing list