RFR: 8338449: ubsan: division by zero in sharedRuntimeTrans.cpp

Kim Barrett kbarrett at openjdk.org
Tue Oct 22 03:41:16 UTC 2024


On Mon, 21 Oct 2024 08:10:45 GMT, Lutz Schmidt <lucy at openjdk.org> wrote:

>> Ubsan is just following the C++ standard 
>> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf
>> 5.6 Multiplicative operators  
>>  ....
>> 'The binary / operator yields the quotient, and the binary % operator yields the remainder from the division
>> of the first expression by the second. If the second operand of / or % is zero the behavior is undefined.'
>> 
>> See also https://stackoverflow.com/questions/42926763/the-behaviour-of-floating-point-division-by-zero .
>> 
>> However on our set of platforms in OpenJDK we probably get away with the expected results when dividing by 0  (because they all seem to follow IEEE-754).
>> That's why I just added the static_assert.
>
> To me, this feels like the C++ standard is not compatible with IEEE-754 arithmetic. Undefined behavior would give the optimizer freedom to do whatever it likes to do. That is in contrast to the well-defined IEEE-754 requirement.

`ATTRIBUTE_NO_UBSAN` suppresses conditions found by ubsan instrumentation. If
ubsan is enabled, the compiler's optimizer presumably doesn't take advantage
of the no-UB assumption, as that would defeat the point of ubsan. But in a
non-ubsan-enabled build, I think that attribute does nothing and the compiler
may take advantage of the no-UB assumption. So that part of the change may not
do anything useful for non-ubsan builds.

cppreference is inconsistent about this. It first states that division by zero
is UB, as per the standard. But then it says if the type `is_iec599`, then
division by zero returns the IEEE defined value (correctly signed infinity if
lhs is non-zero, NaN if lhs is zero) and raises the appropriate floating point
trap. I think this claim makes sense for a C compiler that supports Annex F.
But C++ isn't C, and I don't see anything comparable in a C++ standard.

I can't find any text in any version of either the C or C++ standard to
support the claimed `is_iec599` behavior though.

I did find this, which has some interesting bits.
https://stackoverflow.com/questions/42926763/the-behaviour-of-floating-point-division-by-zero

For example, it is suggested that claiming `is_iec599` implicity defines the
behavior for floating point division by zero (among other things). It is also
mentioned that gcc does that, but (some version of?) clang-the-compiler
doesn't implement iec599, even though the standard library one is using might
claim so. Hm...

It also mentions that the default for `-fsanitize=undefined` for clang includes
`float-divide-by-zero`, while gcc does not.  Any chance the reported issue is
arising with clang as the compiler?

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/21500#discussion_r1809801664


More information about the hotspot-dev mailing list