Обсуждение: BUG #5592: list of integer undefined behaviors

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

BUG #5592: list of integer undefined behaviors

От
"John Regehr"
Дата:
The following bug has been logged online:

Bug reference:      5592
Logged by:          John Regehr
Email address:      regehr@cs.utah.edu
PostgreSQL version: head 8/1/10
Operating system:   OSX
Description:        list of integer undefined behaviors
Details:

Below: a list of integer undefined behaviors that occur when running "make
check" on yesterday's postgresql on an x86-64 Mac Mini.

Here we're using the ANSI C rules for overflow.  Of course many/most of
these errors are not errors when the -fwrapv rules are in effect.

The last error in the list I already reported, just leaving it in for
completeness.

If more details are needed please let me know.

John Regehr



<bitmapset.c, (752:8)> : Op: -, Reason : Signed Subtraction Overflow, UNARY
OPERATION: right (int32): -2147483648

<int.c, (1002:16)> : Op: -, Reason : Signed Subtraction Overflow, BINARY
OPERATION: left (int32): -2147483647 right (int32): 2

<int.c, (1023:16)> : Op: *, Reason : Signed Multiplication Overflow, BINARY
OPERATION: left (int32): 2147483647 right (int32): 2

<int.c, (641:16)> : Op: +, Reason : Signed Addition Overflow, BINARY
OPERATION: left (int32): 2147483647 right (int32): 2

<int.c, (662:16)> : Op: -, Reason : Signed Subtraction Overflow, BINARY
OPERATION: left (int32): -2147483647 right (int32): 2

<int.c, (695:16)> : Op: *, Reason : Signed Multiplication Overflow, BINARY
OPERATION: left (int32): 2147483647 right (int32): 2

<int.c, (981:16)> : Op: +, Reason : Signed Addition Overflow, BINARY
OPERATION: left (int32): 2147483647 right (int32): 2

<int8.c, (1028:16)> : Op: +, Reason : Signed Addition Overflow, BINARY
OPERATION: left (int64): 100 right (int64): 9223372036854775800

<int8.c, (1049:16)> : Op: -, Reason : Signed Subtraction Overflow, BINARY
OPERATION: left (int64): -100 right (int64): 9223372036854775800

<int8.c, (104:23)> : Op: *, Reason : Signed Multiplication Overflow, BINARY
OPERATION: left (int64): 3908203590239580293 right (int64): 10

<int8.c, (104:28)> : Op: +, Reason : Signed Addition Overflow, BINARY
OPERATION: left (int64): 9223372036854775800 right (int64): 9

<int8.c, (1070:16)> : Op: *, Reason : Signed Multiplication Overflow, BINARY
OPERATION: left (int64): 100 right (int64): 9223372036854775800

<int8.c, (497:11)> : Op: -, Reason : Signed Subtraction Overflow, UNARY
OPERATION: right (int64): -9223372036854775808

<int8.c, (521:16)> : Op: +, Reason : Signed Addition Overflow, BINARY
OPERATION: left (int64): 9223372036854775800 right (int64):
9223372036854775800

<int8.c, (542:16)> : Op: -, Reason : Signed Subtraction Overflow, BINARY
OPERATION: left (int64): 9223372036854775800 right (int64):
-9223372036854775800

<int8.c, (563:16)> : Op: *, Reason : Signed Multiplication Overflow, BINARY
OPERATION: left (int64): 4567890123456789 right (int64): 4567890123456789

<int8.c, (623:24)> : Op: -, Reason : Signed Subtraction Overflow, UNARY
OPERATION: right (int64): -9223372036854775808

<int8.c, (748:16)> : Op: +, Reason : Signed Addition Overflow, BINARY
OPERATION: left (int64): 9223372036854775800 right (int64): 100

<int8.c, (769:16)> : Op: -, Reason : Signed Subtraction Overflow, BINARY
OPERATION: left (int64): -9223372036854775800 right (int64): 100

<int8.c, (790:16)> : Op: *, Reason : Signed Multiplication Overflow, BINARY
OPERATION: left (int64): 9223372036854775800 right (int64): 100

<int8.c, (844:16)> : Op: +, Reason : Signed Addition Overflow, BINARY
OPERATION: left (int64): 100 right (int64): 9223372036854775800

<int8.c, (865:16)> : Op: -, Reason : Signed Subtraction Overflow, BINARY
OPERATION: left (int64): -100 right (int64): 9223372036854775800

<int8.c, (886:16)> : Op: *, Reason : Signed Multiplication Overflow, BINARY
OPERATION: left (int64): 100 right (int64): 9223372036854775800

<int8.c, (932:16)> : Op: +, Reason : Signed Addition Overflow, BINARY
OPERATION: left (int64): 9223372036854775800 right (int64): 100

<int8.c, (953:16)> : Op: -, Reason : Signed Subtraction Overflow, BINARY
OPERATION: left (int64): -9223372036854775800 right (int64): 100

<int8.c, (974:16)> : Op: *, Reason : Signed Multiplication Overflow, BINARY
OPERATION: left (int64): 9223372036854775800 right (int64): 100

<nabstime.c, (1193:21)> : Op: -, Reason : Signed Subtraction Overflow,
BINARY OPERATION: left (int32): 2147483644 right (int32): -2147483648

<nabstime.c, (1194:21)> : Op: -, Reason : Signed Subtraction Overflow,
BINARY OPERATION: left (int32): 2147483644 right (int32): -2147483648

<tsquery_util.c, (48:18)> : Op: <<, Reason : Signed Left Shift Error: Right
operand is negative or is greater than or equal to the width of the promoted
left operand, BINARY OPERATION: left (int32): 1 right (int32): -25

Re: BUG #5592: list of integer undefined behaviors

От
Greg Stark
Дата:
On Mon, Aug 2, 2010 at 7:16 PM, John Regehr <regehr@cs.utah.edu> wrote:
> <nabstime.c, (1193:21)> : Op: -, Reason : Signed Subtraction Overflow,
> BINARY OPERATION: left (int32): 2147483644 right (int32): -2147483648
>
> <nabstime.c, (1194:21)> : Op: -, Reason : Signed Subtraction Overflow,
> BINARY OPERATION: left (int32): 2147483644 right (int32): -2147483648
>

These seem to imply that tinterval can contain a start point greater
than its end point. I'm not familiar with the rep invariant of
tinterval well enough to know if that's true or an indication of a bug
elsewhere. I suppose it doesn't matter for cmp since it's still
assigning an arbitrary position in the range to the interval.

--
greg

Re: BUG #5592: list of integer undefined behaviors

От
Tom Lane
Дата:
Greg Stark <gsstark@mit.edu> writes:
> On Mon, Aug 2, 2010 at 7:16 PM, John Regehr <regehr@cs.utah.edu> wrote:
>> <nabstime.c, (1193:21)> : Op: -, Reason : Signed Subtraction Overflow,
>> BINARY OPERATION: left (int32): 2147483644 right (int32): -2147483648
>>
>> <nabstime.c, (1194:21)> : Op: -, Reason : Signed Subtraction Overflow,
>> BINARY OPERATION: left (int32): 2147483644 right (int32): -2147483648

> These seem to imply that tinterval can contain a start point greater
> than its end point.

Just to follow up: all the other ones seem to be non-problems.
The one in bitmapset.c is an intentional trick (see the comment for
the RIGHTMOST_ONE macro), and all the ones in int.c and int8.c have
associated overflow checks.  I'm actually a bit surprised that the
regression tests seem to exercise all of those overflow checks ;-)

Like Greg, I'm not sure about the tinterval_cmp_internal cases.
tinterval is pretty much a dead legacy datatype anyway, but probably we
oughta fix it if there are failures showing up in the regression tests.

            regards, tom lane

Re: BUG #5592: list of integer undefined behaviors

От
Tom Lane
Дата:
Greg Stark <gsstark@mit.edu> writes:
> On Mon, Aug 2, 2010 at 7:16 PM, John Regehr <regehr@cs.utah.edu> wrote:
>> <nabstime.c, (1193:21)> : Op: -, Reason : Signed Subtraction Overflow,
>> BINARY OPERATION: left (int32): 2147483644 right (int32): -2147483648
>>
>> <nabstime.c, (1194:21)> : Op: -, Reason : Signed Subtraction Overflow,
>> BINARY OPERATION: left (int32): 2147483644 right (int32): -2147483648

> These seem to imply that tinterval can contain a start point greater
> than its end point.

On closer investigation, the problem is just that you can't fit the
difference INT_MAX minus INT_MIN into an int :-(.

The particular values cited appear to be NOEND_ABSTIME and
NOSTART_ABSTIME, ie "infinity" and "-infinity" in the abstime datatype,
so this is coming from tinterval comparisons involving this value
in the regression tests:

INSERT INTO TINTERVAL_TBL (f1)
   VALUES ('["-infinity" "infinity"]');

Although this is the worst case, you could easily get overflows from
intervals with ordinary endpoints that are sufficiently far apart.

Since this is a nearly-dead legacy datatype, I can't get excited about
spending a lot of time on it.  What I suggest we do is do the difference
calculation in int64 arithmetic instead of int32.

Another complaint that could be leveled against this code is that
infinity and minus infinity behave way too much like ordinary mortal
timestamps.  It would be very easy to select finite timestamps
a, b, c such that this code thinks [a b] is a longer interval than
[c infinity], which is surprising to say the least.  However, I can't
get excited about fixing that for abstime/tinterval.  It might be
something to consider if anyone ever reimplements this type in a way
that isn't going to fall over in 2038.

            regards, tom lane

Re: BUG #5592: list of integer undefined behaviors

От
Greg Stark
Дата:
On Tue, Aug 3, 2010 at 3:33 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Although this is the worst case, you could easily get overflows from
> intervals with ordinary endpoints that are sufficiently far apart.

Oh, duh, this is pretty obvious in retrospect.

> Since this is a nearly-dead legacy datatype, I can't get excited about
> spending a lot of time on it. =A0What I suggest we do is do the difference
> calculation in int64 arithmetic instead of int32.

At some level this is all not really a problem. It just means that the
arbitrary ordering of tintervals isn't the obvious ordering. If we
change it it would invalidate any indexes on tintervals so it can't be
backpatched. I'm not sure whether it makes sense to bother having a
slightly more sensible ordering in 9.0+ if it's still going to be
wacky in older versions.

Also, does it cause any problem that this comparison function will
treat large swathes of tintervals as equal? Any tinterval with the
same length will compare equal according to this. I suppose it doesn't
have the same problem as strings as long as =3D is defined compatibly.




--=20
greg

Re: BUG #5592: list of integer undefined behaviors

От
Tom Lane
Дата:
Greg Stark <gsstark@mit.edu> writes:
> On Tue, Aug 3, 2010 at 3:33 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> Since this is a nearly-dead legacy datatype, I can't get excited about
>> spending a lot of time on it.  What I suggest we do is do the difference
>> calculation in int64 arithmetic instead of int32.

> At some level this is all not really a problem. It just means that the
> arbitrary ordering of tintervals isn't the obvious ordering. If we
> change it it would invalidate any indexes on tintervals so it can't be
> backpatched. I'm not sure whether it makes sense to bother having a
> slightly more sensible ordering in 9.0+ if it's still going to be
> wacky in older versions.

There is that.  Given the lack of complaints from the field, maybe we
should leave it alone, except maybe for adding some more comments to
tinterval_cmp_internal.

> Also, does it cause any problem that this comparison function will
> treat large swathes of tintervals as equal?

Since we don't have hashing support for tinterval, there's nothing
inconsistent about the behavior.  Whether it is *useful* is a whole
different discussion.

            regards, tom lane

Re: BUG #5592: list of integer undefined behaviors

От
Tom Lane
Дата:
John Regehr <regehr@cs.utah.edu> writes:
>> Just to follow up: all the other ones seem to be non-problems.

> Would you folks be willing to specify which arithmetic operations are
> considered to be safe in the case of overflow?  Something simple like an
> "INTEGER_OVERFLOW_OK" comment at the end of the line of code containing
> the operation would suffice.  This would let me automatically filter out
> error messages on these lines of code in the future.

That might be doable for individual operations, but I don't think that
(for example) having to label all the users of RIGHTMOST_ONE() would be
very maintainable.  Is your code capable of tracking back to a macro
definition?

Also, it would be nicer if we could put the marker comment on an
adjacent line.  If it has to be on the same line then there are
formatting problems when the code is wide (and pgindent could break it).

            regards, tom lane

Re: BUG #5592: list of integer undefined behaviors

От
Tom Lane
Дата:
John Regehr <regehr@cs.utah.edu> writes:
> Tom, would you be willing to isolate these operations into functions
> that could be marked with a "no_overflow_check" attribute?  This would
> be easy for us to deal with, would survive preprocesing cleanly, and
> wouldn't have any performance cost since inliners do a fine job.

Uh, *some* inliners do a fine job.  I'm not really willing to depend on
that for performance.

However, most of the cases that seem of interest so far are in fairly
small, stable functions.  Would it be reasonable to attach a "checked
for overflow problems" label to these functions as a whole?

            regards, tom lane

Re: BUG #5592: list of integer undefined behaviors

От
John Regehr
Дата:
> Just to follow up: all the other ones seem to be non-problems.

Would you folks be willing to specify which arithmetic operations are
considered to be safe in the case of overflow?  Something simple like an
"INTEGER_OVERFLOW_OK" comment at the end of the line of code containing
the operation would suffice.  This would let me automatically filter out
error messages on these lines of code in the future.

John Regehr

Re: BUG #5592: list of integer undefined behaviors

От
John Regehr
Дата:
Tom, would you be willing to isolate these operations into functions
that could be marked with a "no_overflow_check" attribute?  This would
be easy for us to deal with, would survive preprocesing cleanly, and
wouldn't have any performance cost since inliners do a fine job.

John



On 8/3/2010 3:43 PM, Tom Lane wrote:
> John Regehr<regehr@cs.utah.edu>  writes:
>>> Just to follow up: all the other ones seem to be non-problems.
>
>> Would you folks be willing to specify which arithmetic operations are
>> considered to be safe in the case of overflow?  Something simple like an
>> "INTEGER_OVERFLOW_OK" comment at the end of the line of code containing
>> the operation would suffice.  This would let me automatically filter out
>> error messages on these lines of code in the future.
>
> That might be doable for individual operations, but I don't think that
> (for example) having to label all the users of RIGHTMOST_ONE() would be
> very maintainable.  Is your code capable of tracking back to a macro
> definition?
>
> Also, it would be nicer if we could put the marker comment on an
> adjacent line.  If it has to be on the same line then there are
> formatting problems when the code is wide (and pgindent could break it).
>
>             regards, tom lane
>

Re: BUG #5592: list of integer undefined behaviors

От
John Regehr
Дата:
On 8/3/2010 4:08 PM, Tom Lane wrote:
> However, most of the cases that seem of interest so far are in fairly
> small, stable functions.  Would it be reasonable to attach a "checked
> for overflow problems" label to these functions as a whole?

This should work great.  I'll get my clang hacker to start working on it.

I see that pgsql has support already in place to def out attributes when
non-GCC ocmpilers are used.

Just to be clear we're talking about putting something like this in your
header files:

int
bms_first_member(Bitmapset *a)
__attribute__((no_integer_overflow_checks));

Pick whatever name you like for this attribute, it doesn't matter to us.

John