Skip to content

Commit 9fd31bf

Browse files
authored
Merge pull request #20909 from github/idrissrio/cpp/overlay/overlay.qll
C/C++ overlay: Add basic `Overlay.qll` file
2 parents c43b03b + 4ad25e4 commit 9fd31bf

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

cpp/ql/lib/cpp.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,4 @@ import semmle.code.cpp.Preprocessor
7474
import semmle.code.cpp.Iteration
7575
import semmle.code.cpp.NameQualifiers
7676
import DefaultOptions
77+
private import semmle.code.cpp.internal.Overlay
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* Defines entity discard predicates for C++ overlay analysis.
3+
*/
4+
5+
/**
6+
* Holds always for the overlay variant and never for the base variant.
7+
* This local predicate is used to define local predicates that behave
8+
* differently for the base and overlay variant.
9+
*/
10+
overlay[local]
11+
predicate isOverlay() { databaseMetadata("isOverlay", "true") }
12+
13+
overlay[local]
14+
private string getLocationFilePath(@location_default loc) {
15+
exists(@file file | locations_default(loc, file, _, _, _, _) | files(file, result))
16+
}
17+
18+
/**
19+
* Gets the file path for an element with a single location.
20+
*/
21+
overlay[local]
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
26+
}
27+
28+
/**
29+
* Gets the file path for an element with potentially multiple locations.
30+
*/
31+
overlay[local]
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
38+
}
39+
40+
/**
41+
* A local helper predicate that holds in the base variant and never in the
42+
* overlay variant.
43+
*/
44+
overlay[local]
45+
private predicate holdsInBase() { not isOverlay() }
46+
47+
/**
48+
* Discards an element from the base variant if:
49+
* - It has a single location in a changed file, or
50+
* - All of its locations are in changed files.
51+
*/
52+
overlay[discard_entity]
53+
private predicate discardElement(@element e) {
54+
holdsInBase() and
55+
(
56+
overlayChangedFiles(getSingleLocationFilePath(e))
57+
or
58+
forex(string path | path = getMultiLocationFilePath(e) | overlayChangedFiles(path))
59+
)
60+
}

0 commit comments

Comments
 (0)