diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.qhelp b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.qhelp index 621ae3273fd..7907df47957 100644 --- a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.qhelp +++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.qhelp @@ -18,49 +18,39 @@ optimizing compiler.

Solutions to this problem can be thought of as falling into one of two -categories: (1) rewrite the signed expression so that overflow cannot occur -but the signedness remains, or (2) rewrite (or cast) the signed expression -into unsigned form. +categories:

-

-Below we list examples of expressions where signed overflow may -occur, along with proposed solutions. The list should not be -considered exhaustive. -

+
    +
  1. Rewrite the signed expression so that overflow cannot occur +but the signedness remains.
  2. +
  3. Change the variables and all their uses to be unsigned.
  4. +

-Given unsigned short i, delta and i + delta < i, -it is possible to rewrite it as (unsigned short)(i + delta) < i. -Note that i + deltadoes not actually overflow, due to int promotion +The following cases all fall into the first category.

-

-Given unsigned short i, delta and i + delta < i, -it is also possible to rewrite it as USHORT_MAX - delta. It must be true -that delta > 0 and the limits.h or climits +

    +
  1. +Given unsigned short n1, delta and n1 + delta < n1, +it is possible to rewrite it as (unsigned short)(n1 + delta) < n1. +Note that n1 + delta does not actually overflow, due to int promotion. +
  2. + +
  3. +Given unsigned short n1, delta and n1 + delta < n1, +it is also possible to rewrite it as n1 > USHORT_MAX - delta. The +limits.h or climits header must then be included. +
  4. + +
  5. +Given int n1, delta and n1 + delta < n1, +it is possible to rewrite it as n1 > INT_MAX - delta. It must be true +that delta >= 0 and the limits.h or climits header has been included. -

    - -

    -Given int i, delta and i + delta < i, -it is possible to rewrite it as INT_MAX - delta. It must be true -that delta > 0 and the limits.h or climits -header has been included. -

    - -

    -Given int i, delta and i + delta < i, -it is also possible to rewrite it as (unsigned)i + delta < i. -Note that program semantics are affected by this change. -

    - -

    -Given int i, delta and i + delta < i, -it is also possible to rewrite it as unsigned int i, delta and -i + delta < i. Note that program semantics are -affected by this change. -

    +
  6. +
@@ -68,7 +58,7 @@ affected by this change. In the following example, even though delta has been declared unsigned short, C/C++ type promotion rules require that its type is promoted to the larger type used in the addition and comparison, -namely a signed int. Addition is performed on +namely a signed int. Addition is performed on signed integers, and may have undefined behavior if an overflow occurs. As a result, the entire (comparison) expression may also have an undefined result. @@ -87,10 +77,10 @@ are avoided.

In the following example, even though both n and delta -have been declared unsigned short, both are promoted to +have been declared unsigned short, both are promoted to signed int prior to addition. Because we started out with the narrower short type, the addition is guaranteed not to overflow -and is therefore defined. But the fact that n1 + delta never +and is therefore defined. But the fact that n1 + delta never overflows means that the condition n1 + delta < n1 will never hold true, which likely is not what the programmer intended. (see also the cpp/bad-addition-overflow-check query). @@ -98,7 +88,7 @@ hold true, which likely is not what the programmer intended. (see also the

The next example provides a solution to the previous one. Even though -i + delta does not overflow, casting it to an +n1 + delta does not overflow, casting it to an unsigned short truncates the addition modulo 2^16, so that unsigned short "wrap around" may now be observed. Furthermore, since the left-hand side is now of type unsigned short,