Skip to content

Commit f7dc7b8

Browse files
committed
C/C++ overlay: add discard predicate consistency query
1 parent 3012c8a commit f7dc7b8

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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+
* Consistency query predicate for checking that every database entity
15+
* is covered by the discard predicates in Overlay.qll.
16+
*
17+
* This query is intended to flag cases where new entity types are added
18+
* to the dbscheme but the corresponding discard predicate is not updated.
19+
*
20+
* An element is considered covered if it has a path via either
21+
* `getSingleLocationFilePath` or `getMultiLocationFilePath`.
22+
*/
23+
query predicate consistencyTest(Element element, string message) {
24+
(
25+
// Check that every @element has a path via the discard predicates
26+
not exists(getSingleLocationFilePath(element)) and
27+
not exists(getMultiLocationFilePath(element)) and
28+
// Exclude global/synthetic entities that don't need to be discarded
29+
not element instanceof @specifier and
30+
not element instanceof @builtintype and
31+
not element instanceof @derivedtype and
32+
not element instanceof @routinetype and
33+
not element instanceof @ptrtomember and
34+
not element instanceof @decltype and
35+
not element instanceof @type_operator and
36+
not element instanceof @specialnamequalifyingelement and
37+
// Exclude files/folders (handled separately by overlay infrastructure)
38+
not element instanceof @file and
39+
not element instanceof @folder and
40+
// Exclude XML entities (not C++ code)
41+
not element instanceof @xmllocatable and
42+
// Exclude compiler diagnostics (metadata, not source entities)
43+
not element instanceof @diagnostic and
44+
// Exclude usertypes without declarations (compiler built-ins like 'auto', '__va_list')
45+
not (element instanceof @usertype and not exists(@type_decl td | type_decls(td, element, _))) and
46+
// Exclude namespaces without declarations (global namespace)
47+
not (
48+
element instanceof @namespace and
49+
not exists(@namespace_decl nd | namespace_decls(nd, element, _, _))
50+
) and
51+
// Exclude functions without declarations (compiler-generated like implicit operator=)
52+
not (
53+
element instanceof @function and not exists(@fun_decl fd | fun_decls(fd, element, _, _, _))
54+
) and
55+
// Exclude variables without declarations (parameters of compiler-generated functions)
56+
not (
57+
element instanceof @variable and not exists(@var_decl vd | var_decls(vd, element, _, _, _))
58+
) and
59+
exists(Location loc | loc = element.getLocation() |
60+
message =
61+
element.getPrimaryQlClasses() + " at " + loc.getFile().getRelativePath() + ":" +
62+
loc.getStartLine().toString() + " not covered by discard predicates"
63+
)
64+
)
65+
}

0 commit comments

Comments
 (0)