Skip to content

Commit dd07767

Browse files
committed
Rule 2.5: Consider macros accessed before definition
1 parent f9070ca commit dd07767

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

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

Lines changed: 11 additions & 0 deletions
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\\((.*)\\).*", 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

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,35 @@
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+
#define CHECKED_MACRO_BEFORE_1 // COMPLIANT - used in branch
46+
#define CHECKED_MACRO_BEFORE_2 // COMPLIANT - used in branch
47+
#define CHECKED_MACRO_BEFORE_3 // COMPLIANT - used in branch

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

Lines changed: 2 additions & 0 deletions
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)