Tim Rühsen tim.ruehsen@gmx.de writes:
Nothing with a real impact, just to silence sanitizers.
Can you explain precisely what's undefined behavior in this code ?
diff --git a/sec-tabselect.c b/sec-tabselect.c index e6bf2282..942c4247 100644 --- a/sec-tabselect.c +++ b/sec-tabselect.c @@ -55,7 +55,7 @@ sec_tabselect (mp_limb_t *rp, mp_size_t rn, mpn_zero (rp, rn); for (p = table; p < end; p += rn, k--) {
mp_limb_t mask = - (mp_limb_t) (k == 0);
As far as I understand, this should be perfectly portable C.
(k == 0) evaluates to zero or one, with int type.
This always fits in an mp_limb_t, hence
(mp_limb_t) (k == 0) evaluates to zero or one, with mp_limb_t type.
And since mp_limb_t is an *unsigned* type, arithmetic is always well defined as being performed modulo (ULONG_MAX + 1), including unary negation. So
-(mp_limb_t) (k == 0) evaluates to zero or ULONG_MAX.
(Assuming mp_limb_t is unsigned long, which it is an almost anything except 64-bit windows, where it's instead unsigned long long).
But I may be missing something? These corners of the C language are a bit subtle.
mp_limb_t mask = (mp_limb_t) -(k == 0);
If the other way isn't broken, I'd prefer to change it like this. Because then one also has to think about why it produces the intended sign extension (which it does; it's not the same as (mp_limb_t) (unsigned) -(k == 0)).
In general, both nettle and GMP depend on well-defined modulo arithmetic on unsigned types in *lots* of places. Any sanitizer which complains about that is pretty useless for this code. If your sanitizer complains by default, please use some option to disable that. And if there's no such option, please bug report the sanitizer tool.
Best regards, /Niels