[cfe-dev] ubsan: problem with detecting UB in shift operation with large RHS

Geoffrey Romer via cfe-dev cfe-dev at lists.llvm.org
Mon Dec 12 16:23:51 PST 2016


On Mon, Dec 12, 2016 at 3:27 PM, Kostya Serebryany via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> Is it actually undefined behavior?
>

Yes.


> What does the standard say about " int32_value >> int64_value" ?
> If int64_value should be first cast to int32, then there is no UB in:
>     res += 123 >> l;
>

The standard says that for >>, "integral promotions are performed", which
basically has no effect here (assuming int is 32 bits), and then says "The
type of the result is that of the promoted left operand". It does not
specify any conversion or casting of the right operand, other than integral
promotion.


>
> As for the first buggy line, there is a FE warning:
> b.c:6:19: warning: shift count >= width of type [-Wshift-count-overflow]
>     int res = 123 >> 0x100000000ULL;
>
> --kcc
>
>
>
>
> On Mon, Dec 12, 2016 at 2:46 PM, Dmitry Babokin <babokin at gmail.com> wrote:
>
>> Hello,
>>
>> I'm using ubsan together with creduce to ensure that reduced test doesn't
>> have UB. And I've noticed that ubsan is not detecting UB in case of large
>> shift amount, particularly when rhs of shift has larger type that lhs. To
>> reproduce, rhs also has to have the value that is non-zero, but after
>> truncation to lhs type the value becomes zero.
>>
>> Consider the following example.
>>
>> #include <stdio.h>
>>
>> // 1 is in 33rd bit.
>> unsigned long long l = 0x100000000ULL;
>>
>> int main() {
>>     // Ubsan doesn't fire
>>     int res = 123 >> 0x100000000ULL;
>>     // Ubsan doesn't fire
>>     res += 123 >> l;
>>     // Ubsan does fire
>>     res += 123ULL >> l;
>>     printf("result = %d\n", res);
>>     return 0;
>> }
>>
>> Changing the constant to the value, which fit 32 bits makes ubsan firing.
>>
>> I understand where the problem comes from - LLVM IR definition requires
>> both operands of the shift to be of the same integer type. And ubsan
>> actually check already truncated value. But it doesn't match C/C++ standard
>> definition of UB in shift operation.
>>
>> Is it possible to fix in current infrastructure? Should I file a bug for
>> this problem?
>>
>> Note, it's not a theoretical problem, it's very practical one, which pops
>> up during automatic test reduction relatively frequently for me.
>>
>> Dmitry.
>>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20161212/cd959c24/attachment.html>


More information about the cfe-dev mailing list