| PRE |
Preprocessor |
0-1 out of 3 |
|
| PRE30 |
Do not create a universal character name through concatenation |
No |
✅ |
| PRE31 |
Avoid side effects in arguments to unsafe macros
Context: in C, "unsafe macro" means a macro that evaluates one of its parameters more than once or not at all. Doing so with side effects then means that those side effects are triggered either more than once, or not at all. |
WIP (Félix) |
⬜️ |
| PRE32 |
Do not use preprocessor directives in invocations of function-like macros |
No |
✅ |
| DCL |
Declarations and Initialization |
2 out of 8 |
|
| DCL30 |
Declare objects with appropriate storage durations |
Unsafe Only |
⬜️ |
| DCL31 |
Declare identifiers before using them |
No |
✅ |
| DCL36 |
Do not declare an identifier with conflicting linkage classifications |
No |
✅ |
| DCL37 |
Do not declare or define a reserved identifier |
No |
✅ |
| DCL38 |
Use the correct syntax when declaring a flexible array member |
No |
✅ |
| DCL39 |
Avoid information leakage when passing a structure across a trust boundary |
Yes |
⬜️ |
| DCL40 |
Do not create incompatible declarations of the same function or object |
No |
✅ |
| DCL41 |
Do not declare variables inside a switch statement before the first case label |
No |
✅ |
| EXP |
Expressions |
5-6 out of 15 |
|
| EXP30 |
Do not depend on the order of evaluation for side effects |
No |
✅ |
| EXP32 |
Do not access a volatile object through a nonvolatile reference |
No |
✅ |
| EXP33 |
Do not read uninitialized memory |
Unsafe Only |
⬜️ |
| EXP34 |
Do not dereference null pointers |
Unsafe Only |
⬜️ |
| EXP35 |
Do not modify objects with temporary lifetime |
No |
✅ |
| EXP36 |
Do not cast pointers into more strictly aligned pointer types |
Unsafe Only |
⬜️ |
| EXP37 |
Call functions with the correct number and type of arguments |
No |
✅ |
| EXP39 |
Do not access a variable through a pointer of an incompatible type |
Unsafe Only |
⬜️ |
| EXP40 |
Do not modify constant objects |
Maybe |
⬜️ |
| EXP42 |
Do not compare padding data
Context: it's about avoiding byte-wise comparisons, because that compares padding bits as well. |
Unsafe Only |
⬜️ |
| EXP43 |
Avoid Undefined Behavior when using restrict-qualified pointers |
No |
✅ |
| EXP44 |
Do not rely on side effects in operands to sizeof, _Alignof or _Generic |
No |
✅ |
| EXP45 |
Do not perform assignments in selection statements |
No |
✅ |
| EXP46 |
Do not use a bitwise operator with a Boolean-like operand |
No |
✅ |
| EXP47 |
Do not call va_arg with an argument of the incorrect type |
No |
✅ |
| INT |
Integers |
6 out of 7 |
|
| INT30 |
Ensure that integer operations do not wrap |
Yes |
✅ |
| INT31 |
Ensure that integer conversions do not result in lost or misinterpreted data |
Yes |
⬜️ |
| INT32 |
Ensure that operations on signed integers do not result in overflow |
Yes |
✅ |
| INT33 |
Ensure that division and remainder operations do not result in divide-by-zero errors |
Yes |
✅ |
| INT34 |
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 |
Yes |
✅ |
| INT35 |
Use correct integer precisions |
No |
✅ |
| INT36 |
Converting a pointer to integer or integer to pointer |
Yes |
⬜️ |
| FLP |
Floating Point |
3-4 out of 5 |
|
| FLP30 |
Do not use floating-point variables as loop counters |
WIP (Félix) |
⬜️ |
| FLP32 |
Prevent or detect domain and range errors in math functions |
Yes |
⬜️ |
| FLP34 |
Ensure that floating-point conversions are within range of the new type |
Yes |
⬜️ |
| FLP36 |
Preserve precision when converting integral values to floating-point type |
Yes |
⬜️ |
| FLP37 |
Do not use object representations to compare floating-point values |
No |
✅ |
| ARR |
Arrays |
3-4 out of 6 |
|
| ARR30 |
Do not form or use out-of-bounds pointers or array subscripts |
Yes |
⬜️ |
| ARR32 |
Ensure size arguments for variable length arrays are in a valid range |
No |
✅ |
| ARR36 |
Do not subtract or compare two pointers that do not refer to the same array |
Unsafe Only |
⬜️ |
| ARR37 |
Do not add or subtract an integer to a pointer to a non-array object |
WIP (Félix) |
⬜️ |
| ARR38 |
Guarantee that library functions do not form invalid pointers |
Yes |
⬜️ |
| ARR39 |
Do not add or subtract a scaled integer to a pointer |
No |
✅ |
| STR |
Strings |
0 out of 6 |
|
| STR30 |
Do not attempt to modify string literals |
No |
✅ |
| STR31 |
Guarantee that storage for strings has sufficient space for character data and the null terminator |
No |
✅ |
| STR32 |
Do not pass a non-null-terminated character sequence to a library function that expects a string |
No |
✅ |
| STR34 |
Cast characters to unsigned char before converting to larger integer sizes |
No |
✅ |
| STR37 |
Arguments to characer-handling functions must be representable as an unsigned char |
No |
✅ |
| STR38 |
Do not confuse narrow and wide character strings and functions |
No |
✅ |
| MEM |
Memory Management |
2-5 out of 6 |
|
| MEM30 |
Do not access freed memory |
WIP (Félix) |
⬜️ |
| MEM31 |
Free dynamically allocated memory when no longer needed |
WIP (Félix) |
⬜️ |
| MEM33 |
Allocate and copy structures containing a flexible array member dynamically |
No |
✅ |
| MEM34 |
Only free memory allocated dynamically |
WIP (Félix) |
⬜️ |
| MEM35 |
Allocate sufficient memory for an object
Context: this is all about preventing buffer overflows |
Unsafe Only |
⬜️ |
| MEM36 |
Do not modify the alignment of objects by calling realloc() |
Unsafe Only |
⬜️ |
| FIO |
Input Output |
2-3 out of 13 |
|
| FIO30 |
Exclude user input from format strings |
No |
✅ |
| FIO32 |
Do not perform operations on devices that are only appropriate for files |
WIP (Félix) |
⬜️ |
| FIO34 |
Distinguish between characters read from a file and EOF or WEOF |
No |
✅ |
| FIO37 |
Do not assume that fgets() or fgetws() returns a nonempty string when successful |
No |
✅ |
| FIO38 |
Do not copy a FILE object |
No |
✅ |
| FIO39 |
Do not alternately input and output from a stream without an intervening flush or positioning call |
No |
✅ |
| FIO40 |
Reset strings on fgets() or fgetws() failure |
No |
✅ |
| FIO41 |
Do not call getc(), putc(), getwc() or putwc() with a stream argument that has side effects |
No |
✅ |
| FIO42 |
Close files when they are no longer needed |
Yes |
⬜️ |
| FIO44 |
Only use values for fsetpos() that are returned from fgetpos() |
No |
✅ |
| FIO45 |
Avoid TOCTOU race conditions while accessing files |
Yes |
⬜️ |
| FIO46 |
Do not access a closed file |
No |
✅ |
| FIO47 |
Use valid format strings |
No |
✅ |
| ENV |
Environment |
1 out of 5 |
|
| ENV30 |
Do not modify the object referenced by the return value of certain functions |
No |
|
| ENV31 |
Do not rely on an environment pointer following an operation that may invalidate it |
No |
✅ |
| ENV32 |
All exit handlers must return normally |
No |
✅ |
| ENV33 |
Do not call system() |
Yes |
⬜️ |
| ENV34 |
Do not store pointers returned by certain functions |
No |
✅ |
| SIG |
Signals |
0-4 out of 4 |
|
| SIG30 |
Call only asynchronous-safe functions within signal handlers |
|
⬜️ |
| SIG31 |
Do not access shared objects in signal handlers |
|
⬜️ |
| SIG34 |
Do not call signal() from within interruptible signal handlers |
|
⬜️ |
| SIG35 |
Do not return from a computational exception signal handler |
|
⬜️ |
| ERR |
Error Handling |
0 out of 4 |
|
| ERR30 |
Take care when reading errno |
No |
✅ |
| ERR32 |
Do not rely on indeterminate values of errno |
No |
✅ |
| ERR33 |
Detect and handle standard library errors |
No |
✅ |
| ERR34 |
Detect errors when converting a string to a number |
No |
✅ |
| CON |
Concurrency |
3-11 out of 13 |
|
| CON30 |
Clean up thread-specific storage |
|
⬜️ |
| CON31 |
Do not destroy a mutex while it is locked |
|
⬜️ |
| CON32 |
Prevent data races when accessing bit-fields from multiple threads |
Unsafe Only |
⬜️ |
| CON33 |
Avoid race conditions when using library functions |
Yes |
⬜️ |
| CON34 |
Declare objects shared between threads with appropriate storage durations |
Unsafe Only |
⬜️ |
| CON35 |
Avoid deadlock by locking in a predefined order |
|
⬜️ |
| CON36 |
Wrap functions that can spuriously wake up in a loop |
|
⬜️ |
| CON37 |
Do not call signal() in a multithreaded program |
No |
✅ |
| CON38 |
Preserve thread safety and liveness when using condition variables |
|
⬜️ |
| CON39 |
Do not join or detach a thread that was previously joined or detached |
|
⬜️ |
| CON40 |
Do not refer to an atomic variable twice in an expression |
|
⬜️ |
| CON41 |
Wrap functions that can spuriously fail in a loop |
|
⬜️ |
| CON43 |
Do not allow data races in multithreaded code |
No |
✅ |
| MSC |
Miscellaneous |
2 out of 8 |
|
| MSC30 |
Do not use the rand() function for generating pseudorandom numbers |
No |
✅ |
| MSC32 |
Properly seed pseudorandom number generators |
Yes |
⬜️ |
| MSC33 |
Do not pass invalid data to the asctime() function |
No |
✅ |
| MSC37 |
Ensure that control never reaches the end of a non-void function |
No |
✅ |
| MSC38 |
Do not treat a predefined identifier as an object if it might only be implemented as a macro |
No |
✅ |
| MSC39 |
Do not call va_arg() on a va_list that has an indeterminate value |
No |
✅ |
| MSC40 |
Do not violate constraints
Context: this is about not writing code that doesn't comply with the C standard. |
No |
✅ |
| MSC41 |
Never hard code sensitive information |
Yes |
⬜️ |