Skip to content

Commit ac00467

Browse files
authored
Merge pull request #777 from github/lcartey/rule-2-5-alt-uses
Rule 2.5: Consider macros accessed before definition
2 parents 7efe754 + cbcf037 commit ac00467

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

c/misra/src/rules/RULE-2-5/UnusedMacroDeclaration.ql

+11
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,18 @@ import codingstandards.c.misra
1919
from Macro m
2020
where
2121
not isExcluded(m, DeadCodePackage::unusedMacroDeclarationQuery()) and
22+
// We consider a macro "used" if there is a macro access
2223
not exists(MacroAccess ma | ma.getMacro() = m) and
24+
// Or if there exists a check whether the macro is defined which the extractor
25+
// hasn't been able to tie to a macro (usually because this use came before
26+
// the macro was defined e.g. a header guard)
27+
not exists(PreprocessorBranchDirective bd |
28+
// Covers the #ifdef and #ifndef cases
29+
bd.getHead() = m.getName()
30+
or
31+
// Covers the use of defined() to check if a macro is defined
32+
m.getName() = bd.getHead().regexpCapture(".*defined *\\(? *([^\\s()]+) *\\)?\\.*", 1)
33+
) and
2334
// We consider a macro "used" if the name is undef-ed at some point in the same file, or a file
2435
// that includes the file defining the macro. This will over approximate use in the case of a
2536
// macro which is defined, then undefined, then re-defined but not used.

c/misra/test/rules/RULE-2-5/test.c

+52-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,55 @@
1313
void test() {
1414
MACRO2;
1515
HEADER_MACRO2;
16-
}
16+
}
17+
18+
#define CHECKED_MACRO_1 // COMPLIANT - used in branch
19+
#define CHECKED_MACRO_2 // COMPLIANT - used in branch
20+
#define CHECKED_MACRO_3 // COMPLIANT - used in branch
21+
22+
#ifdef CHECKED_MACRO_1
23+
#endif
24+
25+
#ifndef CHECKED_MACRO_2
26+
#endif
27+
28+
#if defined(CHECKED_MACRO_3)
29+
#endif
30+
31+
// In the case above, the extractor will identify macro accesses with each use
32+
// of the macro. In the case above, the extractor does not tie them together,
33+
// but the standard considers this acceptable usage. Notably, this type of
34+
// pattern occurs for header guards.
35+
36+
#ifdef CHECKED_MACRO_BEFORE_1
37+
#endif
38+
39+
#ifndef CHECKED_MACRO_BEFORE_2
40+
#endif
41+
42+
#if defined(CHECKED_MACRO_BEFORE_3)
43+
#endif
44+
45+
// clang-format off
46+
47+
#if defined (CHECKED_MACRO_BEFORE_4)
48+
#endif
49+
50+
#if defined( CHECKED_MACRO_BEFORE_5 )
51+
#endif
52+
53+
#if defined ( CHECKED_MACRO_BEFORE_6 )
54+
#endif
55+
56+
#if defined CHECKED_MACRO_BEFORE_7
57+
#endif
58+
59+
// clang-format on
60+
61+
#define CHECKED_MACRO_BEFORE_1 // COMPLIANT - used in branch
62+
#define CHECKED_MACRO_BEFORE_2 // COMPLIANT - used in branch
63+
#define CHECKED_MACRO_BEFORE_3 // COMPLIANT - used in branch
64+
#define CHECKED_MACRO_BEFORE_4 // COMPLIANT - used in branch
65+
#define CHECKED_MACRO_BEFORE_5 // COMPLIANT - used in branch
66+
#define CHECKED_MACRO_BEFORE_6 // COMPLIANT - used in branch
67+
#define CHECKED_MACRO_BEFORE_7 // COMPLIANT - used in branch

change_notes/2024-10-22-rule-2-5.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `RULE-2-5` - `UnusedMacroDeclaration.ql`:
2+
- Exclude false positives where a macro was used before definition, for example a header guard.

0 commit comments

Comments
 (0)