7

Most of my -fsanitize=unsigned-integer-overflow errors are bugs, but sometimes I explicitly use it as intended, which results in UBSan producing false positives.

Is there a way to turn UBSan unsigned-integer-overflow check off for a particular expression?

EDIT in response to Shafik comment, here is an example:

unsigned a = 0;
unsigned b = a - 1; // error: unsigned integer overflow

Most of the time that is a bug, sometimes it isn't. With UBSan one can find every time that happens, fix the bugs, but I haven't found a way to silence the false positives.

EDIT 2: to enable the check one needs to pass either -fsanitize=integer (to enable all integer checks) or fsanitize=unsigned-integer-overflow. From the comments below it seems that the check is only available in clang and not in GCC yet.

jww
  • 97,681
  • 90
  • 411
  • 885
gnzlbg
  • 7,135
  • 5
  • 53
  • 106
  • Why is it triggered in the first place? Overflow in unsigned arithmetic is well-defined. – edmz Oct 26 '15 at 17:30
  • 1
    @black UndefinedBehaviorSanitizer has a check that allows you to find unsigned integer overflow. It is not undefined behavior, but at least in my programs it is typically a bug (not always, and hence the question). I would like to have a way of expressing "here I am explicitly using wraparound behavior". – gnzlbg Oct 26 '15 at 17:31
  • You mean **`-fsanitize=integer`**, that triggers a runtime error _not_ UB. – edmz Oct 26 '15 at 17:33
  • @black yes, sorry, integer. – gnzlbg Oct 26 '15 at 17:34
  • And GCC doesn't have it. (yet, apparently) – edmz Oct 26 '15 at 17:34
  • I use `-fsanitize=address,integer,undefined` to get the error, and to disable the check that is at fault I can use `-fno-sanitize=unsigned-integer-overflow`. – gnzlbg Oct 26 '15 at 17:35
  • 1
    As I read the docs, the parameter appears to be `-fsanitize=unsigned-integer-overflow`. – Mark B Oct 26 '15 at 17:35
  • @MarkB that flag should be enough to trigger the error. Thanks. – gnzlbg Oct 26 '15 at 17:36
  • Removing comment since they don't have much anymore – Shafik Yaghmour Oct 26 '15 at 20:04

2 Answers2

13

If you want to wrap the operation in a function you can use __attribute__((no_sanitize("integer"))) like so (see it live):

__attribute__((no_sanitize("integer")))
unsigned calc( unsigned a )
{
    return a - 1 ;
}

I found this via a bug report/feature request Suppression support for UbSAN.

The clang documentation on attributes does not indicate any way to apply this except to a function:

Use the no_sanitize attribute on a function declaration to specify that a particular instrumentation or set of instrumentations should not be applied to that function. The attribute takes a list of string literals, which have the same meaning as values accepted by the -fno-sanitize= flag. For example, attribute((no_sanitize("address", "thread"))) specifies that AddressSanitizer and ThreadSanitizer should not be applied to the function.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • Thanks! I'm marking this as the answer. Do you happen to know if one can apply this attribute to an expression? – gnzlbg Oct 26 '15 at 17:59
  • @gnzlbg it appears not from the linked bug report, it was closed since the form I gave in my example worked for the reporter but you may want to see if it can be reopened since a way to apply it to statements would be nice. – Shafik Yaghmour Oct 26 '15 at 18:12
0

Using the bitwise NOT operator seems to fix the alleged runtime error.

auto b = ~a;
auto c = ~a - 5;
edmz
  • 8,220
  • 2
  • 26
  • 45