From e3bcd3bdd5789a27c052c09ea9081ab52d28e5e3 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 12 Mar 2025 21:08:05 +0000 Subject: [PATCH] Improve SSA tests for variables in closures --- .../semmle/go/dataflow/SSA/DefUse.expected | 16 ++++++--- .../go/dataflow/SSA/SsaDefinition.expected | 16 +++++++-- .../go/dataflow/SSA/SsaWithFields.expected | 26 ++++++++++---- .../semmle/go/dataflow/SSA/VarDefs.expected | 33 +++++++++++------- .../semmle/go/dataflow/SSA/VarUses.expected | 34 ++++++++++++++----- .../semmle/go/dataflow/SSA/main.go | 18 ++++++++++ 6 files changed, 107 insertions(+), 36 deletions(-) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/SSA/DefUse.expected b/go/ql/test/library-tests/semmle/go/dataflow/SSA/DefUse.expected index aad16b89ab6..9fe33491cfd 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/SSA/DefUse.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/SSA/DefUse.expected @@ -28,7 +28,15 @@ | main.go:84:15:84:15 | x | main.go:83:2:83:2 | definition of x | main.go:83:2:83:2 | x | | main.go:97:2:97:8 | wrapper | main.go:95:22:95:28 | definition of wrapper | main.go:95:22:95:28 | wrapper | | main.go:100:9:100:9 | x | main.go:97:2:99:3 | capture variable x | main.go:96:2:96:2 | x | -| main.go:117:2:117:2 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p | -| main.go:119:12:119:12 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p | -| main.go:119:17:119:17 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p | -| main.go:119:24:119:24 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p | +| main.go:105:2:105:8 | wrapper | main.go:103:20:103:26 | definition of wrapper | main.go:103:20:103:26 | wrapper | +| main.go:106:8:106:8 | x | main.go:105:16:108:2 | capture variable x | main.go:104:2:104:2 | x | +| main.go:107:7:107:7 | y | main.go:106:3:106:3 | definition of y | main.go:106:3:106:3 | y | +| main.go:109:9:109:9 | x | main.go:104:2:104:2 | definition of x | main.go:104:2:104:2 | x | +| main.go:114:2:114:8 | wrapper | main.go:112:29:112:35 | definition of wrapper | main.go:112:29:112:35 | wrapper | +| main.go:115:8:115:8 | x | main.go:114:16:117:2 | capture variable x | main.go:113:2:113:2 | x | +| main.go:116:7:116:7 | y | main.go:115:3:115:3 | definition of y | main.go:115:3:115:3 | y | +| main.go:118:9:118:9 | x | main.go:114:2:117:3 | capture variable x | main.go:113:2:113:2 | x | +| main.go:135:2:135:2 | p | main.go:135:2:135:2 | p = phi(def@130:3, def@132:3) | main.go:128:6:128:6 | p | +| main.go:137:12:137:12 | p | main.go:135:2:135:2 | p = phi(def@130:3, def@132:3) | main.go:128:6:128:6 | p | +| main.go:137:17:137:17 | p | main.go:135:2:135:2 | p = phi(def@130:3, def@132:3) | main.go:128:6:128:6 | p | +| main.go:137:24:137:24 | p | main.go:135:2:135:2 | p = phi(def@130:3, def@132:3) | main.go:128:6:128:6 | p | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/SSA/SsaDefinition.expected b/go/ql/test/library-tests/semmle/go/dataflow/SSA/SsaDefinition.expected index bd905b5c2a7..ddff7565818 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/SSA/SsaDefinition.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/SSA/SsaDefinition.expected @@ -36,6 +36,16 @@ | main.go:96:2:96:2 | definition of x | | main.go:97:2:99:3 | capture variable x | | main.go:98:3:98:3 | definition of x | -| main.go:112:3:112:3 | definition of p | -| main.go:114:3:114:3 | definition of p | -| main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | +| main.go:103:20:103:26 | definition of wrapper | +| main.go:104:2:104:2 | definition of x | +| main.go:105:16:108:2 | capture variable x | +| main.go:106:3:106:3 | definition of y | +| main.go:112:29:112:35 | definition of wrapper | +| main.go:113:2:113:2 | definition of x | +| main.go:114:2:117:3 | capture variable x | +| main.go:114:16:117:2 | capture variable x | +| main.go:115:3:115:3 | definition of y | +| main.go:116:3:116:3 | definition of x | +| main.go:130:3:130:3 | definition of p | +| main.go:132:3:132:3 | definition of p | +| main.go:135:2:135:2 | p = phi(def@130:3, def@132:3) | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/SSA/SsaWithFields.expected b/go/ql/test/library-tests/semmle/go/dataflow/SSA/SsaWithFields.expected index 245a82acc83..40b9195fc87 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/SSA/SsaWithFields.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/SSA/SsaWithFields.expected @@ -37,10 +37,22 @@ | main.go:96:2:96:2 | (def@96:2) | x | | main.go:97:2:99:3 | (capture@97:2) | x | | main.go:98:3:98:3 | (def@98:3) | x | -| main.go:112:3:112:3 | (def@112:3) | p | -| main.go:114:3:114:3 | (def@114:3) | p | -| main.go:117:2:117:2 | (phi@117:2) | p | -| main.go:117:2:117:2 | (phi@117:2).a | p.a | -| main.go:117:2:117:2 | (phi@117:2).b | p.b | -| main.go:117:2:117:2 | (phi@117:2).b.a | p.b.a | -| main.go:117:2:117:2 | (phi@117:2).c | p.c | +| main.go:103:20:103:26 | (def@103:20) | wrapper | +| main.go:103:20:103:26 | (def@103:20).s | wrapper.s | +| main.go:104:2:104:2 | (def@104:2) | x | +| main.go:105:16:108:2 | (capture@105:16) | x | +| main.go:106:3:106:3 | (def@106:3) | y | +| main.go:112:29:112:35 | (def@112:29) | wrapper | +| main.go:112:29:112:35 | (def@112:29).s | wrapper.s | +| main.go:113:2:113:2 | (def@113:2) | x | +| main.go:114:2:117:3 | (capture@114:2) | x | +| main.go:114:16:117:2 | (capture@114:16) | x | +| main.go:115:3:115:3 | (def@115:3) | y | +| main.go:116:3:116:3 | (def@116:3) | x | +| main.go:130:3:130:3 | (def@130:3) | p | +| main.go:132:3:132:3 | (def@132:3) | p | +| main.go:135:2:135:2 | (phi@135:2) | p | +| main.go:135:2:135:2 | (phi@135:2).a | p.a | +| main.go:135:2:135:2 | (phi@135:2).b | p.b | +| main.go:135:2:135:2 | (phi@135:2).b.a | p.b.a | +| main.go:135:2:135:2 | (phi@135:2).c | p.c | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/SSA/VarDefs.expected b/go/ql/test/library-tests/semmle/go/dataflow/SSA/VarDefs.expected index 2cadf9f87ab..6149ddfbb54 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/SSA/VarDefs.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/SSA/VarDefs.expected @@ -32,16 +32,23 @@ | main.go:95:22:95:28 | initialization of wrapper | main.go:95:22:95:28 | wrapper | main.go:95:22:95:28 | argument corresponding to wrapper | | main.go:96:2:96:2 | assignment to x | main.go:96:2:96:2 | x | main.go:96:7:96:7 | 0 | | main.go:98:3:98:3 | assignment to x | main.go:96:2:96:2 | x | main.go:98:7:98:7 | 1 | -| main.go:110:6:110:6 | assignment to p | main.go:110:6:110:6 | p | main.go:110:6:110:6 | zero value for p | -| main.go:112:3:112:3 | assignment to p | main.go:110:6:110:6 | p | main.go:112:7:112:24 | struct literal | -| main.go:112:9:112:9 | init of 2 | main.go:104:2:104:2 | a | main.go:112:9:112:9 | 2 | -| main.go:112:12:112:18 | init of struct literal | main.go:105:2:105:2 | b | main.go:112:12:112:18 | struct literal | -| main.go:112:14:112:14 | init of 1 | main.go:89:2:89:2 | a | main.go:112:14:112:14 | 1 | -| main.go:112:17:112:17 | init of 5 | main.go:90:2:90:2 | b | main.go:112:17:112:17 | 5 | -| main.go:112:21:112:23 | init of 'n' | main.go:106:2:106:2 | c | main.go:112:21:112:23 | 'n' | -| main.go:114:3:114:3 | assignment to p | main.go:110:6:110:6 | p | main.go:114:7:114:24 | struct literal | -| main.go:114:9:114:9 | init of 3 | main.go:104:2:104:2 | a | main.go:114:9:114:9 | 3 | -| main.go:114:12:114:18 | init of struct literal | main.go:105:2:105:2 | b | main.go:114:12:114:18 | struct literal | -| main.go:114:14:114:14 | init of 4 | main.go:89:2:89:2 | a | main.go:114:14:114:14 | 4 | -| main.go:114:17:114:17 | init of 5 | main.go:90:2:90:2 | b | main.go:114:17:114:17 | 5 | -| main.go:114:21:114:23 | init of '2' | main.go:106:2:106:2 | c | main.go:114:21:114:23 | '2' | +| main.go:103:20:103:26 | initialization of wrapper | main.go:103:20:103:26 | wrapper | main.go:103:20:103:26 | argument corresponding to wrapper | +| main.go:104:2:104:2 | assignment to x | main.go:104:2:104:2 | x | main.go:104:7:104:7 | 0 | +| main.go:106:3:106:3 | assignment to y | main.go:106:3:106:3 | y | main.go:106:8:106:8 | x | +| main.go:112:29:112:35 | initialization of wrapper | main.go:112:29:112:35 | wrapper | main.go:112:29:112:35 | argument corresponding to wrapper | +| main.go:113:2:113:2 | assignment to x | main.go:113:2:113:2 | x | main.go:113:7:113:7 | 0 | +| main.go:115:3:115:3 | assignment to y | main.go:115:3:115:3 | y | main.go:115:8:115:12 | ...+... | +| main.go:116:3:116:3 | assignment to x | main.go:113:2:113:2 | x | main.go:116:7:116:7 | y | +| main.go:128:6:128:6 | assignment to p | main.go:128:6:128:6 | p | main.go:128:6:128:6 | zero value for p | +| main.go:130:3:130:3 | assignment to p | main.go:128:6:128:6 | p | main.go:130:7:130:24 | struct literal | +| main.go:130:9:130:9 | init of 2 | main.go:122:2:122:2 | a | main.go:130:9:130:9 | 2 | +| main.go:130:12:130:18 | init of struct literal | main.go:123:2:123:2 | b | main.go:130:12:130:18 | struct literal | +| main.go:130:14:130:14 | init of 1 | main.go:89:2:89:2 | a | main.go:130:14:130:14 | 1 | +| main.go:130:17:130:17 | init of 5 | main.go:90:2:90:2 | b | main.go:130:17:130:17 | 5 | +| main.go:130:21:130:23 | init of 'n' | main.go:124:2:124:2 | c | main.go:130:21:130:23 | 'n' | +| main.go:132:3:132:3 | assignment to p | main.go:128:6:128:6 | p | main.go:132:7:132:24 | struct literal | +| main.go:132:9:132:9 | init of 3 | main.go:122:2:122:2 | a | main.go:132:9:132:9 | 3 | +| main.go:132:12:132:18 | init of struct literal | main.go:123:2:123:2 | b | main.go:132:12:132:18 | struct literal | +| main.go:132:14:132:14 | init of 4 | main.go:89:2:89:2 | a | main.go:132:14:132:14 | 4 | +| main.go:132:17:132:17 | init of 5 | main.go:90:2:90:2 | b | main.go:132:17:132:17 | 5 | +| main.go:132:21:132:23 | init of '2' | main.go:124:2:124:2 | c | main.go:132:21:132:23 | '2' | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/SSA/VarUses.expected b/go/ql/test/library-tests/semmle/go/dataflow/SSA/VarUses.expected index 332f859f051..2e6b3c855c3 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/SSA/VarUses.expected +++ b/go/ql/test/library-tests/semmle/go/dataflow/SSA/VarUses.expected @@ -28,13 +28,29 @@ | main.go:84:15:84:15 | x | main.go:83:2:83:2 | x | | main.go:97:2:97:8 | wrapper | main.go:95:22:95:28 | wrapper | | main.go:97:2:97:10 | selection of s | main.go:95:38:95:38 | s | +| main.go:97:2:97:10 | selection of s | main.go:103:36:103:36 | s | +| main.go:97:2:97:10 | selection of s | main.go:112:45:112:45 | s | | main.go:100:9:100:9 | x | main.go:96:2:96:2 | x | -| main.go:117:2:117:2 | p | main.go:110:6:110:6 | p | -| main.go:117:2:117:4 | selection of b | main.go:105:2:105:2 | b | -| main.go:119:12:119:12 | p | main.go:110:6:110:6 | p | -| main.go:119:12:119:14 | selection of a | main.go:104:2:104:2 | a | -| main.go:119:17:119:17 | p | main.go:110:6:110:6 | p | -| main.go:119:17:119:19 | selection of b | main.go:105:2:105:2 | b | -| main.go:119:17:119:21 | selection of a | main.go:89:2:89:2 | a | -| main.go:119:24:119:24 | p | main.go:110:6:110:6 | p | -| main.go:119:24:119:26 | selection of c | main.go:106:2:106:2 | c | +| main.go:105:2:105:8 | wrapper | main.go:103:20:103:26 | wrapper | +| main.go:105:2:105:10 | selection of s | main.go:95:38:95:38 | s | +| main.go:105:2:105:10 | selection of s | main.go:103:36:103:36 | s | +| main.go:105:2:105:10 | selection of s | main.go:112:45:112:45 | s | +| main.go:106:8:106:8 | x | main.go:104:2:104:2 | x | +| main.go:107:7:107:7 | y | main.go:106:3:106:3 | y | +| main.go:109:9:109:9 | x | main.go:104:2:104:2 | x | +| main.go:114:2:114:8 | wrapper | main.go:112:29:112:35 | wrapper | +| main.go:114:2:114:10 | selection of s | main.go:95:38:95:38 | s | +| main.go:114:2:114:10 | selection of s | main.go:103:36:103:36 | s | +| main.go:114:2:114:10 | selection of s | main.go:112:45:112:45 | s | +| main.go:115:8:115:8 | x | main.go:113:2:113:2 | x | +| main.go:116:7:116:7 | y | main.go:115:3:115:3 | y | +| main.go:118:9:118:9 | x | main.go:113:2:113:2 | x | +| main.go:135:2:135:2 | p | main.go:128:6:128:6 | p | +| main.go:135:2:135:4 | selection of b | main.go:123:2:123:2 | b | +| main.go:137:12:137:12 | p | main.go:128:6:128:6 | p | +| main.go:137:12:137:14 | selection of a | main.go:122:2:122:2 | a | +| main.go:137:17:137:17 | p | main.go:128:6:128:6 | p | +| main.go:137:17:137:19 | selection of b | main.go:123:2:123:2 | b | +| main.go:137:17:137:21 | selection of a | main.go:89:2:89:2 | a | +| main.go:137:24:137:24 | p | main.go:128:6:128:6 | p | +| main.go:137:24:137:26 | selection of c | main.go:124:2:124:2 | c | diff --git a/go/ql/test/library-tests/semmle/go/dataflow/SSA/main.go b/go/ql/test/library-tests/semmle/go/dataflow/SSA/main.go index cda85fdfc66..3967c14469f 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/SSA/main.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/SSA/main.go @@ -100,6 +100,24 @@ func updateInClosure(wrapper struct{ s }) int { return x } +func readInClosure(wrapper struct{ s }) int { + x := 0 + wrapper.s.foo(func() { + y := x + _ = y + }) + return x +} + +func readAndUpdateInClosure(wrapper struct{ s }) int { + x := 0 + wrapper.s.foo(func() { + y := x + 1 + x = y + }) + return x +} + type t struct { a int b s