Skip to content

Commit 922cf64

Browse files
Dave Bartolomeordmarsh2
authored andcommitted
C++/C#: Add combineOverlap() predicate
1 parent 86b1d03 commit 922cf64

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

cpp/ql/src/semmle/code/cpp/ir/internal/Overlap.qll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ private newtype TOverlap =
88
*/
99
abstract class Overlap extends TOverlap {
1010
abstract string toString();
11+
12+
/**
13+
* Gets a value representing how precise this overlap is. The higher the value, the more precise
14+
* the overlap. The precision values are ordered as
15+
* follows, from most to least precise:
16+
* `MustExactlyOverlap`
17+
* `MustTotallyOverlap`
18+
* `MayPartiallyOverlap`
19+
*/
20+
abstract int getPrecision();
1121
}
1222

1323
/**
@@ -16,6 +26,8 @@ abstract class Overlap extends TOverlap {
1626
*/
1727
class MayPartiallyOverlap extends Overlap, TMayPartiallyOverlap {
1828
final override string toString() { result = "MayPartiallyOverlap" }
29+
30+
final override int getPrecision() { result = 0 }
1931
}
2032

2133
/**
@@ -24,6 +36,8 @@ class MayPartiallyOverlap extends Overlap, TMayPartiallyOverlap {
2436
*/
2537
class MustTotallyOverlap extends Overlap, TMustTotallyOverlap {
2638
final override string toString() { result = "MustTotallyOverlap" }
39+
40+
final override int getPrecision() { result = 1 }
2741
}
2842

2943
/**
@@ -32,4 +46,25 @@ class MustTotallyOverlap extends Overlap, TMustTotallyOverlap {
3246
*/
3347
class MustExactlyOverlap extends Overlap, TMustExactlyOverlap {
3448
final override string toString() { result = "MustExactlyOverlap" }
49+
50+
final override int getPrecision() { result = 2 }
51+
}
52+
53+
/**
54+
* Gets the `Overlap` that best represents the relationship between two memory locations `a` and
55+
* `c`, where `getOverlap(a, b) = previousOverlap` and `getOverlap(b, c) = newOverlap`, for some
56+
* intermediate memory location `b`.
57+
*/
58+
Overlap combineOverlap(Overlap previousOverlap, Overlap newOverlap) {
59+
// Note that it's possible that two less precise overlaps could combine to result in a more
60+
// precise overlap. For example, both `previousOverlap` and `newOverlap` could be
61+
// `MustTotallyOverlap` even though the actual relationship between `a` and `c` is
62+
// `MustExactlyOverlap`. We will still return `MustTotallyOverlap` as the best conservative
63+
// approximation we can make without additional input information.
64+
result =
65+
min(Overlap overlap |
66+
overlap = [previousOverlap, newOverlap]
67+
|
68+
overlap order by overlap.getPrecision()
69+
)
3570
}

csharp/ql/src/experimental/ir/internal/Overlap.qll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ private newtype TOverlap =
88
*/
99
abstract class Overlap extends TOverlap {
1010
abstract string toString();
11+
12+
/**
13+
* Gets a value representing how precise this overlap is. The higher the value, the more precise
14+
* the overlap. The precision values are ordered as
15+
* follows, from most to least precise:
16+
* `MustExactlyOverlap`
17+
* `MustTotallyOverlap`
18+
* `MayPartiallyOverlap`
19+
*/
20+
abstract int getPrecision();
1121
}
1222

1323
/**
@@ -16,6 +26,8 @@ abstract class Overlap extends TOverlap {
1626
*/
1727
class MayPartiallyOverlap extends Overlap, TMayPartiallyOverlap {
1828
final override string toString() { result = "MayPartiallyOverlap" }
29+
30+
final override int getPrecision() { result = 0 }
1931
}
2032

2133
/**
@@ -24,6 +36,8 @@ class MayPartiallyOverlap extends Overlap, TMayPartiallyOverlap {
2436
*/
2537
class MustTotallyOverlap extends Overlap, TMustTotallyOverlap {
2638
final override string toString() { result = "MustTotallyOverlap" }
39+
40+
final override int getPrecision() { result = 1 }
2741
}
2842

2943
/**
@@ -32,4 +46,25 @@ class MustTotallyOverlap extends Overlap, TMustTotallyOverlap {
3246
*/
3347
class MustExactlyOverlap extends Overlap, TMustExactlyOverlap {
3448
final override string toString() { result = "MustExactlyOverlap" }
49+
50+
final override int getPrecision() { result = 2 }
51+
}
52+
53+
/**
54+
* Gets the `Overlap` that best represents the relationship between two memory locations `a` and
55+
* `c`, where `getOverlap(a, b) = previousOverlap` and `getOverlap(b, c) = newOverlap`, for some
56+
* intermediate memory location `b`.
57+
*/
58+
Overlap combineOverlap(Overlap previousOverlap, Overlap newOverlap) {
59+
// Note that it's possible that two less precise overlaps could combine to result in a more
60+
// precise overlap. For example, both `previousOverlap` and `newOverlap` could be
61+
// `MustTotallyOverlap` even though the actual relationship between `a` and `c` is
62+
// `MustExactlyOverlap`. We will still return `MustTotallyOverlap` as the best conservative
63+
// approximation we can make without additional input information.
64+
result =
65+
min(Overlap overlap |
66+
overlap = [previousOverlap, newOverlap]
67+
|
68+
overlap order by overlap.getPrecision()
69+
)
3570
}

0 commit comments

Comments
 (0)