An interesting GCC (v5.4.0) bug

46 views
Skip to first unread message

gmhwxi

unread,
Jan 30, 2021, 5:48:48 PM1/30/21
to ats-lang-users
I tried the following example today.

Without -O2, the executable generated by gcc returns 32.
With -O2, it is a non-terminating loop. Clearly, gcc assumes
(with -O2) that the sum of two positive integers is also positive
(but it is obviously false when modulo arithmetic is involved).
BTW, clang does NOT have this issue.

This kind of bug is really scary, isn't it ?!

implement
int_test() =
(
  loop(0, 1)
) where
{
fun
loop
(n: int, i: int): int =
(
println!
("loop(", n, ", ", i, ")");
if i = 0 then n else loop(n+1, i+i)
)
}

--Hongwei

Elijah Stone

unread,
Jan 30, 2021, 7:04:22 PM1/30/21
to ats-lang-users
On Sat, 30 Jan 2021, gmhwxi wrote:

> Without -O2, the executable generated by gcc returns 32. With -O2, it is
> a non-terminating loop. Clearly, gcc assumes (with -O2) that the sum of
> two positive integers is also positive (but it is obviously false when
> modulo arithmetic is involved). BTW, clang does NOT have this issue.

It's actually not a bug!

In c, signed integer overflow is considered undefined behaviour, so the
compiler is free to treat is as nonterminating instead of wrapping. And
in fact, my version of clang (11.0.1) returns 33 for that function.

If you want the compiler to treat integer overflow as wrapping, you have
to pass it -fwrapv.

-E

gmhwxi

unread,
Jan 30, 2021, 7:32:21 PM1/30/21
to ats-lang-users

Oh, I see.

But this is kind of like punting the problem to the user :(
The compiler should really generate code that raises an exception
(just like in the case of 1/0).

Elijah Stone

unread,
Jan 30, 2021, 7:57:19 PM1/30/21
to ats-lang-users
On Sat, 30 Jan 2021, gmhwxi wrote:

> But this is kind of like punting the problem to the user :(
> The compiler should really generate code that raises an exception
> (just like in the case of 1/0).

You can do that with -ftrapv.

gmhwxi

unread,
Jan 30, 2021, 8:02:48 PM1/30/21
to ats-lang-users
To me, it would be a better design if -ftrapv was actually the default.

gmhwxi

unread,
Jan 30, 2021, 8:24:36 PM1/30/21
to ats-lang-users
Is there an easy way to trap individual arithmetic operations?

Here is some code I wrote a few year ago:


It would nice to make sure that only provably non-wrapping arithmetic operations are not trapped.

Thanks!

Elijah Stone

unread,
Jan 30, 2021, 8:35:21 PM1/30/21
to ats-lang-users
On Sat, 30 Jan 2021, gmhwxi wrote:

> Is there an easy way to trap individual arithmetic operations?

For gcc/clang,
https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html. It
doesn't trap on its own, but you can easily wrap it with e.g.
assert(!__builtin_add_overflow(...)) or similar.
Reply all
Reply to author
Forward
0 new messages