Обсуждение: BUG #16790: Integer overflow not detected with <<

Поиск
Список
Период
Сортировка

BUG #16790: Integer overflow not detected with <<

От
PG Bug reporting form
Дата:
The following bug has been logged on the website:

Bug reference:      16790
Logged by:          Alexander Lakhin
Email address:      exclusion@gmail.com
PostgreSQL version: 13.1
Operating system:   Ubuntu 20.04
Description:

It seems that the bitwise shift left operator ignores overflow:
SELECT -1::int4<<32;
-1
But:
SELECT (-1::int4<<31) * 2;
ERROR:  integer out of range

Is this an expected behavior (a kind of UB)? It's not like an arithmetic
shift. (The semantic of '1::int4<<-1' is questionable too.)


Re: BUG #16790: Integer overflow not detected with <<

От
Tom Lane
Дата:
PG Bug reporting form <noreply@postgresql.org> writes:
> It seems that the bitwise shift left operator ignores overflow:
> Is this an expected behavior (a kind of UB)? It's not like an arithmetic
> shift. (The semantic of '1::int4<<-1' is questionable too.)

It's defined to do whatever the C << operator does.  That will certainly
not involve throwing an error.

            regards, tom lane



Re: BUG #16790: Integer overflow not detected with <<

От
Alexander Lakhin
Дата:
23.12.2020 18:29, Tom Lane wrote:
> PG Bug reporting form <noreply@postgresql.org> writes:
>> It seems that the bitwise shift left operator ignores overflow:
>> Is this an expected behavior (a kind of UB)? It's not like an arithmetic
>> shift. (The semantic of '1::int4<<-1' is questionable too.)
> It's defined to do whatever the C << operator does.  That will certainly
> not involve throwing an error.
Unfortunately, the behavior of the C << operator varies from defined to
implementation-defined and undefined. In fact I found this issue when
executing that query in an instance built with "-fsanitize=undefined".
Also I found an interesting reading about the shift operator:

https://devblogs.microsoft.com/cppblog/hello-arm-exploring-undefined-unspecified-and-implementation-defined-behavior-in-c/
So it's not that simple to describe the expected result of the operator
for all cases/platforms/architectures. It seems that a user is left with
"just try and see" or "avoid illegal values" approach.
On the other hand, there are pg_{mul,add,sub}_s{16,32,64}_overflow()
functions. Aren't they purposed to provide a well-defined behaviour for
related arithmetic operators?
Maybe the bitwise shift can be thought as something different from
arithmetic shift, and i<<1 is not the same as i*2, but in my opinion
it's not that could be expected at the database level.

Best regards,
Alexander