diff --git a/Makefile b/Makefile
index 099cf6367ad..ab94b28dd92 100644
--- a/Makefile
+++ b/Makefile
@@ -95,7 +95,7 @@ ql/src/go.dbscheme.stats: ql/src/go.dbscheme
odasa collectStats --dbscheme $^ --db build/stats-project/revision/working/db-go --outputFile $@
test: all extractor build/testdb/check-upgrade-path
- codeql test run ql/test --search-path . --additional-packs .
+ codeql test run ql/test --search-path . --additional-packs ql
cd extractor; go test -mod=vendor ./... | grep -vF "[no test files]"
.PHONY: build/testdb/check-upgrade-path
diff --git a/ql/examples/.project b/ql/examples/.project
new file mode 100644
index 00000000000..45114efbc5a
--- /dev/null
+++ b/ql/examples/.project
@@ -0,0 +1,12 @@
+
+
+ go-examples
+
+
+
+
+
+
+ com.semmle.plugin.qdt.core.qlnature
+
+
diff --git a/ql/examples/.qlpath b/ql/examples/.qlpath
new file mode 100644
index 00000000000..ac27c76308e
--- /dev/null
+++ b/ql/examples/.qlpath
@@ -0,0 +1,10 @@
+
+
+
+ /go-queries
+
+ /go-queries/go.dbscheme
+
+ go
+
+
diff --git a/ql/examples/qlpack.yml b/ql/examples/qlpack.yml
new file mode 100644
index 00000000000..0fb500ee37f
--- /dev/null
+++ b/ql/examples/qlpack.yml
@@ -0,0 +1,3 @@
+name: codeql-go-examples
+version: 0.0.0
+libraryPathDependencies: codeql-go
diff --git a/ql/examples/queries.xml b/ql/examples/queries.xml
new file mode 100644
index 00000000000..6a456b21d09
--- /dev/null
+++ b/ql/examples/queries.xml
@@ -0,0 +1 @@
+
diff --git a/ql/examples/snippets/calltobuiltin.ql b/ql/examples/snippets/calltobuiltin.ql
new file mode 100644
index 00000000000..5ff20e563be
--- /dev/null
+++ b/ql/examples/snippets/calltobuiltin.ql
@@ -0,0 +1,15 @@
+/**
+ * @name Call to built-in function
+ * @description Finds calls to the built-in `len` function.
+ * @id go/examples/calltolen
+ * @tags call
+ * function
+ * len
+ * built-in
+ */
+
+import go
+
+from DataFlow::CallNode call
+where call = Builtin::len().getACall()
+select call
diff --git a/ql/examples/snippets/calltofunction.ql b/ql/examples/snippets/calltofunction.ql
new file mode 100644
index 00000000000..5bbe28b52a6
--- /dev/null
+++ b/ql/examples/snippets/calltofunction.ql
@@ -0,0 +1,16 @@
+/**
+ * @name Call to library function
+ * @description Finds calls to "fmt.Println".
+ * @id go/examples/calltoprintln
+ * @tags call
+ * function
+ * println
+ */
+
+import go
+
+from Function println, DataFlow::CallNode call
+where
+ println.hasQualifiedName("fmt", "Println") and
+ call = println.getACall()
+select call
diff --git a/ql/examples/snippets/calltomethod.ql b/ql/examples/snippets/calltomethod.ql
new file mode 100644
index 00000000000..eebfc707f2b
--- /dev/null
+++ b/ql/examples/snippets/calltomethod.ql
@@ -0,0 +1,18 @@
+/**
+ * @name Call to method
+ * @description Finds calls to the `Get` method of type `Header` from the `net/http` package.
+ * @id go/examples/calltoheaderget
+ * @tags call
+ * function
+ * net/http
+ * Header
+ * strings
+ */
+
+import go
+
+from Method get, DataFlow::CallNode call
+where
+ get.hasQualifiedName("net/http", "Header", "Get") and
+ call = get.getACall()
+select call
diff --git a/ql/examples/snippets/constant.ql b/ql/examples/snippets/constant.ql
new file mode 100644
index 00000000000..7f787b147a2
--- /dev/null
+++ b/ql/examples/snippets/constant.ql
@@ -0,0 +1,14 @@
+/**
+ * @name Compile-time constant
+ * @description Finds compile-time constants with value zero.
+ * @id go/examples/zeroconstant
+ * @tags expression
+ * numeric value
+ * constant
+ */
+
+import go
+
+from DataFlow::Node zero
+where zero.getNumericValue() = 0
+select zero
\ No newline at end of file
diff --git a/ql/examples/snippets/emptythen.ql b/ql/examples/snippets/emptythen.ql
new file mode 100644
index 00000000000..97a810e388c
--- /dev/null
+++ b/ql/examples/snippets/emptythen.ql
@@ -0,0 +1,18 @@
+/**
+ * @name If statements with empty then branch
+ * @description Finds 'if' statements where the 'then' branch is
+ * an empty block statement
+ * @id go/examples/emptythen
+ * @tags if
+ * then
+ * empty
+ * conditional
+ * branch
+ * statement
+ */
+
+import go
+
+from IfStmt i
+where i.getThen().getNumStmt() = 0
+select i
diff --git a/ql/examples/snippets/fieldread.ql b/ql/examples/snippets/fieldread.ql
new file mode 100644
index 00000000000..eec209db12d
--- /dev/null
+++ b/ql/examples/snippets/fieldread.ql
@@ -0,0 +1,16 @@
+/**
+ * @name Field read
+ * @description Finds code that reads `Request.Method`.
+ * @id go/examples/readofrequestmethod
+ * @tags field
+ * read
+ */
+
+import go
+
+from Type reqtp, Field reqm, DataFlow::Read read
+where
+ reqtp.hasQualifiedName("net/http", "Request") and
+ reqm = reqtp.getField("Method") and
+ read = reqm.getARead()
+select read
diff --git a/ql/examples/snippets/fieldwrite.ql b/ql/examples/snippets/fieldwrite.ql
new file mode 100644
index 00000000000..4b479208e20
--- /dev/null
+++ b/ql/examples/snippets/fieldwrite.ql
@@ -0,0 +1,16 @@
+/**
+ * @name Field write
+ * @description Finds assignments to field `Status` of type `Response` from package `net/http`.
+ * @id go/examples/responsestatus
+ * @tags net/http
+ * field write
+ */
+
+import go
+
+from Type response, Field status, DataFlow::Write write
+where
+ response.hasQualifiedName("net/http", "Response") and
+ status = response.getField("Status") and
+ write = status.getAWrite()
+select write, write.getRhs()
diff --git a/ql/examples/snippets/function.ql b/ql/examples/snippets/function.ql
new file mode 100644
index 00000000000..559dd34c234
--- /dev/null
+++ b/ql/examples/snippets/function.ql
@@ -0,0 +1,13 @@
+/**
+ * @name Function
+ * @description Finds functions called "main".
+ * @id go/examples/mainfunction
+ * @tags function
+ * main
+ */
+
+import go
+
+from Function main
+where main.getName() = "main"
+select main
diff --git a/ql/examples/snippets/nilcheck.ql b/ql/examples/snippets/nilcheck.ql
new file mode 100644
index 00000000000..cb82f14618e
--- /dev/null
+++ b/ql/examples/snippets/nilcheck.ql
@@ -0,0 +1,15 @@
+/**
+ * @name Comparison with nil
+ * @description Finds comparisons with nil.
+ * @id go/examples/nilcheck
+ * @tags comparison
+ * nil
+ */
+
+import go
+
+from DataFlow::EqualityTestNode eq, DataFlow::Node nd, DataFlow::Node nil
+where
+ nil = Builtin::nil().getARead() and
+ eq.eq(_, nd, nil)
+select eq
diff --git a/ql/examples/snippets/param.ql b/ql/examples/snippets/param.ql
new file mode 100644
index 00000000000..4340e018f9a
--- /dev/null
+++ b/ql/examples/snippets/param.ql
@@ -0,0 +1,12 @@
+/**
+ * @name Parameter
+ * @description Finds parameters of type "ResponseWriter" from package "net/http".
+ * @id go/examples/responseparam
+ * @tags parameter
+ */
+
+import go
+
+from Parameter req
+where req.getType().hasQualifiedName("net/http", "ResponseWriter")
+select req
diff --git a/ql/examples/snippets/pointertype.ql b/ql/examples/snippets/pointertype.ql
new file mode 100644
index 00000000000..b21f03f243e
--- /dev/null
+++ b/ql/examples/snippets/pointertype.ql
@@ -0,0 +1,15 @@
+/**
+ * @name Type
+ * @description Finds pointer type `*Request` from package `net/http`.
+ * @id go/examples/requestptrtype
+ * @tags net/http
+ * type
+ */
+
+import go
+
+from Type reqtp, PointerType reqptrtp
+where
+ reqtp.hasQualifiedName("net/http", "Request") and
+ reqptrtp.getBaseType() = reqtp
+select reqptrtp
diff --git a/ql/examples/snippets/receiver.ql b/ql/examples/snippets/receiver.ql
new file mode 100644
index 00000000000..511ef1314f5
--- /dev/null
+++ b/ql/examples/snippets/receiver.ql
@@ -0,0 +1,12 @@
+/**
+ * @name Receiver variable
+ * @description Finds receiver variables of pointer type.
+ * @id go/examples/pointerreceiver
+ * @tags receiver variable
+ */
+
+import go
+
+from ReceiverVariable recv
+where recv.getType() instanceof PointerType
+select recv
diff --git a/ql/examples/snippets/result.ql b/ql/examples/snippets/result.ql
new file mode 100644
index 00000000000..1241142bd4a
--- /dev/null
+++ b/ql/examples/snippets/result.ql
@@ -0,0 +1,12 @@
+/**
+ * @name Result variable
+ * @description Finds result variables of type "error".
+ * @id go/examples/errresult
+ * @tags result variable
+ */
+
+import go
+
+from ResultVariable err
+where err.getType() = Builtin::error().getType()
+select err
diff --git a/ql/examples/snippets/type.ql b/ql/examples/snippets/type.ql
new file mode 100644
index 00000000000..db20790dc0b
--- /dev/null
+++ b/ql/examples/snippets/type.ql
@@ -0,0 +1,13 @@
+/**
+ * @name Type
+ * @description Finds type `Request` from package `net/http`.
+ * @id go/examples/requesttype
+ * @tags net/http
+ * type
+ */
+
+import go
+
+from Type response
+where response.hasQualifiedName("net/http", "Request")
+select response
diff --git a/ql/examples/snippets/typeinfo.ql b/ql/examples/snippets/typeinfo.ql
new file mode 100644
index 00000000000..b5c22943466
--- /dev/null
+++ b/ql/examples/snippets/typeinfo.ql
@@ -0,0 +1,16 @@
+/**
+ * @name Type information
+ * @description Finds code elements of type `*Request` from package `net/http`.
+ * @id go/examples/requests
+ * @tags net/http
+ * types
+ */
+
+import go
+
+from Type reqtp, PointerType reqptrtp, DataFlow::Node req
+where
+ reqtp.hasQualifiedName("net/http", "Request") and
+ reqptrtp.getBaseType() = reqtp and
+ req.getType() = reqptrtp
+select req
diff --git a/ql/examples/snippets/updateinloop.ql b/ql/examples/snippets/updateinloop.ql
new file mode 100644
index 00000000000..f047f16dae2
--- /dev/null
+++ b/ql/examples/snippets/updateinloop.ql
@@ -0,0 +1,13 @@
+/**
+ * @name Increment statements in loops
+ * @description Finds increment statements that are nested in a loop
+ * @id go/examples/updateinloop
+ * @tags nesting
+ * increment
+ */
+
+import go
+
+from IncStmt s, LoopStmt l
+where s.getParent+() = l
+select s, l
diff --git a/ql/examples/snippets/variable.ql b/ql/examples/snippets/variable.ql
new file mode 100644
index 00000000000..c6587103368
--- /dev/null
+++ b/ql/examples/snippets/variable.ql
@@ -0,0 +1,13 @@
+/**
+ * @name Variable
+ * @description Finds variables called "err".
+ * @id go/examples/errvariable
+ * @tags variable
+ * err
+ */
+
+import go
+
+from Variable err
+where err.getName() = "err"
+select err
diff --git a/ql/examples/snippets/varread.ql b/ql/examples/snippets/varread.ql
new file mode 100644
index 00000000000..1e6719ef403
--- /dev/null
+++ b/ql/examples/snippets/varread.ql
@@ -0,0 +1,14 @@
+/**
+ * @name Variable read
+ * @description Finds code that reads a variable called `err`.
+ * @id go/examples/readoferr
+ * @tags variable read
+ */
+
+import go
+
+from Variable err, DataFlow::Read read
+where
+ err.getName() = "err" and
+ read = err.getARead()
+select read
diff --git a/ql/examples/snippets/varwrite.ql b/ql/examples/snippets/varwrite.ql
new file mode 100644
index 00000000000..72effcafbb3
--- /dev/null
+++ b/ql/examples/snippets/varwrite.ql
@@ -0,0 +1,14 @@
+/**
+ * @name Variable write
+ * @description Finds assignments to variables named "err".
+ * @id go/examples/errwrite
+ * @tags variable write
+ */
+
+import go
+
+from Variable err, DataFlow::Write write
+where
+ err.getName() = "err" and
+ write = err.getAWrite()
+select write, write.getRhs()
diff --git a/ql/examples/snippets/zerocheck.ql b/ql/examples/snippets/zerocheck.ql
new file mode 100644
index 00000000000..467dae7122d
--- /dev/null
+++ b/ql/examples/snippets/zerocheck.ql
@@ -0,0 +1,16 @@
+/**
+ * @name Comparison with zero
+ * @description Finds comparisons between an unsigned value and zero.
+ * @id go/examples/unsignedgez
+ * @tags comparison
+ * unsigned
+ */
+
+import go
+
+from DataFlow::RelationalComparisonNode cmp, DataFlow::Node unsigned, DataFlow::Node zero
+where
+ zero.getNumericValue() = 0 and
+ unsigned.getType().getUnderlyingType() instanceof UnsignedIntegerType and
+ cmp.leq(_, zero, unsigned, 0)
+select cmp, unsigned
diff --git a/ql/test/example-tests/snippets/calltobuiltin.expected b/ql/test/example-tests/snippets/calltobuiltin.expected
new file mode 100644
index 00000000000..67f3307c74c
--- /dev/null
+++ b/ql/test/example-tests/snippets/calltobuiltin.expected
@@ -0,0 +1 @@
+| main.go:15:41:15:52 | call to len |
diff --git a/ql/test/example-tests/snippets/calltobuiltin.qlref b/ql/test/example-tests/snippets/calltobuiltin.qlref
new file mode 100644
index 00000000000..529ae381fad
--- /dev/null
+++ b/ql/test/example-tests/snippets/calltobuiltin.qlref
@@ -0,0 +1 @@
+snippets/calltobuiltin.ql
diff --git a/ql/test/example-tests/snippets/calltofunction.expected b/ql/test/example-tests/snippets/calltofunction.expected
new file mode 100644
index 00000000000..04e88f8febf
--- /dev/null
+++ b/ql/test/example-tests/snippets/calltofunction.expected
@@ -0,0 +1 @@
+| main.go:14:2:14:29 | call to Println |
diff --git a/ql/test/example-tests/snippets/calltofunction.qlref b/ql/test/example-tests/snippets/calltofunction.qlref
new file mode 100644
index 00000000000..19670ecd47b
--- /dev/null
+++ b/ql/test/example-tests/snippets/calltofunction.qlref
@@ -0,0 +1 @@
+snippets/calltofunction.ql
diff --git a/ql/test/example-tests/snippets/calltomethod.expected b/ql/test/example-tests/snippets/calltomethod.expected
new file mode 100644
index 00000000000..ad50d0dba83
--- /dev/null
+++ b/ql/test/example-tests/snippets/calltomethod.expected
@@ -0,0 +1 @@
+| main.go:19:2:19:22 | call to Get |
diff --git a/ql/test/example-tests/snippets/calltomethod.qlref b/ql/test/example-tests/snippets/calltomethod.qlref
new file mode 100644
index 00000000000..70bcbb35c19
--- /dev/null
+++ b/ql/test/example-tests/snippets/calltomethod.qlref
@@ -0,0 +1 @@
+snippets/calltomethod.ql
diff --git a/ql/test/example-tests/snippets/constant.expected b/ql/test/example-tests/snippets/constant.expected
new file mode 100644
index 00000000000..ecad2c8f8e0
--- /dev/null
+++ b/ql/test/example-tests/snippets/constant.expected
@@ -0,0 +1,4 @@
+| main.go:11:18:11:26 | ...-... |
+| main.go:15:56:15:59 | zero |
+| main.go:35:9:35:9 | 0 |
+| main.go:46:11:46:11 | 0 |
diff --git a/ql/test/example-tests/snippets/constant.qlref b/ql/test/example-tests/snippets/constant.qlref
new file mode 100644
index 00000000000..717ffb95e7f
--- /dev/null
+++ b/ql/test/example-tests/snippets/constant.qlref
@@ -0,0 +1 @@
+snippets/constant.ql
diff --git a/ql/test/example-tests/snippets/emptythen.expected b/ql/test/example-tests/snippets/emptythen.expected
new file mode 100644
index 00000000000..e32bcfa6893
--- /dev/null
+++ b/ql/test/example-tests/snippets/emptythen.expected
@@ -0,0 +1 @@
+| main.go:30:2:31:2 | if statement |
diff --git a/ql/test/example-tests/snippets/emptythen.qlref b/ql/test/example-tests/snippets/emptythen.qlref
new file mode 100644
index 00000000000..355b1bc6308
--- /dev/null
+++ b/ql/test/example-tests/snippets/emptythen.qlref
@@ -0,0 +1 @@
+snippets/emptythen.ql
diff --git a/ql/test/example-tests/snippets/fieldread.expected b/ql/test/example-tests/snippets/fieldread.expected
new file mode 100644
index 00000000000..ccb1955a538
--- /dev/null
+++ b/ql/test/example-tests/snippets/fieldread.expected
@@ -0,0 +1 @@
+| main.go:20:5:20:14 | selection of Method |
diff --git a/ql/test/example-tests/snippets/fieldread.qlref b/ql/test/example-tests/snippets/fieldread.qlref
new file mode 100644
index 00000000000..24aedbf48f1
--- /dev/null
+++ b/ql/test/example-tests/snippets/fieldread.qlref
@@ -0,0 +1 @@
+snippets/fieldread.ql
diff --git a/ql/test/example-tests/snippets/fieldwrite.expected b/ql/test/example-tests/snippets/fieldwrite.expected
new file mode 100644
index 00000000000..26c7f7b90f8
--- /dev/null
+++ b/ql/test/example-tests/snippets/fieldwrite.expected
@@ -0,0 +1 @@
+| main.go:23:3:23:13 | assignment to field Status | main.go:23:17:23:21 | "200" |
diff --git a/ql/test/example-tests/snippets/fieldwrite.qlref b/ql/test/example-tests/snippets/fieldwrite.qlref
new file mode 100644
index 00000000000..66f9a47f7eb
--- /dev/null
+++ b/ql/test/example-tests/snippets/fieldwrite.qlref
@@ -0,0 +1 @@
+snippets/fieldwrite.ql
diff --git a/ql/test/example-tests/snippets/function.expected b/ql/test/example-tests/snippets/function.expected
new file mode 100644
index 00000000000..1716095c187
--- /dev/null
+++ b/ql/test/example-tests/snippets/function.expected
@@ -0,0 +1,2 @@
+| file://:0:0:0:0 | main |
+| main.go:13:6:13:9 | main |
diff --git a/ql/test/example-tests/snippets/function.qlref b/ql/test/example-tests/snippets/function.qlref
new file mode 100644
index 00000000000..ca05804be09
--- /dev/null
+++ b/ql/test/example-tests/snippets/function.qlref
@@ -0,0 +1 @@
+snippets/function.ql
diff --git a/ql/test/example-tests/snippets/main.go b/ql/test/example-tests/snippets/main.go
new file mode 100644
index 00000000000..9b36730787e
--- /dev/null
+++ b/ql/test/example-tests/snippets/main.go
@@ -0,0 +1,49 @@
+package main
+
+import (
+ "errors"
+ "fmt"
+ "net/http"
+ "os"
+)
+
+const one int = 1
+const zero int = one - one
+
+func main() {
+ fmt.Println("Hello, world!")
+ fmt.Printf("Ignoring %d arguments.\n", len(os.Args)-1+zero)
+}
+
+func test1(req *http.Request, hdr *http.Header, resp *http.Response, w http.ResponseWriter) (e error) {
+ hdr.Get("X-MyHeader")
+ if req.Method != "GET" {
+ return errors.New("nope")
+ } else {
+ resp.Status = "200"
+ }
+ return nil
+}
+
+func test2(w http.ResponseWriter) {
+ err := test1(nil, nil, nil, w)
+ if err == nil {
+ }
+}
+
+func test3(n uint) string {
+ if n < 0 {
+ return "?"
+ }
+ return ""
+}
+
+type counter struct {
+ val int
+}
+
+func (c *counter) bump(n int) {
+ for i := 0; i < n; i++ {
+ c.val++
+ }
+}
diff --git a/ql/test/example-tests/snippets/nilcheck.expected b/ql/test/example-tests/snippets/nilcheck.expected
new file mode 100644
index 00000000000..09d14c265b9
--- /dev/null
+++ b/ql/test/example-tests/snippets/nilcheck.expected
@@ -0,0 +1 @@
+| main.go:30:5:30:14 | ...==... |
diff --git a/ql/test/example-tests/snippets/nilcheck.qlref b/ql/test/example-tests/snippets/nilcheck.qlref
new file mode 100644
index 00000000000..b4b6af19c03
--- /dev/null
+++ b/ql/test/example-tests/snippets/nilcheck.qlref
@@ -0,0 +1 @@
+snippets/nilcheck.ql
diff --git a/ql/test/example-tests/snippets/param.expected b/ql/test/example-tests/snippets/param.expected
new file mode 100644
index 00000000000..47a7e09967a
--- /dev/null
+++ b/ql/test/example-tests/snippets/param.expected
@@ -0,0 +1,2 @@
+| main.go:18:70:18:70 | w |
+| main.go:28:12:28:12 | w |
diff --git a/ql/test/example-tests/snippets/param.qlref b/ql/test/example-tests/snippets/param.qlref
new file mode 100644
index 00000000000..b6e1f441fb2
--- /dev/null
+++ b/ql/test/example-tests/snippets/param.qlref
@@ -0,0 +1 @@
+snippets/param.ql
diff --git a/ql/test/example-tests/snippets/pointertype.expected b/ql/test/example-tests/snippets/pointertype.expected
new file mode 100644
index 00000000000..b6dc6edcbdb
--- /dev/null
+++ b/ql/test/example-tests/snippets/pointertype.expected
@@ -0,0 +1 @@
+| pointer type |
diff --git a/ql/test/example-tests/snippets/pointertype.qlref b/ql/test/example-tests/snippets/pointertype.qlref
new file mode 100644
index 00000000000..3c7b1c283dd
--- /dev/null
+++ b/ql/test/example-tests/snippets/pointertype.qlref
@@ -0,0 +1 @@
+snippets/pointertype.ql
diff --git a/ql/test/example-tests/snippets/receiver.expected b/ql/test/example-tests/snippets/receiver.expected
new file mode 100644
index 00000000000..51f13eed73c
--- /dev/null
+++ b/ql/test/example-tests/snippets/receiver.expected
@@ -0,0 +1 @@
+| main.go:45:7:45:7 | c |
diff --git a/ql/test/example-tests/snippets/receiver.qlref b/ql/test/example-tests/snippets/receiver.qlref
new file mode 100644
index 00000000000..e1cdf7414b2
--- /dev/null
+++ b/ql/test/example-tests/snippets/receiver.qlref
@@ -0,0 +1 @@
+snippets/receiver.ql
diff --git a/ql/test/example-tests/snippets/result.expected b/ql/test/example-tests/snippets/result.expected
new file mode 100644
index 00000000000..20d7c8a4fa3
--- /dev/null
+++ b/ql/test/example-tests/snippets/result.expected
@@ -0,0 +1 @@
+| main.go:18:94:18:94 | e |
diff --git a/ql/test/example-tests/snippets/result.qlref b/ql/test/example-tests/snippets/result.qlref
new file mode 100644
index 00000000000..3c254f63106
--- /dev/null
+++ b/ql/test/example-tests/snippets/result.qlref
@@ -0,0 +1 @@
+snippets/result.ql
diff --git a/ql/test/example-tests/snippets/type.expected b/ql/test/example-tests/snippets/type.expected
new file mode 100644
index 00000000000..6c24f73f3a8
--- /dev/null
+++ b/ql/test/example-tests/snippets/type.expected
@@ -0,0 +1 @@
+| Request |
diff --git a/ql/test/example-tests/snippets/type.qlref b/ql/test/example-tests/snippets/type.qlref
new file mode 100644
index 00000000000..234a6a9720d
--- /dev/null
+++ b/ql/test/example-tests/snippets/type.qlref
@@ -0,0 +1 @@
+snippets/type.ql
diff --git a/ql/test/example-tests/snippets/typeinfo.expected b/ql/test/example-tests/snippets/typeinfo.expected
new file mode 100644
index 00000000000..c78f79a49c3
--- /dev/null
+++ b/ql/test/example-tests/snippets/typeinfo.expected
@@ -0,0 +1,3 @@
+| main.go:18:12:18:14 | argument corresponding to req |
+| main.go:18:12:18:14 | definition of req |
+| main.go:20:5:20:7 | req |
diff --git a/ql/test/example-tests/snippets/typeinfo.qlref b/ql/test/example-tests/snippets/typeinfo.qlref
new file mode 100644
index 00000000000..1b4e2368d9d
--- /dev/null
+++ b/ql/test/example-tests/snippets/typeinfo.qlref
@@ -0,0 +1 @@
+snippets/typeinfo.ql
diff --git a/ql/test/example-tests/snippets/updateinloop.expected b/ql/test/example-tests/snippets/updateinloop.expected
new file mode 100644
index 00000000000..b4ec5e7b4ea
--- /dev/null
+++ b/ql/test/example-tests/snippets/updateinloop.expected
@@ -0,0 +1,2 @@
+| main.go:46:21:46:23 | increment statement | main.go:46:2:48:2 | for statement |
+| main.go:47:3:47:9 | increment statement | main.go:46:2:48:2 | for statement |
diff --git a/ql/test/example-tests/snippets/updateinloop.qlref b/ql/test/example-tests/snippets/updateinloop.qlref
new file mode 100644
index 00000000000..e436d667642
--- /dev/null
+++ b/ql/test/example-tests/snippets/updateinloop.qlref
@@ -0,0 +1 @@
+snippets/updateinloop.ql
diff --git a/ql/test/example-tests/snippets/variable.expected b/ql/test/example-tests/snippets/variable.expected
new file mode 100644
index 00000000000..8f51749125b
--- /dev/null
+++ b/ql/test/example-tests/snippets/variable.expected
@@ -0,0 +1,47 @@
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| file://:0:0:0:0 | err |
+| main.go:29:2:29:4 | err |
diff --git a/ql/test/example-tests/snippets/variable.qlref b/ql/test/example-tests/snippets/variable.qlref
new file mode 100644
index 00000000000..2d6a8919849
--- /dev/null
+++ b/ql/test/example-tests/snippets/variable.qlref
@@ -0,0 +1 @@
+snippets/variable.ql
diff --git a/ql/test/example-tests/snippets/varread.expected b/ql/test/example-tests/snippets/varread.expected
new file mode 100644
index 00000000000..5baec6bee93
--- /dev/null
+++ b/ql/test/example-tests/snippets/varread.expected
@@ -0,0 +1 @@
+| main.go:30:5:30:7 | err |
diff --git a/ql/test/example-tests/snippets/varread.qlref b/ql/test/example-tests/snippets/varread.qlref
new file mode 100644
index 00000000000..1d9ae358b3d
--- /dev/null
+++ b/ql/test/example-tests/snippets/varread.qlref
@@ -0,0 +1 @@
+snippets/varread.ql
diff --git a/ql/test/example-tests/snippets/varwrite.expected b/ql/test/example-tests/snippets/varwrite.expected
new file mode 100644
index 00000000000..b2c06e76a27
--- /dev/null
+++ b/ql/test/example-tests/snippets/varwrite.expected
@@ -0,0 +1 @@
+| main.go:29:2:29:4 | assignment to err | main.go:29:9:29:31 | call to test1 |
diff --git a/ql/test/example-tests/snippets/varwrite.qlref b/ql/test/example-tests/snippets/varwrite.qlref
new file mode 100644
index 00000000000..f5d74f3532b
--- /dev/null
+++ b/ql/test/example-tests/snippets/varwrite.qlref
@@ -0,0 +1 @@
+snippets/varwrite.ql
diff --git a/ql/test/example-tests/snippets/zerocheck.expected b/ql/test/example-tests/snippets/zerocheck.expected
new file mode 100644
index 00000000000..5476adc47b4
--- /dev/null
+++ b/ql/test/example-tests/snippets/zerocheck.expected
@@ -0,0 +1 @@
+| main.go:35:5:35:9 | ...<... | main.go:35:5:35:5 | n |
diff --git a/ql/test/example-tests/snippets/zerocheck.qlref b/ql/test/example-tests/snippets/zerocheck.qlref
new file mode 100644
index 00000000000..36356991038
--- /dev/null
+++ b/ql/test/example-tests/snippets/zerocheck.qlref
@@ -0,0 +1 @@
+snippets/zerocheck.ql
diff --git a/ql/test/qlpack.yml b/ql/test/qlpack.yml
index 5b45041ba8b..8e6d3fd57eb 100644
--- a/ql/test/qlpack.yml
+++ b/ql/test/qlpack.yml
@@ -1,3 +1,5 @@
name: codeql-go-tests
version: 0.0.0
-libraryPathDependencies: codeql-go
+libraryPathDependencies:
+ - codeql-go
+ - codeql-go-examples