Skip to content

Commit 34abb42

Browse files
committed
Rule 5.4: Exclude cases where the two macros are conditional
- Macros in #ifndef MACRO_NAME blocks - Pairs of macros that exists in different #if/#elif/#else cases - Pairs of macros defined in files that are mutually exclusively included. - If the macros are used, they must be both occur in the same link target.
1 parent 1543019 commit 34abb42

File tree

1 file changed

+44
-1
lines changed

1 file changed

+44
-1
lines changed

c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,25 @@
1515

1616
import cpp
1717
import codingstandards.c.misra
18+
import codingstandards.cpp.Macro
19+
import codingstandards.cpp.Includes
20+
import codingstandards.cpp.PreprocessorDirective
21+
22+
/**
23+
* Gets a link target that this macro is expanded in.
24+
*/
25+
LinkTarget getALinkTarget(Macro m) {
26+
exists(Element e | e = m.getAnInvocation().getAnAffectedElement() |
27+
result = e.(Expr).getEnclosingFunction().getALinkTarget()
28+
or
29+
result = e.(Stmt).getEnclosingFunction().getALinkTarget()
30+
or
31+
exists(GlobalOrNamespaceVariable g |
32+
result = g.getALinkTarget() and
33+
g.getInitializer().getExpr().getAChild*() = e
34+
)
35+
)
36+
}
1837

1938
from Macro m, Macro m2
2039
where
@@ -30,7 +49,31 @@ where
3049
else m.getName() = m2.getName()
3150
) and
3251
//reduce double report since both macros are in alert, arbitrary ordering
33-
m.getLocation().getStartLine() >= m2.getLocation().getStartLine()
52+
m.getLocation().getStartLine() >= m2.getLocation().getStartLine() and
53+
// Not within an #ifndef MACRO_NAME
54+
not exists(PreprocessorIfndef ifBranch |
55+
m.getAGuard() = ifBranch or
56+
m2.getAGuard() = ifBranch
57+
|
58+
ifBranch.getHead() = m.getName()
59+
) and
60+
// Must be included unconditionally from the same file, otherwise m1 may not be defined
61+
// when m2 is defined
62+
exists(File f |
63+
getAnUnconditionallyIncludedFile*(f) = m.getFile() and
64+
getAnUnconditionallyIncludedFile*(f) = m2.getFile()
65+
) and
66+
// Macros can't be mutually exclusive
67+
not mutuallyExclusiveMacros(m, m2) and
68+
not mutuallyExclusiveMacros(m2, m) and
69+
// If at least one invocation exists for at least one of the macros, then they must share a link
70+
// target - i.e. must both be expanded in the same context
71+
(
72+
(exists(m.getAnInvocation()) and exists(m2.getAnInvocation()))
73+
implies
74+
// Must share a link target - e.g. must both be expanded in the same context
75+
getALinkTarget(m) = getALinkTarget(m2)
76+
)
3477
select m,
3578
"Macro identifer " + m.getName() + " is nondistinct in first 63 characters, compared to $@.", m2,
3679
m2.getName()

0 commit comments

Comments
 (0)