|
| 1 | +/** |
| 2 | + * Provides consistency queries for checking that every database entity |
| 3 | + * that can be discarded (i.e. everything but `@compilation` and some external |
| 4 | + * entities) in an overlay database is indeed discarded. |
| 5 | + * |
| 6 | + * This validates that Overlay.qll's `getSingleLocationFilePath` and |
| 7 | + * `getMultiLocationFilePath` predicates cover all entity types. |
| 8 | + */ |
| 9 | + |
| 10 | +import cpp |
| 11 | +private import Overlay |
| 12 | + |
| 13 | +/** |
| 14 | + * Holds if `element` is not covered by the discard predicates in Overlay.qll. |
| 15 | + * |
| 16 | + * This query is intended to flag cases where new entity types are added |
| 17 | + * to the dbscheme but the corresponding discard predicate is not updated. |
| 18 | + * |
| 19 | + * An element is considered covered if it has a path via either |
| 20 | + * `getSingleLocationFilePath` or `getMultiLocationFilePath`. |
| 21 | + */ |
| 22 | +query predicate consistencyTest(Element element, string message) { |
| 23 | + ( |
| 24 | + // Check that every @element has a path via the discard predicates |
| 25 | + not exists(getSingleLocationFilePath(element)) and |
| 26 | + not exists(getMultiLocationFilePath(element)) and |
| 27 | + // Exclude global/synthetic entities that don't need to be discarded |
| 28 | + not element instanceof @specifier and |
| 29 | + not element instanceof @builtintype and |
| 30 | + not element instanceof @derivedtype and |
| 31 | + not element instanceof @routinetype and |
| 32 | + not element instanceof @ptrtomember and |
| 33 | + not element instanceof @decltype and |
| 34 | + not element instanceof @type_operator and |
| 35 | + not element instanceof @specialnamequalifyingelement and |
| 36 | + // Exclude files/folders (handled separately by overlay infrastructure) |
| 37 | + not element instanceof @file and |
| 38 | + not element instanceof @folder and |
| 39 | + // Exclude XML entities (not C++ code) |
| 40 | + not element instanceof @xmllocatable and |
| 41 | + // Exclude compiler diagnostics (metadata, not source entities) |
| 42 | + not element instanceof @diagnostic and |
| 43 | + // Exclude usertypes without declarations (compiler built-ins like 'auto', '__va_list') |
| 44 | + not (element instanceof @usertype and not exists(@type_decl td | type_decls(td, element, _))) and |
| 45 | + // Exclude namespaces without declarations (global namespace) |
| 46 | + not ( |
| 47 | + element instanceof @namespace and |
| 48 | + not exists(@namespace_decl nd | namespace_decls(nd, element, _, _)) |
| 49 | + ) and |
| 50 | + // Exclude functions without declarations (compiler-generated like implicit operator=) |
| 51 | + not ( |
| 52 | + element instanceof @function and not exists(@fun_decl fd | fun_decls(fd, element, _, _, _)) |
| 53 | + ) and |
| 54 | + // Exclude variables without declarations (parameters of compiler-generated functions) |
| 55 | + not ( |
| 56 | + element instanceof @variable and not exists(@var_decl vd | var_decls(vd, element, _, _, _)) |
| 57 | + ) and |
| 58 | + exists(Location loc | loc = element.getLocation() | |
| 59 | + message = |
| 60 | + element.getPrimaryQlClasses() + " at " + loc.getFile().getRelativePath() + ":" + |
| 61 | + loc.getStartLine().toString() + " not covered by discard predicates" |
| 62 | + ) |
| 63 | + ) |
| 64 | +} |
0 commit comments