Re: Keep compiler silence (clang 10, implicit conversion from 'long' to 'double' )
Yuya Watari <watari.yuya@gmail.com>
From: Yuya Watari <watari.yuya@gmail.com>
To: pgsql-hackers@postgresql.org
Date: 2019-09-27T07:43:53Z
Lists: pgsql-hackers
Attachments
- v2-keep-compiler-silence.patch (application/octet-stream) patch v2
Hello,
I add further information. This issue also has a problem about
*overflow checking*.
The original code is as follows.
src/backend/utils/adt/timestamp.c:3222
-----
if (result_double > PG_INT64_MAX || result_double < PG_INT64_MIN)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("interval out of range")));
result->time = (int64) result_double;
-----
Here, the code checks whether "result_double" fits 64-bit integer size
before casting it.
However, as I have mentioned in the previous email, PG_INT64_MAX is
cast to double and the value becomes 9223372036854775808 due to lack
of precision.
Therefore, the above code is identical to "result_double >
9223372036854775808.0". This checking does not cover the case when
result_double is equal to 9223372036854775808. In this case, "(int64)
result_double" will be -9223372036854775808, which is wrong.
The next code confirms what I explained.
===
#include <stdio.h>
#include <stdint.h>
int main(void)
{
double value = (double) INT64_MAX;
printf("INT64_MAX = %ld\n", INT64_MAX);
printf("value = %lf\n", value);
printf("(value > (double) INT64_MAX) == %d\n", value > (double) INT64_MAX);
printf("(long int) value == %ld\n", (long int) value);
}
===
Output:
INT64_MAX = 9223372036854775807
value = 9223372036854775808.000000
(value > (double) INT64_MAX) == 0
(long int) value == -9223372036854775808
===
I think the code should be "result_double >= (double) PG_INT64_MAX",
that is we have to use >= rather than >. I attached the modified
patch.
Thanks,
Yuya Watari
NTT Software Innovation Center
watari.yuya@gmail.com
2019年9月27日(金) 12:00 Yuya Watari <watari.yuya@gmail.com>:
>
> Hello,
>
> I found the problem that clang compiler introduces warnings when building PostgreSQL. Attached patch fixes it.
>
> ===
> Compiler version
> ===
> clang version 10.0.0-svn372772-1~exp1+0~20190924181208.2504~1.gbpb209ff (trunk)
>
> Older versions of clang may not generate this warning.
>
> ===
> Warning
> ===
>
> timestamp.c:3236:22: warning: implicit conversion from 'long' to 'double' changes value from 9223372036854775807 to 9223372036854775808 [-Wimplicit-int-float-conversion]
> if (result_double > PG_INT64_MAX || result_double < PG_INT64_MIN)
> ~ ^~~~~~~~~~~~
> ../../../../src/include/c.h:444:22: note: expanded from macro 'PG_INT64_MAX'
> #define PG_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF)
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../../../../src/include/c.h:381:25: note: expanded from macro 'INT64CONST'
> #define INT64CONST(x) (x##L)
> ^~~~
> <scratch space>:234:1: note: expanded from here
> 0x7FFFFFFFFFFFFFFFL
> ^~~~~~~~~~~~~~~~~~~
> 1 warning generated.
> pgbench.c:1657:30: warning: implicit conversion from 'long' to 'double' changes value from 9223372036854775807 to 9223372036854775808 [-Wimplicit-int-float-conversion]
> if (dval < PG_INT64_MIN || PG_INT64_MAX < dval)
> ^~~~~~~~~~~~ ~
> ../../../src/include/c.h:444:22: note: expanded from macro 'PG_INT64_MAX'
> #define PG_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF)
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../../../src/include/c.h:381:25: note: expanded from macro 'INT64CONST'
> #define INT64CONST(x) (x##L)
> ^~~~
> <scratch space>:252:1: note: expanded from here
> 0x7FFFFFFFFFFFFFFFL
> ^~~~~~~~~~~~~~~~~~~
> 1 warning generated.
>
> ===
>
> This warning is due to implicit conversion from PG_INT64_MAX to double, which drops the precision as described in the warning. This drop is not a problem in this case, but we have to get rid of useless warnings. Attached patch casts PG_INT64_MAX explicitly.
>
> Thanks,
> Yuya Watari
> NTT Software Innovation Center
> watari.yuya@gmail.com
Commits
-
Fix integer-overflow edge case detection in interval_mul and pgbench.
- 8d380864a523 9.4.25 landed
- 84780d468023 9.5.20 landed
- 15783d057543 9.6.16 landed
- 5f794f7572e1 10.11 landed
- b49b7f94489a 11.6 landed
- f6e72dc9cc8b 12.1 landed
- a7145f6bc8b7 13.0 landed
-
Change floating-point output format for improved performance.
- 02ddd499322a 12.0 cited