|
23 | 23 | * }
|
24 | 24 | * ```
|
25 | 25 | *
|
| 26 | + * The provided predicates are separated into general "controls" predicates and |
| 27 | + * "directly controls" predicates. The former use all possible implication |
| 28 | + * logic as described above, whereas the latter only use control flow dominance |
| 29 | + * of the corresponding conditional successor edges. |
| 30 | + * |
| 31 | + * In some cases, a guard may have a successor edge that can be relevant for |
| 32 | + * controlling the input to an SSA phi node, but does not dominate the |
| 33 | + * preceding block. To support this, the `hasBranchEdge` and |
| 34 | + * `controlsBranchEdge` predicates are provided, where the former only uses the |
| 35 | + * control flow graph similar to the `directlyControls` predicate, and the |
| 36 | + * latter uses the full implication logic. |
| 37 | + * |
| 38 | + * All of these predicates are also available in the more general form that refers |
| 39 | + * to `GuardValue`s instead of `boolean`s. |
| 40 | + * |
26 | 41 | * The implementation is nested in two parameterized modules intended to
|
27 | 42 | * facilitate multiple instantiations of the nested module with different
|
28 |
| - * precision levels |
| 43 | + * precision levels. For example, more implications are available if the result |
| 44 | + * of Range Analysis is available, but Range Analysis depends on Guards. This |
| 45 | + * allows an initial instantiation of the `Logic` module without Range Analysis |
| 46 | + * that can be used as input to Range Analysis, and a second instantiation |
| 47 | + * using the result of Range Analysis to provide a final and more complete |
| 48 | + * controls relation. |
29 | 49 | */
|
30 | 50 |
|
31 | 51 | private import codeql.util.Boolean
|
@@ -178,6 +198,7 @@ signature module InputSig<LocationSig Location> {
|
178 | 198 | }
|
179 | 199 | }
|
180 | 200 |
|
| 201 | +/** Provides guards-related predicates and classes. */ |
181 | 202 | module Make<LocationSig Location, InputSig<Location> Input> {
|
182 | 203 | private import Input
|
183 | 204 |
|
@@ -513,6 +534,10 @@ module Make<LocationSig Location, InputSig<Location> Input> {
|
513 | 534 | }
|
514 | 535 | }
|
515 | 536 |
|
| 537 | + /** |
| 538 | + * Provides the `Guard` class with suitable 'controls' predicates augmented |
| 539 | + * with logical implications based on SSA. |
| 540 | + */ |
516 | 541 | module Logic<LogicInputSig LogicInput> {
|
517 | 542 | private import LogicInput
|
518 | 543 |
|
@@ -1016,7 +1041,8 @@ module Make<LocationSig Location, InputSig<Location> Input> {
|
1016 | 1041 |
|
1017 | 1042 | /**
|
1018 | 1043 | * A guard. This may be any expression whose value determines subsequent
|
1019 |
| - * control flow. |
| 1044 | + * control flow. It may also be a switch case, which as a guard is considered |
| 1045 | + * to evaluate to either true or false depending on whether the case matches. |
1020 | 1046 | */
|
1021 | 1047 | final class Guard extends PreGuard {
|
1022 | 1048 | /**
|
|
0 commit comments