CWE Rule 191
Description
Rule Description
The product subtracts one value from another, such that the result is less than the minimum allowable integer value, which produces a value that is not equal to the correct result.
Polyspace Implementation
The rule checker checks for these issues:
Integer constant overflow
Integer overflow
Unsigned integer constant overflow
Unsigned integer conversion overflow
Unsigned integer overflow
Examples
Integer constant overflow
This issue occurs in the following cases:
You assign a compile-time integer constant to a signed integer variable whose data type cannot accommodate the value.
You use an
enum
value that cannot be accommodated by the underlying type of theenum
(and the underlying type is signed). For most C compilers, the default underlying type issigned int
(based on the C standard).You perform a binary operation involving two integer constants that results in an overflow, that is, a value outside the range allowed by the data type that the operation uses. A binary operation with integer constants uses the
signed int
data type (unless you use modifiers such asu
orL
).
An n
-bit signed integer holds values in the range [-2n
-1, 2n
-1-1]. For instance, c
is an 8-bit signed char
variable that cannot hold the value 255.
signed char c = 255;
This defect checker depends on the following options:
Target processor type (-target)
: Determines the sizes of fundamental types.Enum type definition (-enum-type-definition)
: Determines the underlying types of enumerations.Compiler (-compiler)
: Impacts the interpretation of code.
You do not see the defect in these situations:
Creation of new constants from
const
variables (for specific compilers only).Different compilers might define compile-time constants differently. In the following code,
c+1
is considered a compile-time constant by GCC compilers, but not by the standard C compiler:Whether you see a violation of this check onconst int16_t c = 32767; int16_t y = c + 1;
y
might depend on your compiler.Bitwise
NOT
operation.Polyspace® does not raise this violation when you perform a bitwise
NOT
operation.
The default behavior for constant overflows can vary between compilers and platforms. Retaining constant overflows can reduce the portability of your code.
Even if your compilers wraps around overflowing constants with a warning, the wrap-around behavior can be unintended and cause unexpected results.
Check if the constant value is what you intended. If the value is correct, use a different, possibly wider, data type for the variable.
#define MAX_UNSIGNED_CHAR 255 //Noncompliant #define MAX_SIGNED_CHAR 127 //Noncompliant void main() { char c1 = MAX_UNSIGNED_CHAR; char c2 = MAX_SIGNED_CHAR+1; }
In this example, the defect appears on the macros
because at least one use of the macro causes an overflow. To reproduce these defects, use a
Target processor type
(-target)
where char
is signed by default.
One possible correction is to use a different data type for the variables that overflow.
#define MAX_UNSIGNED_CHAR 255 #define MAX_SIGNED_CHAR 127 void main() { unsigned char c1 = MAX_UNSIGNED_CHAR; unsigned char c2 = MAX_SIGNED_CHAR+1; }
enum { a=0x7fffffff, b, //Noncompliant c=0xffffffff //Noncompliant } MyEnumA;
In this example, the enum
has an underlying type int
.
The int
type can accommodate values in the range
[-231, 231-1]. However, the value of the
enumerator b
is 0x80000000 or 231 (one more than
the previous value a
). This value falls outside the allowed range of
int
.
The value of c
, that is 0xffffffff or 232-1,
is even larger and also causes an overflow.
To see this defect:
Specify
Compiler (-compiler)
asgeneric
.Specify
Source code language (-lang)
asc
.
const unsigned int K_ATM_Label_Ram_init_value [] = { 0x06 | ( 3 << 29) , 0x80 | ( 9 << 29) , //Noncompliant ( 2 << 31 ) //Noncompliant };
In this example, two of the shift operations result in values that cannot be accommodated by the signed int
data type. The signed int
data type can accommodate values in the range [-231, 231-1]. The operation:
9 << 29
results in the value 232+536870912.2 << 31
results in the value 232.
Note that even though the result is assigned to an unsigned int
variable,
the overflow detection uses the underlying type of the binary operation, that is,
signed int
.
Integer overflow
This issue occurs when an operation on integer variables results in values that cannot be represented by the data type that the operation uses. This data type depends on the operand types and determines the number of bytes allocated for storing the result, thus constraining the range of allowed values.
Note that:
The data type used to determine an overflow is based on the operand data types. If you then assign the result of an operation to another variable, a different checker,
Integer conversion overflow
, determines if the value assigned also overflows the variable assigned to. For instance, in an operation such as:This checker checks for an overflow based on the types ofres = x + y;
x
andy
, and not on the type ofres
. The checker for integer conversion overflows then checks for an overflow based on the type ofres
.The two operands in a binary operation might undergo promotion before the operation occurs. See also Code Prover Assumptions About Implicit Data Type Conversions (Polyspace Code Prover).
The exact storage allocation for different data types depends on your processor. See
Target processor type (-target)
.
Integer overflows on signed integers result in undefined behavior.
The fix depends on the root cause of the defect. Often the result details (or source code tooltips in Polyspace as You Code) show a sequence of events that led to the defect. You can implement the fix on any event in the sequence. If the result details do not show this event history, you can search for previous references of variables relevant to the defect using right-click options in the source code and find related events. See also Interpret Bug Finder Results in Polyspace Desktop User Interface or Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access).
You can fix the defect by:
Using a bigger data type for the result of the operation so that all values can be accommodated.
Checking for values that lead to the overflow and performing appropriate error handling.
To avoid overflows in general, try one of these techniques:
Keep integer variable values restricted to within half the range of signed integers.
In operations that might overflow, check for conditions that can lead to the overflow and implement wrap around or saturation behavior depending on how the result of the operation is used. The result then becomes predictable and can be safely used in subsequent computations.
See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. See:
Address Results in Polyspace User Interface Through Bug Fixes or Justifications if you review results in the Polyspace user interface.
Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access) if you review results in a web browser.
Annotate Code and Hide Known or Acceptable Results if you review results in an IDE.
A default Bug Finder analysis might not raise this defect when the input values are unknown and only a subset of inputs cause an issue. To check for defects caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.
#include <limits.h> int plusplus(void) { int var = INT_MAX; var++; //Noncompliant return var; }
In the third statement of this function, the
variable var
is increased by one. But the value
of var
is the maximum integer value, so an int
cannot
represent one plus the maximum integer value.
One possible correction is to change data types.
Store the result of the operation in a larger data type (Note that
on a 32-bit machine, int
and long
has
the same size). In this example, on a 32-bit machine, by returning
a long long
instead of an int
,
the overflow error is fixed.
#include <limits.h> long long plusplus(void) { long long lvar = INT_MAX; lvar++; return lvar; }
Unsigned integer constant overflow
This issue occurs in the following cases:
You assign a compile-time constant to an unsigned integer variable whose data type cannot accommodate the value.
You use an
enum
value that cannot be accommodated by the underlying type of theenum
(and the underlying type is unsigned).
An n
-bit unsigned integer holds values in the range [0, 2n
-1]. For instance, c
is an 8-bit unsigned char
variable that cannot hold the value 256.
unsigned char c = 256;
This defect checker depends on the following options:
To determine the sizes of fundamental types, Bug Finder uses your specification for
Target processor type (-target)
.To determine the underlying types of enumerations, Bug Finder uses your specification for
Enum type definition (-enum-type-definition)
.
You do not see the defect in these situations:
Creation of new constants from
const
variables (for specific compilers only).Different compilers might define compile-time constants differently. In the following code,
c+1u
is considered a compile time-constant by GCC compilers, but not by the standard C compiler:Whether you see a violation of this check onconst uint16_t c = 0xffffu; uint16_t y = c + 1u;
y
might depend on your compiler.Bitwise
NOT
operation.Polyspace does not raise this violation when you perform a bitwise
NOT
operation.
The C standard states that overflowing unsigned integers must be wrapped around (see, for instance, the C11 standard, section 6.2.5). However, the wrap-around behavior can be unintended and cause unexpected results.
Check if the constant value is what you intended. If the value is correct, use a wider data type for the variable.
#define MAX_UNSIGNED_CHAR 255 //Noncompliant #define MAX_UNSIGNED_SHORT 65535 //Noncompliant void main() { unsigned char c1 = MAX_UNSIGNED_CHAR + 1; unsigned short c2 = MAX_UNSIGNED_SHORT + 1; }
In this example, the defect appears on the macros because at least one use of the macro causes an overflow.
One possible correction is to use a wider data type for the variables that overflow.
#define MAX_UNSIGNED_CHAR 255 #define MAX_UNSIGNED_SHORT 65535 void main() { unsigned short c1 = MAX_UNSIGNED_CHAR + 1; unsigned int c2 = MAX_UNSIGNED_SHORT + 1; }
Unsigned integer conversion overflow
This issue occurs when converting an unsigned integer to a smaller unsigned integer type. If the variable does not have enough bytes to represent the original constant, the conversion overflows.
The exact storage allocation for different floating point types depends on your
processor. See Target processor type (-target)
.
Integer conversion overflows result in undefined behavior.
The fix depends on the root cause of the defect. Often the result details (or source code tooltips in Polyspace as You Code) show a sequence of events that led to the defect. You can implement the fix on any event in the sequence. If the result details do not show this event history, you can search for previous references of variables relevant to the defect using right-click options in the source code and find related events. See also Interpret Bug Finder Results in Polyspace Desktop User Interface or Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access).
You can fix the defect by:
Using a bigger data type for the result of the conversion so that all values can be accommodated.
Checking for values that lead to the overflow and performing appropriate error handling.
In general, avoid conversions to smaller integer types.
See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. See:
Address Results in Polyspace User Interface Through Bug Fixes or Justifications if you review results in the Polyspace user interface.
Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access) if you review results in a web browser.
Annotate Code and Hide Known or Acceptable Results if you review results in an IDE.
A default Bug Finder analysis might not raise this defect when the input values are unknown and only a subset of inputs cause an issue. To check for defects caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.
unsigned char convert(void) { unsigned int unum = 1000000U; return (unsigned char)unum; //Noncompliant }
In the return statement, the unsigned integer
variable unum
is converted to an unsigned character
type. However, the conversion overflows because 1000000 requires at
least 20 bits. The C programming language standard does not view unsigned
overflow as an error because the program automatically reduces the
result by modulo the maximum value plus 1. In this example, unum
is
reduced by modulo 2^8
because a character data
type can only represent 2^8-1
.
One possible correction is to convert to a different integer
type that can represent the entire number. For example, long
.
unsigned long convert(void) { unsigned int unum = 1000000U; return (unsigned long)unum; }
Unsigned integer overflow
This issue occurs when an operation on unsigned integer variables can result in values that cannot be represented by the result data type. The data type of a variable determines the number of bytes allocated for the variable storage and constrains the range of allowed values.
The exact storage allocation for different floating point types depends on your
processor. See Target processor type (-target)
.
The C11 standard states that unsigned integer overflows result in wrap-around behavior. However, a wrap around behavior might not always be desirable. For instance, if the result of a computation is used as an array size and the computation overflows, the array size is much smaller than expected.
The fix depends on the root cause of the defect. Often the result details (or source code tooltips in Polyspace as You Code) show a sequence of events that led to the defect. You can implement the fix on any event in the sequence. If the result details do not show this event history, you can search for previous references of variables relevant to the defect using right-click options in the source code and find related events. See also Interpret Bug Finder Results in Polyspace Desktop User Interface or Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access).
You can fix the defect by:
Using a bigger data type for the result of the operation so that all values can be accommodated.
Checking for values that lead to the overflow and performing appropriate error handling. In the error handling code, you can override the default wrap-around behavior for overflows and implement saturation behavior, for instance.
See examples of fixes below.
If you do not want to fix the issue, add comments to your result or code to avoid another review. See:
Address Results in Polyspace User Interface Through Bug Fixes or Justifications if you review results in the Polyspace user interface.
Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access) if you review results in a web browser.
Annotate Code and Hide Known or Acceptable Results if you review results in an IDE.
A default Bug Finder analysis might not raise this defect when the input values are unknown and only a subset of inputs cause an issue. To check for defects caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.
#include <limits.h> unsigned int plusplus(void) { unsigned uvar = UINT_MAX; uvar++; //Noncompliant return uvar; }
In the third statement of this function, the
variable uvar
is increased by 1. However, the value
of uvar
is the maximum unsigned integer value,
so 1 plus the maximum integer value cannot be represented by an unsigned
int
. The C programming language standard does not view unsigned
overflow as an error because the program automatically reduces the
result by modulo the maximum value plus 1. In this example, uvar
is
reduced by modulo UINT_MAX
. The result is uvar
= 1
.
One possible correction is to store the operation
result in a larger data type. In this example, by returning an unsigned
long long
instead of an unsigned int
,
the overflow error is fixed.
#include <limits.h> unsigned long long plusplus(void) { unsigned long long ullvar = UINT_MAX; ullvar++; return ullvar; }
Check Information
Category: Numeric Errors |
Version History
Introduced in R2023a
See Also
External Websites
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)