 
                            Bitwise operators include the complement operator ~, bitwise shift operators >> and <<, bitwise AND operator &, bitwise exclusive OR operator ^, bitwise inclusive OR operator | and compound assignment operators >>=, <<=, &=, ^= and |=. Bitwise operators should be used only with unsigned integer operands, as the results of bitwise operations on signed integers are implementation-defined (Annex G.3.5 [ISO/IEC 9899:1990]).
The C90 StandardC11 standard, section 6.35, paragraph 4 [ISO/IEC 9899:19902011], states:
Some operators (the unary operator ~ , and the binary operators <<, >>, &, ^, and |, collectively described as bitwise operators) shall have operands that have integral type. These operators return values that depend on the internal representations of integers, and thus have implementation-defined and undefined aspects for signed types.
FurtherFurthermore,   the bitwise shift operator << for signed type is not defined in C90 subclause 6.3.7 [ISO/IEC 9899:1990].operators << and >> are undefined under many circumstances, and are implementation-defined for signed integers for more circumstances; see rule INT34-C. Do not shift an expression by a negative number of bits or by greater than or equal to the number of bits that exist in the operand for more information.
Implementation details
The Microsoft C compiler documentation says that:
...
On-line GCC documentation about the implementation of some bitwise operations on signed integers says:
...
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| int rc = 0;
unsigned int stringify = 0x80000000;
char buf[sizeof("256")];
rc = snprintf(buf, sizeof(buf), "%u", stringify >> 24);
if (rc == -1 || rc >= sizeof(buf)) {
  /* Handle error */
} | 
...
| / | 
...
Noncompliant Code Example (enum)
In this noncompliant code example, initializer expressions for all enumeration constants in enum attrib_mask are unsigned integers. However, the C Standard says (section 6.1.3.3 [ISO/IEC 9899:1990]) that enumeration constants have type int. The bitwise OR is applied to signed integers which is implementation-defined behavior.
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| enum attrib_mask
{
  POINT_BIT = 0x02U,
  LINE_BIT  = 0x04U
};
unsigned int mask = (POINT_BIT | LINE_BIT);
 | 
Compliant Solution (enum)
One solution is to cast the enumeration constants to an unsigned type to eliminate any possible implementation-defined behavior. The initializer expressions and enumeration constants have type int:
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| enum attrib_mask { POINT_BIT = (1 << 1), LINE_BIT = (1 << 2) }; unsigned int mask = ((unsigned int)POINT_BIT | (unsigned int)LINE_BIT); | 
Exceptions
INT13-C-EX1: When used as bit flags, it is acceptable to use preprocessor macros or enumeration constants as arguments to the & and | operators even if the value is not explicitly declared as unsigned.
| Code Block | ||||
|---|---|---|---|---|
| 
 | ||||
| fd = open(file_name, UO_WRONLY | UO_CREAT | UO_EXCL | UO_TRUNC, 0600); | 
INT13-C-EX2: If the right-side operand to a shift operator is known at compile time, it is acceptable for the value to be represented with a signed type provided it is positive.
...
Performing bitwise operations on signed numbers can lead to buffer overflows and the execution of arbitrary code by an attacker in some cases, unexpected or implementation-defined behavior in others.
| Recommendation | Severity | Likelihood | Detectable | 
|---|
| Repairable | Priority | Level | |
|---|---|---|---|
| INT13-C | High | Unlikely | Yes | 
| No | P6 | L2 | 
Automated Detection
| Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Astrée | 
 | bitop-type | Fully checked | ||||||
| Axivion Bauhaus Suite | 
 | CertC-INT13 | |||||||
| CodeSonar | 
 | LANG.TYPE.IOT | Inappropriate operand type | ||||||
| Compass/ROSE | 
| Can detect violations of this rule. In particular, it flags bitwise operations that involved variables not declared with  | |||||||||
| 
 | CC2.INT13 | Fully implemented | 
5.0
| Helix QAC | 
 | C4532, C4533, C4534, C4543, C4544 | |||||||
| Klocwork | 
 | MISRA.BITS.NOT_UNSIGNED MISRA.BITS.NOT_UNSIGNED.PREP | 
| LDRA tool suite | 
 | 50 S | Fully implemented | ||||||
| Parasoft C/C++test | 
| 
 | CERT_C-INT13-a CERT_C-INT13-b | Operands of bitwise and complement operators shall have an unsigned type Operands of shift operators shall have an unsigned type | |||||||
| PC-lint Plus | 
 | 9233 | Partially supported: reports use of a bitwise operator on an expression with a signed MISRA C 2004 underlying type | ||||||
| 
 | Checks for bitwise operation on negative value (rec. fully covered) | ||||||||
| RuleChecker | 
 | bitop-type | Fully checked | ||||||
| SonarQube C/C++ Plugin | 
 | 
| Splint | 
 | 
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
| SEI CERT C++ Coding Standard | VOID INT13-CPP. Use bitwise operators only on unsigned operands | 
| ISO/IEC TR 24772:2013 | Bit Representations [STR] Arithmetic Wrap-around Error [FIF] Sign Extension Error [XZI] | 
| MITRE CWE | CWE-682, Incorrect calculation | 
Bibliography
| [Dowd 2006] | Chapter 6, "C Language Issues" | 
| [C99 Rationale 2003] | Subclause 6.5.7, "Bitwise Shift Operators" | 
...
...