Astrée is a sound static analyzer of C source code. Its primary purpose is proving the absence of runtime errors, data races, and other program defects in safety-critical programs. This includes violations of the C90, C99, C11 and C17/C18 standard, and implementation-specific undefined behaviors.
Since 2020, the runtime error analysis can also be applied to C++ and mixed C/C++ code bases, thus additionally supporting the C++98, C++11, C++14, and C++17 language norms. The analysis of C++ code is designed to meet the characteristics of safety-critical embedded software, and so is subject to the same restrictions as the analysis of C code.
Additionally, Astrée’s sophisticated analysis engine can be applied to address other program properties relevant to functional safety and security, and to check for violations of user-specified programming guidelines.
In each of the language standards ISO/IEC 9899:1999 (E), ISO/IEC 9899:2011, and ISO/IEC 9899:2018, Annex J covers behaviors that the standard regards as unspecified, undefined or implementation-defined, listing in several sections hundreds of scenarios in total.
A detailed 30-page PDF description of how Astrée addresses each of these scenarios is available. For each section of Annex J, the document lists all the covered situations and provides details about how each is handled by Astrée.
If you have Astrée installed, you can access the document via “Help” → “Compliance matrices”. Otherwise, please contact info@absint.com with any questions.
Astrée’s integrated RuleChecker supports
The tool is highly configurable, allowing you to check for individual rules and even specific aspects of certain rules.
For most rules, RuleChecker can be invoked separately, without running a full-fledged Astrée analysis. This allows for even faster checks of your code.
The main benefit of running both RuleChecker and Astrée at once is that you can greatly improve the precision of all checks for semantical rules, as the soundness of Astrée’s semantic analyses guarantees zero false negatives and minimizes false positives.
This is where Astrée truly shines, as no standalone MISRA tool is capable of checking for semantical rules with such precision, and no testing environment can guarantee the full data and path coverage provided by the static analysis.
As of release 24.04, more than 900 rules of the five MISRA rule sets are checked. Below is a quick overview of all the supported rule categories.
A detailed 70-page PDF description of how Astrée and RuleChecker handle each individual rule comes included with the software. See the menu “Help” → “Compliance matrices” or contact info@absint.com with any questions.
MISRA C:2004 | ||
1 | Environment | ✓ |
2 | Language extensions | ✓ |
3 | Documentation | ✓ |
4 | Character sets | ✓ |
5 | Identifiers | ✓ |
6 | Types | ✓ |
7 | Constants | ✓ |
8 | Declarations and definitions | ✓ |
9 | Initialization | ✓ |
10 | Arithmetic type conversions | ✓ |
11 | Pointer type conversions | ✓ |
12 | Expressions | ✓ |
13 | Control statement expressions | ✓ |
14 | Control flow | ✓ |
15 | Switch statements | ✓ |
16 | Functions | ✓ |
17 | Pointers and arrays | ✓ |
18 | Structures and unions | ✓ |
19 | Preprocessing directives | ✓ |
20 | Standard libraries | ✓ |
21 | Run-time failures | ✓ |
MISRA C:2012 | ||
D | Directives | ✓ |
1 | A standard C environment | ✓ |
2 | Unused code | ✓ |
3 | Comments | ✓ |
4 | Character sets and lexical convention | ✓ |
5 | Identifiers | ✓ |
6 | Types | ✓ |
7 | Literals and constants | ✓ |
8 | Declarations and definitions | ✓ |
9 | Initialization | ✓ |
10 | The essential type model | ✓ |
11 | Pointer type conversions | ✓ |
12 | Expressions | ✓ |
13 | Side effects | ✓ |
14 | Control statement expressions | ✓ |
15 | Control flow | ✓ |
16 | Switch statements | ✓ |
17 | Functions | ✓ |
18 | Pointers and arrays | ✓ |
19 | Overlapping storage | ✓ |
20 | Preprocessing directives | ✓ |
21 | Standard libraries | ✓ |
22 | Resources | ✓ |
MISRA C:2012 Amendment 1 | ||
All 15 rules | ✓ | |
MISRA C:2012 Amendment 2 | ||
All 4 rules | ✓ | |
MISRA C:2012 Amendment 3 | ||
28 out of 29 rules | ✓ | |
MISRA C++:2008 | ||
0 | Language-independent issues | ✓ |
1 | General | ✓ |
2 | Lexical conventions | ✓ |
3 | Basic concepts | ✓ |
4 | Standard conversions | ✓ |
5 | Expressions | ✓ |
6 | Statements | ✓ |
7 | Declarations | ✓ |
8 | Declarators | ✓ |
9 | Classes | ✓ |
10 | Derived classes | ✓ |
11 | Member access control | ✓ |
12 | Special member functions | ✓ |
14 | Templates | ✓ |
15 | Exception handling | ✓ |
16 | Preprocessing directives | ✓ |
17 | Library introduction | ✓ |
18 | Language support library | ✓ |
19 | Diagnostics library | ✓ |
27 | Input/output library | ✓ |
MISRA C++:2023 | ||
0 | Language-independent issues | ✓ |
4 | General principles | ✓ |
5 | Lexical conventions | ✓ |
6 | Basic concepts | ✓ |
7 | Standard conversions | ✓ |
8 | Expressions | ✓ |
9 | Statements | ✓ |
10 | Declarations | ✓ |
11 | Declarators | ✓ |
12 | Classes | ✓ |
13 | Derived classes | ✓ |
14 | Member access control | ✓ |
15 | Special member functions | ✓ |
16 | Overloading | ✓ |
17 | Templates | ✓ |
18 | Exception handling | ✓ |
19 | Preprocessing directives | ✓ |
21 | Language support library | ✓ |
22 | Diagnostics library | ✓ |
23 | General utilities library | ✓ |
24 | Strings library | ✓ |
25 | Localization library | ✓ |
26 | Containers library | ✓ |
28 | Algorithms library | ✓ |
30 | Input/output library | ✓ |
Below is the list of CWE rules supported by Astrée and RuleChecker as of release 24.04 or higher. This includes items with the CWE CCR accuracies Exact, CWE-more-abstract, CWE-more-specific, and CWE-partial. For further details, see Astrée’s “Help” menu or contact info@absint.com.
Astrée is sound — that is, it will never miss defects like division by zero, buffer overflows, data races, etc.
15 | External control of system or configuration setting | ✓ |
73 | External control of file system or path | ✓ |
77 | Improper neutralization of special elements used in a command (command injection) | ✓ |
78 | Improper neutralization of special elements used in an OS command (OS-command injection) | ✓ |
79 | Improper neutralization of input during Web page generation (cross-site scripting) | ✓ |
88 | Argument injection or modification | ✓ |
89 | Improper neutralization of special elements used in an SQL command (SQL injection) | ✓ |
90 | Improper neutralization of special elements used in an LDAP command (LDAP injection) | ✓ |
91 | XML injection (aka blind XPath injection) | ✓ |
99 | Improper control of resource identifiers (resource injection) | ✓ |
117 | Improper output neutralization for logs | ✓ |
118 | Improper access of indexable resource | ✓ |
119 | Improper restriction of operations within the bounds of a memory buffer | ✓ |
120 | Buffer copy without checking size of input (‘classic buffer overflow‘) | ✓ |
121 | Stack-based buffer overflow | ✓ |
122 | Heap-based buffer overflow | ✓ |
123 | Write-what-where condition | ✓ |
124 | Buffer underwrite | ✓ |
125 | Out-of-bounds read | ✓ |
126 | Buffer over-read | ✓ |
127 | Buffer under-read | ✓ |
128 | Wrap-around error | ✓ |
129 | Improper validation of array index | ✓ |
130 | Improper handling of length parameter inconsistency | ✓ |
131 | Incorrect calculation of buffer size | ✓ |
134 | Uncontrolled format string | ✓ |
135 | Incorrect calculation of multi-byte string length | ✓ |
170 | Improper null termination | ✓ |
188 | Reliance on data/memory layout | ✓ |
190 | Integer overflow or wraparound | ✓ |
191 | Integer underflow or wraparound | ✓ |
192 | Integer coercion error | ✓ |
193 | Off-by-one error | ✓ |
194 | Unexpected sign extension | ✓ |
195 | Signed to unsigned conversion error | ✓ |
196 | Unsigned to signed conversion error | ✓ |
197 | Numeric truncation error | ✓ |
240 | Improper handling of inconsistent structural elements | ✓ |
242 | Use of inherently dangerous function | ✓ |
244 | Improper clearing of heap memory before release (‘heap inspection’) | ✓ |
248 | Uncaught exception | ✓ |
252 | Unchecked return value | ✓ |
253 | Incorrect check of function return value | ✓ |
328 | Reversible one-way hash | ✓ |
362 | Concurrent execution using shared resource with improper synchronization (‘race condition’) | ✓ |
364 | Signal handler race condition | ✓ |
365 | Race condition in switch | ✓ |
366 | Race condition within a thread | ✓ |
367 | Time-of-check time-of-use (TOCTOU) race condition | ✓ |
369 | Divde by zero | ✓ |
398 | Indicator of poor code quality | ✓ |
401 | Improper release of memory before removing last reference (memory leak) | ✓ |
404 | Improper resource shutdown or release | ✓ |
411 | Resource locking problems | ✓ |
415 | Double free | ✓ |
416 | Use after free | ✓ |
456 | Missing initialization of a variable | ✓ |
457 | Use of uninitialized variable | ✓ |
460 | Improper cleanup on thrown exception | ✓ |
463 | Deletion of data structure sentinel | ✓ |
464 | Addition of data structure sentinel | ✓ |
466 | Return of pointer value outside of expected range | ✓ |
467 | Use of sizeof() on a pointer type | ✓ |
468 | Incorrect pointer scaling | ✓ |
471 | Modification of assumed-immutable data (MAID) | ✓ |
475 | Undefined behavior for input to API | ✓ |
476 | NULL pointer dereference | ✓ |
477 | Use of obsolete functions | ✓ |
478 | Missing default case in switch statement | ✓ |
479 | Signal handler use of a non-reentrant function | ✓ |
480 | Use of incorrect operator | ✓ |
481 | Assigning instead of comparing | ✓ |
482 | Comparing instead of assigning | ✓ |
497 | Exposure of system data to an unauthorized control sphere | ✓ |
543 | Use of singleton pattern without synchronization in a multi-threaded context | ✓ |
558 | Use of getlogin() in multithreaded application | ✓ |
561 | Dead code | ✓ |
562 | Return of stack variable address | ✓ |
563 | Assignment to variable without use (‘unused variable’) | ✓ |
567 | Unsynchronized access to shared data in a multithreaded context | ✓ |
573 | Improper following of specification by caller | ✓ |
587 | Assignment of a fixed address to a pointer | ✓ |
588 | Attempt to access child of a nonstructure pointer | ✓ |
606 | Unchecked input for loop condition | ✓ |
611 | Improper restriction of XML External Entity reference (XXE) | ✓ |
628 | Function call with incorrectly specified arguments | ✓ |
643 | Improper neutralization of data within XPath expressions (XPath injection) | ✓ |
662 | Improper synchronization | ✓ |
663 | Use of a non-reentrant function in a concurrent context | ✓ |
665 | Improper initialization | ✓ |
666 | Operation on resource in wrong phase of lifetime | ✓ |
667 | Improper locking | ✓ |
672 | Operation on a resource after expiration or release | ✓ |
676 | Use of potentially dangerous function | ✓ |
680 | Integer overflow to buffer overflow | ✓ |
681 | Incorrect conversion between numeric types | ✓ |
682 | Incorrect calculation | ✓ |
685 | Function call with incorrect number of arguments | ✓ |
686 | Function call with incorrect argument type | ✓ |
690 | Unchecked return value to NULL pointer dereference | ✓ |
704 | Incorrect type conversion or cast | ✓ |
754 | Improper check for unusual or exceptional conditions | ✓ |
759 | Use of a one-way hash without a salt | ✓ |
761 | Free of pointer not at start of buffer | ✓ |
762 | Mismatched memory management routines | ✓ |
763 | Release of invalid pointer or reference | ✓ |
764 | Multiple locks of a critical resource | ✓ |
765 | Multiple unlocks of a critical resource | ✓ |
766 | Critical data element declared public | ✓ |
767 | Access to critical private variable via public method | ✓ |
783 | Operator precedence logic error | ✓ |
785 | Use of path manipulation function without maximum-sized buffer | ✓ |
786 | Access of memory location before start of buffer | ✓ |
787 | Out-of-bounds write | ✓ |
789 | Uncontrolled memory allocation | ✓ |
805 | Buffer access with incorrect length value | ✓ |
806 | Buffer access using size of source buffer | ✓ |
807 | Reliance on untrusted inputs in a security decision | ✓ |
822 | Untrusted pointer dereference | ✓ |
823 | Use of out-of-range pointer offset | ✓ |
824 | Access of uninitialized pointer | ✓ |
825 | Expired pointer dereference | ✓ |
831 | Signal handler function associated with multiple signals | ✓ |
832 | Unlock of a resource that is not locked | ✓ |
833 | Deadlock | ✓ |
835 | Loop with unreachable exit condition (‘infinite loop’) | ✓ |
843 | Access of resource using incompatible type (‘type confusion’) | ✓ |
908 | Use of uninitialized resource | ✓ |
910 | Use of expired file descriptor | ✓ |
911 | Improper update of reference count | ✓ |
1325 | Improperly controlled sequential memory allocation | ✓ |
1335 | Incorrect bitwise shift or integer | ✓ |
1341 | Multiple releases of same resource or handle | ✓ |
Below are the lists of SEI CERT rules and recommendations for C and C++ supported by Astrée and RuleChecker as of release 24.04 or higher. Exclamation marks denote recommendations that by definition cannot be checked for statically. Further details are available in the documentation included with the software, or by contacting info@absint.com.
Rule 01: Preprocessor | ||
PRE.0 | Prefer inline or static functions to function-like macros | ✓ |
PRE.1 | Use parentheses within macros around parameter names | ✓ |
PRE.5 | Understand macro replacement when concatenating tokens or performing stringification |
! |
PRE.6 | Enclose header files in an inclusion guard | ✓ |
PRE.7 | Avoid using repeated question marks | ✓ |
PRE.9 | Do not replace secure functions with deprecated or obsolescent functions | ✓ |
PRE.11 | Do not conclude macro definitions with a semicolon | ✓ |
PRE.12 | Do not define unsafe macros | ✓ |
PRE.30 | Do not create a universal character name through concatenation | ✓ |
PRE.31 | Avoid side effects in arguments to unsafe macros | ✓ |
PRE.32 | Do not use preprocessor directives in invocations of function-like macros | ✓ |
Rule 02: Declarations and initialization | ||
DCL.0 | Const-qualify immutable objects | ✓ |
DCL.1 | Do not reuse variable names in subscopes | ✓ |
DCL.5 | Use typedefs of non-pointer types only | ✓ |
DCL.7 | Include the appropriate type information in function declarators | ✓ |
DCL.8 | Properly encode relationships in constant definitions | ! |
DCL.10 | Maintain the contract between the writer and caller of variadic functions | ✓ |
DCL.11 | Understand the type issues associated with variadic functions | ! |
DCL.13 | Declare function parameters that are pointers to values not changed by the function as const |
✓ |
DCL.15 | Declare file-scope objects or functions that do not need external linkage as static | ✓ |
DCL.16 | Use L , not l , to indicate a long value |
✓ |
DCL.17 | Beware of miscompiled volatile-qualified variables | ! |
DCL.18 | Do not begin integer constants with 0 when specifying a decimal value |
✓ |
DCL.19 | Minimize the scope of variables and functions | ✓ |
DCL.20 | Explicitly specify void when a function accepts no arguments |
✓ |
DCL.21 | Understand the storage of compound literals | ! |
DCL.22 | Use volatile for data that cannot be cached | ! |
DCL.23 | Guarantee that mutually visible identifiers are unique | ✓ |
DCL.30 | Declare objects with appropriate storage durations | ✓ |
DCL.31 | Declare identifiers before using them | ✓ |
DCL.36 | Do not declare an identifier with conflicting linkage classifications | ✓ |
DCL.37 | Do not declare or define a reserved identifier | ✓ |
DCL.38 | Use the correct syntax when declaring a flexible array member | ✓ |
DCL.39 | Avoid information leakage when passing a structure across a trust boundary | ✓ |
DCL.40 | Do not create incompatible declarations of the same function or object | ✓ |
DCL.41 | Do not declare variables inside a switch statement before the first case label |
✓ |
Rule 03: Expressions | ||
EXP.2 | Be aware of the short-circuit behavior of the logical AND and OR operators | ✓ |
EXP.3 | Do not assume the size of a structure is the sum of the sizes of its members | ✓ |
EXP.5 | Do not cast away a const qualification | ✓ |
EXP.8 | Ensure pointer arithmetic is used correctly | ✓ |
EXP.9 | Use sizeof to determine the size of a type or variable |
✓ |
EXP.10 | Do not depend on the order of evaluation of subexpressions or the order in which side effects take place |
✓ |
EXP.11 | Do not make assumptions regarding the layout of structures with bit-fields | ✓ |
EXP.12 | Do not ignore values returned by functions | ✓ |
EXP.13 | Treat relational and equality operators as if they were non-associative | ✓ |
EXP.14 | Beware of integer promotion when performing bitwise operations on integer types smaller than int | ✓ |
EXP.15 | Do not place a semicolon on the same line as an if , for , or while statement |
✓ |
EXP.16 | Do not compare function pointers to constant values | ✓ |
EXP.19 | Use braces for the body of an if , for , or while statement |
✓ |
EXP.20 | Perform explicit tests to determine success, true and false, and equality | ✓ |
EXP.30 | Do not depend on the order of evaluation for side effects | ✓ |
EXP.32 | Do not access a volatile object through a nonvolatile reference | ✓ |
EXP.33 | Do not read uninitialized memory | ✓ |
EXP.34 | Do not dereference null pointers | ✓ |
EXP.35 | Do not modify objects with temporary lifetime | ✓ |
EXP.36 | Do not cast pointers into more strictly aligned pointer types | ✓ |
EXP.37 | Call functions with the correct number and type of arguments | ✓ |
EXP.40 | Do not modify constant objects | ✓ |
EXP.42 | Do not compare padding data | ✓ |
EXP.43 | Avoid undefined behavior when using restrict-qualified pointers | ✓ |
EXP.44 | Do not rely on side effects in operands to sizeof , _Alignof , or _Generic |
✓ |
EXP.45 | Do not perform assignments in selection statements | ✓ |
EXP.46 | Do not use a bitwise operator with a Boolean-like operand | ✓ |
Rule 04: Integers | ||
INT.0 | Understand the data model used by your implementation(s) | ! |
INT.2 | Understand integer conversion rules | ! |
INT.7 | Use only explicitly signed or unsigned char type for numeric values | ✓ |
INT.8 | Verify that all integer values are in range | ✓ |
INT.9 | Ensure enumeration constants map to unique values | ✓ |
INT.12 | Do not make assumptions about the type of a plain int bit-field when used in an expression |
✓ |
INT.13 | Use bitwise operators only on unsigned operands | ✓ |
INT.16 | Do not make assumptions about representation of signed integers | ✓ |
INT.18 | Evaluate integer expressions in a larger size before comparing or assigning to that size |
✓ |
INT.30 | Ensure that unsigned integer operations do not wrap | ✓ |
INT.31 | Ensure that integer conversions do not result in lost or misinterpreted data | ✓ |
INT.32 | Ensure that operations on signed integers do not result in overflow | ✓ |
INT.33 | Ensure that division and remainder operations do not result in divide-by-zero errors | ✓ |
INT.34 | 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 |
✓ |
INT.35 | Use correct integer precisions | ✓ |
INT.36 | Converting a pointer to integer or integer to pointer | ✓ |
Rule 05: Floating point | ||
FLP.0 | Understand the limitations of floating-point numbers | ! |
FLP.1 | Take care in rearranging floating-point expressions | ! |
FLP.2 | Avoid using floating-point numbers when precise computation is needed | ✓ |
FLP.3 | Detect and handle floating-point errors | ✓ |
FLP.4 | Check floating-point inputs for exceptional values | ✓ |
FLP.6 | Convert integers to floating point for floating-point operations | ✓ |
FLP.30 | Do not use floating-point variables as loop counters | ✓ |
FLP.32 | Prevent or detect domain and range errors in math functions | ✓ |
FLP.34 | Ensure that floating-point conversions are within range of the new type | ✓ |
FLP.36 | Preserve precision when converting integral values to floating-point type | ✓ |
FLP.37 | Do not use object representations to compare floating-point values | ✓ |
Rule 06: Arrays | ||
ARR.0 | Understand how arrays work | ! |
ARR.1 | Do not apply the sizeof operator to a pointer when taking the size of an array | ✓ |
ARR.2 | Explicitly specify array bounds, even if implicitly defined by an initializer | ✓ |
ARR.30 | Do not form or use out-of-bounds pointers or array subscripts | ✓ |
ARR.36 | Do not subtract or compare two pointers that do not refer to the same array | ✓ |
ARR.37 | Do not add or subtract an integer to a pointer to a non-array object | ✓ |
ARR.38 | Guarantee that library functions do not form invalid pointers | ✓ |
ARR.39 | Do not add or subtract a scaled integer to a pointer | ✓ |
Rule 07: Characters and strings | ||
STR.0 | Represent characters using an appropriate type | ✓ |
STR.4 | Use plain char for characters in the basic character set | ✓ |
STR.5 | Use pointers to const when referring to string literals | ✓ |
STR.9 | Don’t assume numeric values for expressions with type plain character | ✓ |
STR.10 | Do not concatenate different types of string literals | ✓ |
STR.11 | Do not specify the bound of a character array initialized with a string literal | ✓ |
STR.30 | Do not attempt to modify string literals | ✓ |
STR.31 | Guarantee that storage for strings has sufficient space for character data and the null terminator |
✓ |
STR.32 | Do not pass a non-null-terminated character sequence to a library function that expects a string |
✓ |
STR.34 | Cast characters to unsigned char before converting to larger integer sizes | ✓ |
STR.37 | Arguments to character-handling functions must be representable as an unsigned char | ✓ |
STR.38 | Do not confuse narrow and wide character strings and functions | ✓ |
Rule 08: Memory management | ||
MEM.1 | Store a new value in pointers immediately after free() |
✓ |
MEM.2 | Immediately cast the result of a memory-allocation function call into a pointer to the allocated type | ✓ |
MEM.4 | Beware of zero-length allocations | ✓ |
MEM.7 | Ensure that the arguments to calloc() , when multiplied, do not wrap |
✓ |
MEM.30 | Do not access freed memory | ✓ |
MEM.31 | Free dynamically allocated memory when no longer needed | ✓ |
MEM.33 | Allocate and copy structures containing a flexible array member dynamically | ✓ |
MEM.34 | Only free memory allocated dynamically | ✓ |
MEM.35 | Allocate sufficient memory for an object | ✓ |
MEM.36 | Do not modify the alignment of objects by calling realloc() |
✓ |
Rule 09: Input/output | ||
FIO.14 | Understand the difference between text mode and binary mode with file streams | ! |
FIO.37 | Do not assume that fgets() or fgetws()
returns a nonempty string when successful |
✓ |
FIO.38 | Do not copy a FILE object | ✓ |
FIO.39 | Do not alternately input and output from a stream without an intervening flush or positioning call | ✓ |
FIO.41 | Do not call getc() , putc() ,
getwc() or putwc()
with a stream argument that has side effects |
✓ |
FIO.42 | Close files when they are no longer needed | ✓ |
Rule 10: Environment | ||
ENV.30 | Do not modify the object referenced by the return value of certain functions | ✓ |
ENV.31 | Do not rely on an environment pointer following an operation that may invalidate it | ✓ |
ENV.33 | Do not call system() |
✓ |
Rule 11: Signals | ||
SIG.1 | Understand implementation-specific details regarding signal handler persistence | ! |
SIG.30 | Call only asynchronous-safe functions within signal handlers | ✓ |
SIG.31 | Do not access shared objects in signal handlers | ✓ |
SIG.34 | Do not call signal() from within interruptible signal handlers |
✓ |
Rule 12: Error handling | ||
ERR.6 | Understand the termination behavior of assert() and abort() |
! |
ERR.7 | Prefer functions that support error checking over equivalent functions that don’t | ✓ |
ERR.30 | Set errno to zero before calling a library function known to set errno ,
and check errno only after the function returns a value indicating failure |
✓ |
ERR.33 | Detect and handle standard library errors | ✓ |
Rule 13: Application Programming Interfaces (API) | ||
API.8 | Avoid parameter names in a function prototype | ✓ |
Rule 14: Concurrency | ||
CON.0 | Avoid race conditions with multiple threads | ✓ |
CON.1 | Acquire and release synchronization primitives in the same module, at the same level of abstraction |
✓ |
CON.3 | Ensure visibility when accessing shared variables | ✓ |
CON.6 | Ensure that every mutex outlives the data it protects | ✓ |
CON.30 | Clean up thread-specific storage | ✓ |
CON.31 | Do not destroy a mutex while it is locked | ✓ |
CON.32 | Prevent data races when accessing bit-fields from multiple threads | ✓ |
CON.33 | Avoid race conditions when using library functions | ✓ |
CON.35 | Avoid deadlock by locking in a predefined order | ✓ |
CON.37 | Do not call signal() in a multithreaded program |
✓ |
CON.39 | Do not join or detach a thread that was previously joined or detached | ✓ |
CON.40 | Do not refer to an atomic variable twice in an expression | ✓ |
CON.43 | Do not allow data races in multithreaded code | ✓ |
Rule 48: Miscellaneous | ||
MSC.1 | Strive for logical completeness | ✓ |
MSC.4 | Use comments consistently and in a readable fashion | ✓ |
MSC.7 | Detect and remove dead code | ✓ |
MSC.12 | Detect and remove code that has no effect or is never executed | ✓ |
MSC.13 | Detect and remove unused values | ✓ |
MSC.15 | Do not depend on undefined behavior | ✓ |
MSC.17 | Finish every set of statements associated with a case labelwith a break statement |
✓ |
MSC.20 | Do not use a switch statement to transfer control into a complex block |
✓ |
MSC.21 | Use robust loop termination conditions | ✓ |
MSC.23 | Beware of vendor-specific library and language differences | ✓ |
MSC.24 | Do not use deprecated or obsolescent functions | ✓ |
MSC.30 | Do not use the rand() function for generating pseudorandom numbers |
✓ |
MSC.32 | Properly seed pseudorandom number generators | ✓ |
MSC.33 | Do not pass invalid data to the asctime() function |
✓ |
MSC.37 | Ensure that control never reaches the end of a non-void function | ✓ |
MSC.40 | Do not violate constraints | ✓ |
Recommendation 01: Preprocessor | ||
PRE00-C | Prefer inline or static functions to function-like macros | ✓ |
PRE01-C | Use parentheses within macros around parameter names | ✓ |
PRE05-C | Understand macro replacement when concatenating tokens or performing stringification |
! |
PRE06-C | Enclose header files in an inclusion guard | ✓ |
PRE07-C | Avoid using repeated question marks | ✓ |
PRE09-C | Do not replace secure functions with deprecated or obsolescent functions | ✓ |
PRE11-C | Do not conclude macro definitions with a semicolon | ✓ |
PRE12-C | Do not define unsafe macros | ✓ |
Recommendation 02: Declarations and initialization | ||
DCL00-C | Const-qualify immutable objects | ✓ |
DCL01-C | Do not reuse variable names in subscopes | ✓ |
DCL05-C | Use typedefs of non-pointer types only | ✓ |
DCL07-C | Include the appropriate type information in function declarators | ✓ |
DCL08-C | Properly encode relationships in constant definitions | ! |
DCL10-C | Maintain the contract between the writer and caller of variadic functions | ✓ |
DCL11-C | Understand the type issues associated with variadic functions | ! |
DCL13-C | Declare function parameters that are pointers to values not changed by the function as const |
✓ |
DCL15-C | Declare file-scope objects or functions that do not need external linkage as static | ✓ |
DCL16-C | Use L , not l , to indicate a long value |
✓ |
DCL17-C | Beware of miscompiled volatile-qualified variables | ! |
DCL18-C | Do not begin integer constants with 0 when specifying a decimal value |
✓ |
DCL19-C | Minimize the scope of variables and functions | ✓ |
DCL20-C | Explicitly specify void when a function accepts no arguments |
✓ |
DCL21-C | Understand the storage of compound literals | ! |
DCL22-C | Use volatile for data that cannot be cached | ! |
DCL23-C | Guarantee that mutually visible identifiers are unique | ✓ |
Recommendation 03: Expressions | ||
EXP02-C | Be aware of the short-circuit behavior of the logical AND and OR operators | ✓ |
EXP03-C | Do not assume the size of a structure is the sum of the sizes of its members | ✓ |
EXP08-C | Ensure pointer arithmetic is used correctly | ✓ |
EXP10-C | Do not depend on the order of evaluation of subexpressions or the order in which side effects take place |
✓ |
EXP12-C | Do not ignore values returned by functions | ✓ |
EXP19-C | Use braces for the body of an if , for , or while statement |
✓ |
EXP20-C | Perform explicit tests to determine success, true and false, and equality | ✓ |
Recommendation 04: Integers | ||
INT00-C | Understand the data model used by your implementation(s) | ! |
INT02-C | Understand integer conversion rules | ! |
INT07-C | Use only explicitly signed or unsigned char type for numeric values | ✓ |
INT08-C | Verify that all integer values are in range | ✓ |
INT09-C | Ensure enumeration constants map to unique values | ✓ |
INT12-C | Do not make assumptions about the type of a plain int bit-field when used in an expression |
✓ |
INT13-C | Use bitwise operators only on unsigned operands | ✓ |
INT18-C | Evaluate integer expressions in a larger size before comparing or assigning to that size |
✓ |
Recommendation 05: Floating point | ||
FLP00-C | Understand the limitations of floating-point numbers | ! |
FLP01-C | Take care in rearranging floating-point expressions | ! |
FLP02-C | Avoid using floating-point numbers when precise computation is needed | ✓ |
FLP03-C | Detect and handle floating-point errors | ✓ |
FLP04-C | Check floating-point inputs for exceptional values | ✓ |
FLP06-C | Convert integers to floating point for floating-point operations | ✓ |
Recommendation 06: Arrays | ||
ARR00-C | Understand how arrays work | ! |
ARR02-C | Explicitly specify array bounds, even if implicitly defined by an initializer | ✓ |
Recommendation 07: Characters and strings | ||
STR00-C | Represent characters using an appropriate type | ✓ |
STR04-C | Use plain char for characters in the basic character set | ✓ |
STR09-C | Don’t assume numeric values for expressions with type plain character | ✓ |
STR11-C | Do not specify the bound of a character array initialized with a string literal | ✓ |
Recommendation 08: Memory management | ||
MEM01-C | Store a new value in pointers immediately after free() |
✓ |
MEM04-C | Beware of zero-length allocations | ✓ |
MEM07-C | Ensure that the arguments to calloc() , when multiplied, do not wrap |
✓ |
Recommendation 09: Input/output | ||
FIO14-C | Understand the difference between text mode and binary mode with file streams | ! |
Recommendation 11: Signals | ||
SIG01-C | Understand implementation-specific details regarding signal handler persistence | ! |
Recommendation 12: Error handling | ||
ERR06-C | Understand the termination behavior of assert() and abort() |
! |
Recommendation 14: Concurrency | ||
CON00-C | Avoid race conditions with multiple threads | ✓ |
CON01-C | Acquire and release synchronization primitives in the same module, at the same level of abstraction |
✓ |
CON03-C | Ensure visibility when accessing shared variables | ✓ |
CON06-C | Ensure that every mutex outlives the data it protects | ✓ |
Recommendation 15: Concurrency (POSIX) | ||
CON00-C | Avoid race conditions with multiple threads | ✓ |
Recommendation 48: Miscellaneous | ||
MSC01-C | Strive for logical completeness | ✓ |
MSC04-C | Use comments consistently and in a readable fashion | ✓ |
MSC07-C | Detect and remove dead code | ✓ |
MSC12-C | Detect and remove code that has no effect or is never executed | ✓ |
MSC13-C | Detect and remove unused values | ✓ |
MSC15-C | Do not depend on undefined behavior | ✓ |
MSC17-C | Finish every set of statements associated with a case label
with a break statement |
✓ |
MSC20-C | Do not use a switch statement to transfer control into a complex block |
✓ |
MSC23-C | Beware of vendor-specific library and language differences | ✓ |
MSC24-C | Do not use deprecated or obsolescent functions | ✓ |
Recommendation 51: Microsoft Windows | ||
WIN03-C | Understand HANDLE inheritance | ! |
Declarations and initialization | ||
DCL.30 | Declare objects with appropriate storage durations | ✓ |
DCL.40 | Do not create incompatible declarations of the same function or object | ✓ |
DCL.50 | Do not define a C-style variadic function | ✓ |
DCL.51 | Do not declare or define a reserved identifier | ✓ |
DCL.54 | Overload allocation and deallocation functions as a pair in the same scope | ✓ |
DCL.57 | Do not let exceptions escape from descructors or deallocation functions | ✓ |
DCL.59 | Do not define an unnamed namespace in a header file | ✓ |
DCL.60 | Obey the one-definition rule | ✓ |
Expressions | ||
EXP.52 | Do not rely on side effects in unevaluated operands | ✓ |
EXP.53 | Do not read uninitialized memory | ✓ |
EXP.54 | Do not access an object outside of its lifetime | ✓ |
EXP.55 | Do not access a cv-qualified object through a cv-unqualified type | ✓ |
EXP.57 | Do not cast or delete pointers to incomplete classes | ✓ |
EXP.61 | A lambda object must not outlive any of its reference captured objects | ✓ |
EXP.62 | Do not access the bits of an object representation that are not part of the object’s value representation | ✓ |
Arrays | ||
ARR.30 | Do not form or use out-of-bounds pointers or array subscripts | ✓ |
Containers | ||
CTR.50 | Guarantee that container indices and iterators are within the valid range | ✓ |
CTR.51 | Use valid references, pointers, and iterators to reference elements of a container | ✓ |
CTR.52 | Guarantee that library functions do not overflow | ✓ |
CTR.53 | Use valid iterator ranges | ✓ |
CTR.54 | Do not subtract iterators that do not refer to the same container | ✓ |
Characters and strings | ||
STR.51 | Do not attempt to create a std::string from a null pointer |
✓ |
STR.53 | Range check element access | ✓ |
Memory management | ||
MEM.50 | Do not access freed memory | ✓ |
MEM.51 | Properly deallocate dynamically allocated resources | ✓ |
MEM.56 | Do not store an already-owned pointer value in an unrelated smart pointer | ✓ |
Environment | ||
ENV.33 | Do not call system() |
✓ |
Exceptions and error handling | ||
ERR.33 | Detect and handle standard library errors | ✓ |
ERR.50 | Do not abruptly terminate the program | ✓ |
ERR.51 | Handle all exceptions | ✓ |
ERR.52 | Do not use setjmp() or longjmp() |
✓ |
ERR.53 | Do not reference base classes or class data members in a constructor or destructor function-try-block handler | ✓ |
ERR.54 | Catch handlers should order their parameter types from most derived to least derived | ✓ |
ERR.55 | Honor exception specifications | ✓ |
ERR.58 | Handle all exceptions thrown before main() begins executing |
✓ |
ERR.61 | Catch exceptions by lvalue reference | ✓ |
Object oriented programming | ||
OOP.50 | Do not invoke virtual functions from constructors or destructors | ✓ |
OOP.52 | Do not delete a polymorphic object without a virtual destructor | ✓ |
OOP.53 | Write constructor member initializers in the canonical order | ✓ |
OOP.54 | Gracefully handle self-copy assignment | ✓ |
OOP.55 | Do not use pointer-to-member operators to access nonexistent members | ✓ |
OOP.57 | Prefer special member functions and overloaded operators to C Standard Library functions | ✓ |
Concurrency | ||
CON.37 | Do not call signal() in a multithreaded program |
✓ |
CON.52 | Prevent data races when accessing bit-fields from multiple threads | ✓ |
Miscellaneous | ||
MSC.30 | Do not use the rand() function for generating pseudorandom numbers |
✓ |
MSC.32 | Properly seed pseudorandom number generators | ✓ |
MSC.37 | Ensure that control never reaches the end of a non-void function | ✓ |
MSC.50 | Do not use std::rand() for generating pseudorandom numbers |
✓ |
MSC.51 | Ensure your random number generator is properly seeded | ✓ |
MSC.52 | Value-returning functions must return a value from all exit paths | ✓ |
MSC.53 | Do not return from a function declared [[noreturn]] | ✓ |
Below is the list of ISO/IEC rules and diagnostics supported as of release 24.04 or higher. Further details on individual rules are available from within the software via the “Help” menu, or by contacting info@absint.com.
accfree | Accessing freed memory | ✓ |
accsig | Accessing shared objects in signal handlers | ✓ |
addrescape | Escaping of the address of an automatic object | ✓ |
alignconv | Converting pointer values to more strictly aligned pointer types | ✓ |
argcomp | Calling functions with incorrect arguments | ✓ |
asyncsig | Calling functions in the C Standard Library other than
abort , _Exit , and signal from within a signal handler |
✓ |
boolasgn | No assignment in conditional expressions. | ✓ |
chrsgnext | Passing arguments to character-handling functions that are not representable as unsigned char. | ✓ |
dblfree | Freeing memory multiple times | ✓ |
diverr | Integer division errors | ✓ |
filecpy | Copying a FILE object | ✓ |
funcdecl | Declaring the same function or object in incompatible ways | ✓ |
insufmem | Allocating insufficient memory | ✓ |
intoflow | Overflowing signed integers | ✓ |
intptrconv | Converting a pointer to integer or integer to pointer | ✓ |
inverrno | Incorrectly setting and using errno |
✓ |
invfmtstr | Using invalid format strings | ✓ |
invptr | Forming or using out-of-bounds pointers or array subscripts | ✓ |
ioileave | Interleaving stream inputs and outputs without a flush or positioning call | ✓ |
liberr | Failing to detect and handle standard library errors | ✓ |
libmod | Modifying the string returned by
getenv , localeconv , setlocale , and strerror |
✓ |
libptr | Forming invalid pointers by library function | ✓ |
libuse | Using an object overwritten by getenv , localeconv , setlocale , and strerror |
✓ |
nonnullcs | Passing a non-null-terminated character sequence to a library function that expects a string | ✓ |
nullref | Dereferencing an out-of-domain pointer | ✓ |
padcomp | Comparison of padding data | ✓ |
ptrcomp | Accessing an object through a pointer to an incompatible type | ✓ |
ptrobj | Subtracting or comparing two pointers that do not refer to the same array | ✓ |
resident | Using identifiers that are reserved for the implementation | ✓ |
restrict | Passing pointers into the same object as arguments to different restrict-qualified parameters | ✓ |
sigcall | Calling signal from interruptible signal handlers | ✓ |
signconv | Conversion of signed characters to wider integer types before a check for EOF | ✓ |
sizeofptr | Taking the size of a pointer to determine the size of the pointed-to type | ✓ |
strmod | Modifying string literals | ✓ |
swtchdflt | Use of an implied default in a switch statement | ✓ |
syscall | Calling system | ✓ |
taintformatio | Using a tainted value to write to an object using a formatted input or output function | ✓ |
taintnoproto | Using a tainted value as an argument to an unprototyped function pointer | ✓ |
taintsink | Tainted, potentially mutilated, or out-of-domain integer values are used in a restricted sink | ✓ |
taintstrcpy | Tainted strings are passed to a string copying function | ✓ |
uninitref | Referencing uninitialized memory | ✓ |
usrfmt | Including tainted or out-of-domain input in a format string | ✓ |
xfilepos | Using a value for fsetpos other than a value returned from fgetpos |
✓ |
xfree | Reallocating or freeing memory that was not dynamically allocated | ✓ |
Constraint violations | ||
6.2.7p2 | Two declarations that declare the same entity must be of compatible type | ✓ |
6.2.7p2 | At least one type specifier shall be given in a declaration | ✓ |
6.5.2.2p2 | The number of arguments shall agree with the number of parameters | ✓ |
6.5.4p3 | No implicit conversion shall be performed between pointer types and integer types | ✓ |
6.7.5.2p1 | If the size expression of an array declarator is constant, it shall have a value greater than zero | ✓ |
6.7.10p2 | The constant expression of a static assert shall compare unequal to zero | ✓ |
Language extensions | ||
4p5 | Assembler code shall be avoided | ✓ |
4p5 | Data placement at an absolute location shall be avoided | ✓ |
4p5 | Enums shall not be forward-declared, i.e. used as complete type before being defined | ✓ |
4p5 | Lvalue casts shall be avoided | ✓ |
4p5 | Non-standard keywords shall not be used | ✓ |
4p5 | Pointer attributes shall be avoided | ✓ |
4p5 | GCC’s statement expressions shall not be used | ✓ |
6.5.1p2 | Implicit function declaration shall not be used | ✓ |
6.6p10 | Only integer constant expressions stricly conforming to the C standard shall be used | ✓ |
Implementation-defined behavior | ||
6.3.2.3p5+6 | No cast shall be performed between pointer types and integer types | ✓ |
6.4.4.4p10 | The value of an integer character constant containing more than one character is implementation-defined | ✓ |
Unspecified behavior | ||
6.5 | The result of the evaluation of an expression shall not depend on the order of evaluation of subexpressions | ✓ |
6.7.8 | The result of the evaluation of an initializer list expression shall not depend on the order of evaluation of elements and subexpressions | ✓ |
As of release 24.04, Astrée covers 307 AUTOSAR C++14 coding rules, and RuleChecker on its own covers 292. A detailed 30-page PDF description of how each rule is handled comes included with the software. Contact info@absint.com with any questions.
Below is just a quick overview of the currently supported rule categories.
0 | Language independent issues | ✓ |
1 | General | ✓ |
2 | Lexical conventions | ✓ |
3 | Basic concepts | ✓ |
4 | Standard conversions | ✓ |
5 | Expressions | ✓ |
6 | Statements | ✓ |
7 | Declarations | ✓ |
8 | Declarators | ✓ |
9 | Classes | ✓ |
10 | Derived classes | ✓ |
11 | Member access control | ✓ |
12 | Special member functions | ✓ |
13 | Overloading | ✓ |
14 | Templates | ✓ |
15 | Exception handling | ✓ |
16 | Preprocessing directives | ✓ |
17 | Library instruction | ✓ |
18 | Language support library | ✓ |
19 | Diagnostics library | ✓ |
27 | Input/output library | ✓ |
At the US National Institute of Standards and Technology, the Software Assurance Metrics And Tool Evaluation project, or SAMATE for short, is dedicated to improving software assurance by developing methods for evaluating software tools, measuring their effectiveness, and identifying gaps in methods and techniques.
The SAMATE project recognizes the value and importance of sound static code analyzers. During the 6th Static Analysis Tool Exposition (SATE VI), the NIST team evaluated static analyzers with respect to the SATE VI Ockham Sound Analysis Criteria.
In brief, these criteria are:
The definition of a finding includes reporting a buggy site as buggy, but also passing a correct code location without alarm. In other words, in order to satisfy the SATE VI Ockham Sound Analysis Criteria, all defects must be found, and the rate of false alarms must be low.
Astrée was run on 28 sets of test cases from the Juliet 1.3 C test suite, containing a total of 18,954 buggy sites. All 18,954 were reported by Astrée.
These included test cases for buffer overflows/underflows, invalid pointer dereferences, integer overflows/underflows, divisions by zero, use of uninitialized variables, dead code, infinite loops, double free and use after free.
Additionally, Astrée discovered thousands of unintended defects in the Juliet 1.3 benchmark set.
The SAMATE report emphasizes Astrée’s outstanding precision, both with respect to the analysis results as well as the analysis model itself.
“Alarms from Astrée led us to find and fix thousands of mistakes in what was intended as the Juliet known-bug list, manifest.xml.
Because Astrée analyzes code very precisely and we checked meticulously, details of modeling that otherwise would be inconsequential showed up and had to be resolved.”
The full report was published in May 2020 and is available for free as PDF from
nvlpubs.nist.gov/nistpubs/ir/2020/NIST.IR.8304.pdf
Various code metrics are automatically compiled by the static analysis. For each metric, you can optionally specify thresholds to check your code against, essentially creating additional custom rules of your own.
Comment density | ✓ |
Cyclomatic complexity | ✓ |
Number of return statements | ✓ |
Number of goto statements | ✓ |
Number of instructions per function | ✓ |
Number of parameters | ✓ |
Number of maintainable code lines | ✓ |
Maximum nesting of control structures | ✓ |
Maximum number of execution paths | ✓ |
Number of called functions | ✓ |
Number of calling functions | ✓ |
Number of recursive paths | ✓ |
Language scope | ✓ |
These optional rules cover the naming of all C identifiers. For each kind of identifier, you can specify a maximum and minimum length, and check the spelling using regular expressions.
Function naming | |
All functions | ✓ |
Global functions | ✓ |
Static functions | ✓ |
Parameters | ✓ |
Macro naming | |
All macros | ✓ |
Function-like macros | ✓ |
Object-like macros | ✓ |
Member naming | |
All members | ✓ |
Struct members | ✓ |
Union members | ✓ |
Bitfields | ✓ |
Object naming | |
All objects | ✓ |
Global objects | ✓ |
Static objects | ✓ |
Local objects | ✓ |
Tag naming | |
All tags | ✓ |
Enumeration tags | ✓ |
Struct tags | ✓ |
Union tags | ✓ |
Type naming | |
All types | ✓ |
Struct types | ✓ |
Enumeration naming | |
Enumeration constants | ✓ |
We have ample experience with extending RuleChecker for various customers with their very own in-house rule sets. Please contact info@absint.com with any questions.