Skip to content

Commit eac06dd

Browse files
committed
C/C++ overlay: Address review comments
Split the discard predicate into two: one for single-location elements and one for multi-location elements.
1 parent 3d69286 commit eac06dd

File tree

1 file changed

+32
-41
lines changed

1 file changed

+32
-41
lines changed

cpp/ql/lib/semmle/code/cpp/internal/Overlay.qll

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,58 +16,49 @@ private string getLocationFilePath(@location_default loc) {
1616
}
1717

1818
/**
19-
* An element with a single location. Discard if in a changed file.
19+
* Gets the file path for an element with a single location.
2020
*/
2121
overlay[local]
22-
abstract private class Discardable extends @element {
23-
abstract string getFilePath();
24-
25-
predicate existsInBase() { not isOverlay() }
26-
27-
string toString() { none() }
28-
}
29-
30-
overlay[discard_entity]
31-
private predicate discardable(@element e) {
32-
e = any(Discardable d | d.existsInBase() and overlayChangedFiles(d.getFilePath()))
22+
private string getSingleLocationFilePath(@element e) {
23+
// @var_decl has a direct location in the var_decls relation
24+
exists(@location_default loc | var_decls(e, _, _, _, loc) | result = getLocationFilePath(loc))
25+
//TODO: add other kinds of elements with single locations
3326
}
3427

3528
/**
36-
* An element with potentially multiple locations, e.g., variables, functions and types.
37-
* Discard only if all locations are in changed files.
29+
* Gets the file path for an element with potentially multiple locations.
3830
*/
3931
overlay[local]
40-
abstract private class MultiDiscardable extends @element {
41-
abstract string getFilePath();
42-
43-
predicate existsInBase() { not isOverlay() }
44-
45-
string toString() { none() }
32+
private string getMultiLocationFilePath(@element e) {
33+
// @variable gets its location(s) from its @var_decl(s)
34+
exists(@var_decl vd, @location_default loc | var_decls(vd, e, _, _, loc) |
35+
result = getLocationFilePath(loc)
36+
)
37+
//TODO: add other kinds of elements with multiple locations
4638
}
4739

48-
overlay[discard_entity]
49-
private predicate multiDiscardable(@element e) {
50-
e =
51-
any(MultiDiscardable d |
52-
d.existsInBase() and
53-
forall(string path | path = d.getFilePath() | overlayChangedFiles(path))
54-
)
40+
/** Holds if `e` exists in the base variant. */
41+
overlay[local]
42+
private predicate existsInBase(@element e) {
43+
not isOverlay() and
44+
(exists(getSingleLocationFilePath(e)) or exists(getMultiLocationFilePath(e)))
5545
}
5646

57-
overlay[local]
58-
private class DiscardableVarDecl extends Discardable instanceof @var_decl {
59-
override string getFilePath() {
60-
exists(@location_default loc | var_decls(this, _, _, _, loc) |
61-
result = getLocationFilePath(loc)
62-
)
63-
}
47+
/**
48+
* Discard an element with a single location if it is in a changed file.
49+
*/
50+
overlay[discard_entity]
51+
private predicate discardSingleLocationElement(@element e) {
52+
existsInBase(e) and
53+
overlayChangedFiles(getSingleLocationFilePath(e))
6454
}
6555

66-
overlay[local]
67-
private class DiscardableVariable extends MultiDiscardable instanceof @variable {
68-
override string getFilePath() {
69-
exists(@var_decl vd, @location_default loc | var_decls(vd, this, _, _, loc) |
70-
result = getLocationFilePath(loc)
71-
)
72-
}
56+
/**
57+
* Discard an element with multiple locations only if all its locations are in changed files.
58+
*/
59+
overlay[discard_entity]
60+
private predicate discardMultiLocationElement(@element e) {
61+
existsInBase(e) and
62+
exists(getMultiLocationFilePath(e)) and
63+
forall(string path | path = getMultiLocationFilePath(e) | overlayChangedFiles(path))
7364
}

0 commit comments

Comments
 (0)