Skip to content

Commit 671620f

Browse files
committed
Rule 5.4: Improve alert message, ensure efficient performance
1 parent 08c0aaf commit 671620f

File tree

2 files changed

+49
-16
lines changed

2 files changed

+49
-16
lines changed

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

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,52 @@ import codingstandards.cpp.Macro
1919
import codingstandards.cpp.Includes
2020
import codingstandards.cpp.PreprocessorDirective
2121

22+
/**
23+
* Gets a top level element that this macro is expanded to, e.g. an element which does not also have
24+
* an enclosing element in the macro.
25+
*/
26+
Element getATopLevelElement(MacroInvocation mi) {
27+
result = mi.getAnExpandedElement() and
28+
not result.getEnclosingElement() = mi.getAnExpandedElement() and
29+
not result instanceof Conversion
30+
}
31+
2232
/**
2333
* Gets a link target that this macro is expanded in.
2434
*/
2535
LinkTarget getALinkTarget(Macro m) {
26-
exists(Element e | e = m.getAnInvocation().getAnAffectedElement() |
36+
exists(MacroInvocation mi, Element e |
37+
mi = m.getAnInvocation() and
38+
e = getATopLevelElement(mi)
39+
|
2740
result = e.(Expr).getEnclosingFunction().getALinkTarget()
2841
or
2942
result = e.(Stmt).getEnclosingFunction().getALinkTarget()
3043
or
3144
exists(GlobalOrNamespaceVariable g |
3245
result = g.getALinkTarget() and
33-
g.getInitializer().getExpr().getAChild*() = e
46+
g = e.(Expr).getEnclosingDeclaration()
3447
)
3548
)
3649
}
3750

38-
from Macro m, Macro m2
51+
/**
52+
* Holds if the m1 and m2 are unconditionally included from a common file.
53+
*
54+
* Extracted out for performance reasons - otherwise the call to determine the file path for the
55+
* message was specializing the calls to `getAnUnconditionallyIncludedFile*(..)` and causing
56+
* slow performance.
57+
*/
58+
bindingset[m1, m2]
59+
pragma[inline_late]
60+
private predicate isIncludedUnconditionallyFromCommonFile(Macro m1, Macro m2) {
61+
exists(File f |
62+
getAnUnconditionallyIncludedFile*(f) = m1.getFile() and
63+
getAnUnconditionallyIncludedFile*(f) = m2.getFile()
64+
)
65+
}
66+
67+
from Macro m, Macro m2, string message
3968
where
4069
not isExcluded(m, Declarations1Package::macroIdentifiersNotDistinctQuery()) and
4170
not m = m2 and
@@ -44,9 +73,18 @@ where
4473
//C90 states the first 31 characters of macro identifiers are significant and is not currently considered by this rule
4574
//ie an identifier differing on the 32nd character would be indistinct for C90 but distinct for C99
4675
//and is currently not reported by this rule
47-
if m.getName().length() >= 64
48-
then m.getName().prefix(63) = m2.getName().prefix(63)
49-
else m.getName() = m2.getName()
76+
if m.getName().length() >= 64 and not m.getName() = m2.getName()
77+
then (
78+
m.getName().prefix(63) = m2.getName().prefix(63) and
79+
message =
80+
"Macro identifer " + m.getName() + " is nondistinct in first 63 characters, compared to $@."
81+
) else (
82+
m.getName() = m2.getName() and
83+
message =
84+
"Definition of macro " + m.getName() +
85+
" is not distinct from alternative definition of $@ in " +
86+
m2.getLocation().getFile().getRelativePath() + "."
87+
)
5088
) and
5189
//reduce double report since both macros are in alert, arbitrary ordering
5290
m.getLocation().getStartLine() >= m2.getLocation().getStartLine() and
@@ -59,10 +97,7 @@ where
5997
) and
6098
// Must be included unconditionally from the same file, otherwise m1 may not be defined
6199
// when m2 is defined
62-
exists(File f |
63-
getAnUnconditionallyIncludedFile*(f) = m.getFile() and
64-
getAnUnconditionallyIncludedFile*(f) = m2.getFile()
65-
) and
100+
isIncludedUnconditionallyFromCommonFile(m, m2) and
66101
// Macros can't be mutually exclusive
67102
not mutuallyExclusiveMacros(m, m2) and
68103
not mutuallyExclusiveMacros(m2, m) and
@@ -74,6 +109,4 @@ where
74109
// Must share a link target - e.g. must both be expanded in the same context
75110
getALinkTarget(m) = getALinkTarget(m2)
76111
)
77-
select m,
78-
"Macro identifer " + m.getName() + " is nondistinct in first 63 characters, compared to $@.", m2,
79-
m2.getName()
112+
select m, message, m2, m2.getName()
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
| header3.h:7:1:7:24 | #define MULTIPLE_INCLUDE | Macro identifer MULTIPLE_INCLUDE is nondistinct in first 63 characters, compared to $@. | header4.h:1:1:1:24 | #define MULTIPLE_INCLUDE | MULTIPLE_INCLUDE |
2-
| header3.h:14:1:14:21 | #define NOT_PROTECTED | Macro identifer NOT_PROTECTED is nondistinct in first 63 characters, compared to $@. | header4.h:12:1:12:23 | #define NOT_PROTECTED 1 | NOT_PROTECTED |
1+
| header3.h:7:1:7:24 | #define MULTIPLE_INCLUDE | Definition of macro MULTIPLE_INCLUDE is not distinct from alternative definition of $@ in rules/RULE-5-4/header4.h. | header4.h:1:1:1:24 | #define MULTIPLE_INCLUDE | MULTIPLE_INCLUDE |
2+
| header3.h:14:1:14:21 | #define NOT_PROTECTED | Definition of macro NOT_PROTECTED is not distinct from alternative definition of $@ in rules/RULE-5-4/header4.h. | header4.h:12:1:12:23 | #define NOT_PROTECTED 1 | NOT_PROTECTED |
33
| test.c:2:1:2:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB | Macro identifer iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB is nondistinct in first 63 characters, compared to $@. | test.c:1:1:1:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA | iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA |
4-
| test.c:8:1:8:31 | #define FUNCTION_MACRO(X) X + 1 | Macro identifer FUNCTION_MACRO is nondistinct in first 63 characters, compared to $@. | test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | FUNCTION_MACRO |
4+
| test.c:8:1:8:31 | #define FUNCTION_MACRO(X) X + 1 | Definition of macro FUNCTION_MACRO is not distinct from alternative definition of $@ in rules/RULE-5-4/test.c. | test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | FUNCTION_MACRO |

0 commit comments

Comments
 (0)