Skip to content

Rule 2.5: Consider macros accessed before definition #777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions c/misra/src/rules/RULE-2-5/UnusedMacroDeclaration.ql
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,18 @@ import codingstandards.c.misra
from Macro m
where
not isExcluded(m, DeadCodePackage::unusedMacroDeclarationQuery()) and
// We consider a macro "used" if there is a macro access
not exists(MacroAccess ma | ma.getMacro() = m) and
// Or if there exists a check whether the macro is defined which the extractor
// hasn't been able to tie to a macro (usually because this use came before
// the macro was defined e.g. a header guard)
not exists(PreprocessorBranchDirective bd |
// Covers the #ifdef and #ifndef cases
bd.getHead() = m.getName()
or
// Covers the use of defined() to check if a macro is defined
m.getName() = bd.getHead().regexpCapture(".*defined *\\(? *([^\\s()]+) *\\)?\\.*", 1)
) and
// We consider a macro "used" if the name is undef-ed at some point in the same file, or a file
// that includes the file defining the macro. This will over approximate use in the case of a
// macro which is defined, then undefined, then re-defined but not used.
Expand Down
53 changes: 52 additions & 1 deletion c/misra/test/rules/RULE-2-5/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,55 @@
void test() {
MACRO2;
HEADER_MACRO2;
}
}

#define CHECKED_MACRO_1 // COMPLIANT - used in branch
#define CHECKED_MACRO_2 // COMPLIANT - used in branch
#define CHECKED_MACRO_3 // COMPLIANT - used in branch

#ifdef CHECKED_MACRO_1
#endif

#ifndef CHECKED_MACRO_2
#endif

#if defined(CHECKED_MACRO_3)
#endif

// In the case above, the extractor will identify macro accesses with each use
// of the macro. In the case above, the extractor does not tie them together,
// but the standard considers this acceptable usage. Notably, this type of
// pattern occurs for header guards.

#ifdef CHECKED_MACRO_BEFORE_1
#endif

#ifndef CHECKED_MACRO_BEFORE_2
#endif

#if defined(CHECKED_MACRO_BEFORE_3)
#endif

// clang-format off

#if defined (CHECKED_MACRO_BEFORE_4)
#endif

#if defined( CHECKED_MACRO_BEFORE_5 )
#endif

#if defined ( CHECKED_MACRO_BEFORE_6 )
#endif

#if defined CHECKED_MACRO_BEFORE_7
#endif

// clang-format on

#define CHECKED_MACRO_BEFORE_1 // COMPLIANT - used in branch
#define CHECKED_MACRO_BEFORE_2 // COMPLIANT - used in branch
#define CHECKED_MACRO_BEFORE_3 // COMPLIANT - used in branch
#define CHECKED_MACRO_BEFORE_4 // COMPLIANT - used in branch
#define CHECKED_MACRO_BEFORE_5 // COMPLIANT - used in branch
#define CHECKED_MACRO_BEFORE_6 // COMPLIANT - used in branch
#define CHECKED_MACRO_BEFORE_7 // COMPLIANT - used in branch
2 changes: 2 additions & 0 deletions change_notes/2024-10-22-rule-2-5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- `RULE-2-5` - `UnusedMacroDeclaration.ql`:
- Exclude false positives where a macro was used before definition, for example a header guard.
Loading