Skip to content

Commit 58ab33a

Browse files
committed
C/C++ overlay: add discard predicate consistency query
1 parent 90d8548 commit 58ab33a

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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

Comments
 (0)