-
Notifications
You must be signed in to change notification settings - Fork 77
Expand file tree
/
Copy pathUndefOfMacroNotDefinedInFile.ql
More file actions
66 lines (55 loc) · 2.05 KB
/
UndefOfMacroNotDefinedInFile.ql
File metadata and controls
66 lines (55 loc) · 2.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
* @id cpp/misra/undef-of-macro-not-defined-in-file
* @name RULE-19-0-4: #undef should only be used for macros defined previously in the same file
* @description Using #undef to undefine a macro that is not defined in the same file can lead to
* confusion.
* @kind problem
* @precision very-high
* @problem.severity warning
* @tags external/misra/id/rule-19-0-4
* scope/single-translation-unit
* readability
* maintainability
* external/misra/enforcement/decidable
* external/misra/obligation/advisory
*/
import cpp
import codingstandards.cpp.misra
import codingstandards.cpp.util.CondensedList
import codingstandards.cpp.util.Pair
class DefOrUndef extends PreprocessorDirective {
string name;
DefOrUndef() {
name = this.(PreprocessorUndef).getName() or
name = this.(Macro).getName()
}
string getName() { result = name }
}
predicate relevantNameAndFile(string name, File file) {
exists(DefOrUndef m |
m.getName() = name and
m.getFile() = file
)
}
class StringFilePair = Pair<string, File>::Where<relevantNameAndFile/2>::Pair;
module DefUndefListConfig implements CondensedListSig {
class Division = StringFilePair;
class Item = DefOrUndef;
int getSparseIndex(StringFilePair division, DefOrUndef directive) {
directive.getName() = division.getFirst() and
directive.getFile() = division.getSecond() and
result = directive.getLocation().getStartLine()
}
}
class ListEntry = Condense<DefUndefListConfig>::ListEntry;
from PreprocessorUndef undef, ListEntry defUndefListEntry
where
not isExcluded(undef, PreprocessorPackage::undefOfMacroNotDefinedInFileQuery()) and
// There exists a def or undef for a given name and file, and it is an #undef
undef = defUndefListEntry.getItem() and
// Exclude cases where the previous def or undef with the same name in the same file is a #define
not exists(ListEntry prev |
prev = defUndefListEntry.getPrev() and
prev.getItem() instanceof Macro
)
select undef, "Undef of name '" + undef.getName() + "' not defined in the same file."