Skip to content

Commit f7a3c40

Browse files
yoffCopilot
andcommitted
Python: test shared CFG node reachability
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 0aad85c commit f7a3c40

3 files changed

Lines changed: 91 additions & 0 deletions

File tree

‎python/ql/test/library-tests/ControlFlow/shared-cfg-reachability/StrictlyReachesTest.expected‎

Whitespace-only changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Inline-expectations test for node reachability in the shared CFG facade.
3+
*/
4+
5+
import python
6+
import semmle.python.controlflow.internal.Cfg as Cfg
7+
import utils.test.InlineExpectationsTest
8+
9+
private Cfg::NameNode namedNode(string id) { result.getId() = id }
10+
11+
private Call reachabilityCase(string category, string sourceId, string destinationId) {
12+
result.getFunc().(Name).getId() = "__reachability_case__" and
13+
category = result.getPositionalArg(0).(StringLiteral).getText() and
14+
sourceId = result.getPositionalArg(1).(StringLiteral).getText() and
15+
destinationId = result.getPositionalArg(2).(StringLiteral).getText()
16+
}
17+
18+
module StrictlyReachesTest implements TestSig {
19+
string getARelevantTag() { result = ["reaches", "not-reaches"] }
20+
21+
predicate hasActualResult(Location location, string element, string tag, string value) {
22+
exists(
23+
Call marker, string sourceId, string destinationId, Cfg::NameNode source,
24+
Cfg::NameNode destination
25+
|
26+
marker = reachabilityCase(value, sourceId, destinationId) and
27+
source = namedNode(sourceId) and
28+
source.isStore() and
29+
destination = namedNode(destinationId) and
30+
destination.isStore() and
31+
location = marker.getLocation() and
32+
element = marker.toString() and
33+
(
34+
tag = "reaches" and
35+
source.strictlyReaches(destination)
36+
or
37+
tag = "not-reaches" and
38+
not source.strictlyReaches(destination)
39+
)
40+
)
41+
}
42+
}
43+
44+
import MakeTest<StrictlyReachesTest>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
module_anchor = 0
2+
3+
4+
def linear():
5+
same_first = 1
6+
same_second = same_first + 1
7+
return same_second
8+
9+
10+
def branch(branch_condition):
11+
branch_entry = 0
12+
if branch_condition:
13+
branch_left = 1
14+
else:
15+
branch_right = 2
16+
branch_join = branch_entry
17+
return branch_join
18+
19+
20+
def loop(loop_condition):
21+
loop_seed = 0
22+
while loop_condition:
23+
loop_body = loop_seed
24+
loop_latch = loop_body
25+
after_loop = loop_seed
26+
return after_loop
27+
28+
29+
def first_scope():
30+
first_scope_start = 0
31+
first_scope_end = first_scope_start + 1
32+
return first_scope_end
33+
34+
35+
def second_scope():
36+
second_scope_node = 0
37+
return second_scope_node
38+
39+
40+
__reachability_case__("same-block-forward", "same_first", "same_second") # $ reaches=same-block-forward
41+
__reachability_case__("same-block-reverse", "same_second", "same_first") # $ not-reaches=same-block-reverse
42+
__reachability_case__("branch-left-to-join", "branch_left", "branch_join") # $ reaches=branch-left-to-join
43+
__reachability_case__("branch-right-to-join", "branch_right", "branch_join") # $ reaches=branch-right-to-join
44+
__reachability_case__("branch-siblings", "branch_left", "branch_right") # $ not-reaches=branch-siblings
45+
__reachability_case__("loop-backedge", "loop_latch", "loop_body") # $ reaches=loop-backedge
46+
__reachability_case__("loop-exit", "loop_body", "after_loop") # $ reaches=loop-exit
47+
__reachability_case__("distinct-scopes", "first_scope_start", "second_scope_node") # $ not-reaches=distinct-scopes

0 commit comments

Comments
 (0)