C++: Support x-macros that are #undef'ed in header

This fixes a false positive on https://github.com/zduka/tpp.
This commit is contained in:
Jonas Jensen
2019-08-28 11:56:50 +02:00
parent e7dfb3e61b
commit 2c253f360a
2 changed files with 30 additions and 8 deletions

View File

@@ -95,17 +95,28 @@ predicate usesMacro(HeaderFile hf, string macroName) {
)
}
/** File `f` defines a macro called `macroName`. */
predicate definesMacro(File f, string macroName) {
exists(Macro m |
m.getFile() = f and
m.getName() = macroName
)
}
/** File `f` un-defines a macro called `macroName`. */
predicate undefinesMacro(File f, string macroName) {
exists(PreprocessorUndef ud |
ud.getFile() = f and
ud.getName() = macroName
)
}
/**
* File `f` both defines and un-defines a macro called `macroName`.
*/
predicate defUndef(File f, string macroName) {
exists(Macro m |
m.getFile() = f and
m.getName() = macroName
) and exists(PreprocessorUndef ud |
ud.getFile() = f and
ud.getName() = macroName
)
definesMacro(f, macroName) and
undefinesMacro(f, macroName)
}
/**
@@ -115,12 +126,24 @@ predicate defUndef(File f, string macroName) {
* and undefined immediately afterwards.
*/
predicate hasXMacro(HeaderFile hf) {
// Every header that includes `hf` both defines and undefines a macro that's
// used in `hf`.
exists(string macroName |
usesMacro(hf, macroName) and
forex(File f | f.getAnIncludedFile() = hf |
defUndef(f, macroName)
)
)
or
// Every header that includes `hf` defines a macro that's used in `hf`, and
// `hf` itself undefines it.
exists(string macroName |
usesMacro(hf, macroName) and
undefinesMacro(hf, macroName) and
forex(File f | f.getAnIncludedFile() = hf |
definesMacro(f, macroName)
)
)
}
from HeaderFile hf, string detail, MaybePreprocessorDirective detail1, MaybePreprocessorDirective detail2

View File

@@ -1,7 +1,6 @@
| 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 | | |
| 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 | | |
| 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 | | |
| 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 | | |
| 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 |
| 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 | | |
| 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 | | |