Skip to content

Commit 2c253f3

Browse files
committed
C++: Support x-macros that are #undef'ed in header
This fixes a false positive on https://github.com/zduka/tpp.
1 parent e7dfb3e commit 2c253f3

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,32 +95,55 @@ predicate usesMacro(HeaderFile hf, string macroName) {
9595
)
9696
}
9797

98-
/**
99-
* File `f` both defines and un-defines a macro called `macroName`.
100-
*/
101-
predicate defUndef(File f, string macroName) {
98+
/** File `f` defines a macro called `macroName`. */
99+
predicate definesMacro(File f, string macroName) {
102100
exists(Macro m |
103101
m.getFile() = f and
104102
m.getName() = macroName
105-
) and exists(PreprocessorUndef ud |
103+
)
104+
}
105+
106+
/** File `f` un-defines a macro called `macroName`. */
107+
predicate undefinesMacro(File f, string macroName) {
108+
exists(PreprocessorUndef ud |
106109
ud.getFile() = f and
107110
ud.getName() = macroName
108111
)
109112
}
110113

114+
/**
115+
* File `f` both defines and un-defines a macro called `macroName`.
116+
*/
117+
predicate defUndef(File f, string macroName) {
118+
definesMacro(f, macroName) and
119+
undefinesMacro(f, macroName)
120+
}
121+
111122
/**
112123
* Header file `hf` looks like it contains an x-macro.
113124
* That is, a macro that is used to interpret the
114125
* data in `hf`, usually defined just before including that file
115126
* and undefined immediately afterwards.
116127
*/
117128
predicate hasXMacro(HeaderFile hf) {
129+
// Every header that includes `hf` both defines and undefines a macro that's
130+
// used in `hf`.
118131
exists(string macroName |
119132
usesMacro(hf, macroName) and
120133
forex(File f | f.getAnIncludedFile() = hf |
121134
defUndef(f, macroName)
122135
)
123136
)
137+
or
138+
// Every header that includes `hf` defines a macro that's used in `hf`, and
139+
// `hf` itself undefines it.
140+
exists(string macroName |
141+
usesMacro(hf, macroName) and
142+
undefinesMacro(hf, macroName) and
143+
forex(File f | f.getAnIncludedFile() = hf |
144+
definesMacro(f, macroName)
145+
)
146+
)
124147
}
125148

126149
from HeaderFile hf, string detail, MaybePreprocessorDirective detail1, MaybePreprocessorDirective detail2

cpp/ql/test/query-tests/jsf/4.07 Header Files/AV Rule 35/AV Rule 35.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
| complexcondition2.h:0:0:0:0 | complexcondition2.h | This header file should contain a header guard to prevent multiple inclusion. | file://:0:0:0:0 | | | file://:0:0:0:0 | | |
22
| complexcondition.h:0:0:0:0 | complexcondition.h | This header file should contain a header guard to prevent multiple inclusion. | file://:0:0:0:0 | | | file://:0:0:0:0 | | |
33
| fundecl.h:0:0:0:0 | fundecl.h | This header file should contain a header guard to prevent multiple inclusion. | file://:0:0:0:0 | | | file://:0:0:0:0 | | |
4-
| items3.h:0:0:0:0 | items3.h | This header file should contain a header guard to prevent multiple inclusion. | file://:0:0:0:0 | | | file://:0:0:0:0 | | |
54
| multipleguards.h:0:0:0:0 | multipleguards.h | This header file should contain a header guard to prevent multiple inclusion ($@ matching $@ occurs before the end of the file). | multipleguards.h:7:1:7:6 | #endif | #endif | multipleguards.h:2:1:2:24 | #ifndef MULTIPLEGUARDS_H | #ifndef MULTIPLEGUARDS_H |
65
| namespace1.h:0:0:0:0 | namespace1.h | This header file should contain a header guard to prevent multiple inclusion. | file://:0:0:0:0 | | | file://:0:0:0:0 | | |
76
| namespace2.h:0:0:0:0 | namespace2.h | This header file should contain a header guard to prevent multiple inclusion. | file://:0:0:0:0 | | | file://:0:0:0:0 | | |

0 commit comments

Comments
 (0)