Skip to main content

IAR Embedded Workbench for Arm 9.70.x

Detecting signed or unsigned overflow

In this section:
Description

Checks that the result of an expression is in the range of representable values for its type, and that shift counts are valid.

Does not check for overflow in shift operations, which is handled by a separate check. See Detecting bit loss or undefined behavior when shifting.

Why perform the check

Because the behavior of signed overflow is undefined, and because unsigned overflow results in a truncation that can sometimes be undesirable. Although the shift operation is not checked, shift counts are checked because if a shift count is negative or greater than or equal to the width of the promoted left operand, the behavior of the shift operation is undefined.

How to use it

Compiler option: ‑‑runtime_checking signed_overflow|unsiged_overflow

In the IDE: Project>Options>Runtime Checking>Integer overflow

The check can be applied to one or more modules.

The check can be avoided, for example by working in a larger type, when such a type exists:

int f(int a, int b) 
  { return (int) ((long long) a + (long long) b); }
short g(short a, short b) 
  { return (short) ( a + b); } /* Integer promotion occurs */
How it works

The compiler inserts code to perform the check at each integer operation that can overflow (+, -, *, /, %, including unary -) and each shift operation, unless the compiler determines that the check cannot fail.

Note that increment/decrement operators (++/‑‑) and compound assignments (+=, -=, etc) are checked as if they were written longhand (var = var op val).

For example, both ++i and i += 1 are checked as if they were written i = i + 1. In this case, the addition will be checked if overflow checks are enabled, and the assignment will be checked if conversion checks are enabled. For integer types with the same size as int or larger, the conversion check cannot fail. But for smaller integer types, any failure in an expression of this kind will generally be a conversion failure. This example shows this:

signed char a = 127;
void f(void)
{
  ++a;    /* Conversion check error (128 -> -128) */
  a -= 1; /* Conversion check error (-129 -> 127) */
}

The code size increases, which means that if the application has resource constraints this check should be used per module to minimize overhead.

Example

Follow the procedure described in Getting started using C-RUN runtime error checking, but use the Integer overflow option.

This is an example of source code that will be identified during runtime:

crs_sign_overflow_Hom7.1_M16_1.PNG

C-RUN will report either Signed ingeger overflow, Unsigned integer overflow, or Shift count overflow. This is an example of the message information that will be listed:

message_sign_overflow_Hom7.1_M16_1.PNG