|
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