diff --git a/python/ql/test/experimental/dataflow/use-use-flow/read_explosion.py b/python/ql/test/experimental/dataflow/use-use-flow/read_explosion.py new file mode 100644 index 000000000000..ff08f91619dd --- /dev/null +++ b/python/ql/test/experimental/dataflow/use-use-flow/read_explosion.py @@ -0,0 +1,36 @@ +# This test file is inspired by +# `csharp/ql/test/library-tests/dataflow/local/UseUseExplosion.cs` +# but with `n=3` kept small, since we do have the explosion. + +cond = ... + +# global variables are slightly special, +# so we go into a function scope +def scope(): + x = 0 + + if(cond > 3): + if(cond > 2): + if(cond > 1): + pass + else: + use(x) + else: + use(x) + else: + use(x) + + if(cond > 3): + if(cond > 2): + if(cond > 1): + pass + else: + use(x) + else: + use(x) + else: + use(x) + + def use(v): + # this could just be `pass` but we do not want it optimized away. + y = v+2 \ No newline at end of file diff --git a/python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.expected b/python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.expected new file mode 100644 index 000000000000..92f5114fb8f4 --- /dev/null +++ b/python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.expected @@ -0,0 +1,24 @@ +implicit_use_count +| 0 | +implicit_use +source_use_count +| 6 | +source_use +| read_explosion.py:17:15:17:15 | ControlFlowNode for x | +| read_explosion.py:19:13:19:13 | ControlFlowNode for x | +| read_explosion.py:21:11:21:11 | ControlFlowNode for x | +| read_explosion.py:28:15:28:15 | ControlFlowNode for x | +| read_explosion.py:30:13:30:13 | ControlFlowNode for x | +| read_explosion.py:32:11:32:11 | ControlFlowNode for x | +use_use_edge_count +| 9 | +use_use_edge +| read_explosion.py:17:15:17:15 | ControlFlowNode for x | read_explosion.py:28:15:28:15 | ControlFlowNode for x | +| read_explosion.py:17:15:17:15 | ControlFlowNode for x | read_explosion.py:30:13:30:13 | ControlFlowNode for x | +| read_explosion.py:17:15:17:15 | ControlFlowNode for x | read_explosion.py:32:11:32:11 | ControlFlowNode for x | +| read_explosion.py:19:13:19:13 | ControlFlowNode for x | read_explosion.py:28:15:28:15 | ControlFlowNode for x | +| read_explosion.py:19:13:19:13 | ControlFlowNode for x | read_explosion.py:30:13:30:13 | ControlFlowNode for x | +| read_explosion.py:19:13:19:13 | ControlFlowNode for x | read_explosion.py:32:11:32:11 | ControlFlowNode for x | +| read_explosion.py:21:11:21:11 | ControlFlowNode for x | read_explosion.py:28:15:28:15 | ControlFlowNode for x | +| read_explosion.py:21:11:21:11 | ControlFlowNode for x | read_explosion.py:30:13:30:13 | ControlFlowNode for x | +| read_explosion.py:21:11:21:11 | ControlFlowNode for x | read_explosion.py:32:11:32:11 | ControlFlowNode for x | diff --git a/python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.ql b/python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.ql new file mode 100644 index 000000000000..ff18cc66f68b --- /dev/null +++ b/python/ql/test/experimental/dataflow/use-use-flow/use-use-counts.ql @@ -0,0 +1,37 @@ +import python +private import semmle.python.dataflow.new.internal.DataFlowPrivate + +query int implicit_use_count() { + exists(SsaSourceVariable x | x.getName() = "x" | result = count(x.getAnImplicitUse())) +} + +query ControlFlowNode implicit_use() { + exists(SsaSourceVariable x | x.getName() = "x" | result = x.getAnImplicitUse()) +} + +query int source_use_count() { + exists(SsaSourceVariable x | x.getName() = "x" | result = count(x.getASourceUse())) +} + +query ControlFlowNode source_use() { + exists(SsaSourceVariable x | x.getName() = "x" | result = x.getASourceUse()) +} + +query int use_use_edge_count() { + exists(SsaSourceVariable x | x.getName() = "x" | + result = + count(NameNode use1, NameNode use2 | + use1 = x.getAUse() and + use2 = x.getAUse() and + LocalFlow::useToNextUse(use1, use2) + ) + ) +} + +query predicate use_use_edge(NameNode use1, NameNode use2) { + exists(SsaSourceVariable x | x.getName() = "x" | + use1 = x.getAUse() and + use2 = x.getAUse() and + LocalFlow::useToNextUse(use1, use2) + ) +}