mirror of
https://github.com/github/codeql.git
synced 2026-01-29 22:32:58 +01:00
Merge pull request #61 from max-schaefer/better-method-sets
Reformulate `Method.hasQualifiedName` in terms of method sets
This commit is contained in:
@@ -427,21 +427,40 @@ class Method extends Function {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this method has name `m` and its receiver base type has qualified name `tp`.
|
||||
*/
|
||||
override predicate hasQualifiedName(string tp, string m) {
|
||||
tp = getReceiverBaseType().getQualifiedName() and
|
||||
m = getName()
|
||||
/** Holds if this method has name `m` and belongs to the method set of type `tp` or `*tp`. */
|
||||
private predicate isIn(NamedType tp, string m) {
|
||||
this = tp.getMethod(m) or
|
||||
this = tp.getPointerType().getMethod(m)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this method has name `m` and its receiver base type is declared in package `pkg` and
|
||||
* has name `tp`.
|
||||
* Holds if this method has name `m` and belongs to the method set of a type `T` or `*T` where
|
||||
* `T` has qualified name `tp`.
|
||||
*
|
||||
* Note that `meth.hasQualifiedName(tp, m)` is almost, but not quite, equivalent to
|
||||
* `exists(Type t | tp = t.getQualifiedName() and meth = t.getMethod(m))`: the latter
|
||||
* distinguishes between the method sets of `T` and `*T`, while the former does not.
|
||||
*/
|
||||
override predicate hasQualifiedName(string tp, string m) {
|
||||
exists(NamedType t |
|
||||
this.isIn(t, m) and
|
||||
tp = t.getQualifiedName()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this method has name `m` and belongs to the method set of a type `T` or `*T` where
|
||||
* `T` is declared in package `pkg` and has name `tp`.
|
||||
*
|
||||
* Note that `meth.hasQualifiedName(pkg, tp, m)` is almost, but not quite, equivalent to
|
||||
* `exists(Type t | t.hasQualifiedName(pkg, tp) and meth = t.getMethod(m))`: the latter
|
||||
* distinguishes between the method sets of `T` and `*T`, while the former does not.
|
||||
*/
|
||||
predicate hasQualifiedName(string pkg, string tp, string m) {
|
||||
getReceiverBaseType().hasQualifiedName(pkg, tp) and
|
||||
m = getName()
|
||||
exists(NamedType t |
|
||||
this.isIn(t, m) and
|
||||
t.hasQualifiedName(pkg, tp)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,6 +40,9 @@ class Type extends @type {
|
||||
|
||||
/**
|
||||
* Gets the method `m` belonging to the method set of this type, if any.
|
||||
*
|
||||
* Note that this predicate never has a result for struct types. Methods are associated
|
||||
* with the corresponding named type instead.
|
||||
*/
|
||||
Method getMethod(string m) {
|
||||
result.getReceiverType() = this and
|
||||
@@ -441,11 +444,29 @@ class PointerType extends @pointertype, CompositeType {
|
||||
override Package getPackage() { result = this.getBaseType().getPackage() }
|
||||
|
||||
override Method getMethod(string m) {
|
||||
// https://golang.org/ref/spec#Method_sets: "the method set of a pointer type *T is
|
||||
// the set of all methods declared with receiver *T or T"
|
||||
result = CompositeType.super.getMethod(m)
|
||||
or
|
||||
// https://golang.org/ref/spec#Method_sets: "the method set of a pointer type *T is
|
||||
// the set of all methods declared with receiver *T or T"
|
||||
result = getBaseType().getMethod(m)
|
||||
or
|
||||
// promoted methods from embedded types
|
||||
exists(StructType s, Type embedded |
|
||||
s = getBaseType().(NamedType).getUnderlyingType() and
|
||||
s.hasOwnField(_, _, embedded, true) and
|
||||
// ensure that `m` can be promoted
|
||||
not s.hasOwnField(_, m, _, _) and
|
||||
not exists(Method m2 | m2.getReceiverBaseType() = getBaseType() and m2.getName() = m)
|
||||
|
|
||||
result = embedded.getMethod(m)
|
||||
or
|
||||
// If S contains an embedded field T, the method set of *S includes promoted methods with receiver T or T*
|
||||
not embedded instanceof PointerType and
|
||||
result = embedded.getPointerType().getMethod(m)
|
||||
or
|
||||
// If S contains an embedded field *T, the method set of *S includes promoted methods with receiver T or *T
|
||||
result = embedded.(PointerType).getBaseType().getMethod(m)
|
||||
)
|
||||
}
|
||||
|
||||
override string pp() { result = "* " + getBaseType().pp() }
|
||||
@@ -566,12 +587,6 @@ class SendRecvChanType extends @sendrcvchantype, ChanType {
|
||||
|
||||
/** A named type. */
|
||||
class NamedType extends @namedtype, CompositeType {
|
||||
/** Gets a method with name `m` defined on this type. */
|
||||
MethodDecl getMethodDecl(string m) {
|
||||
result.getName() = m and
|
||||
this = result.getReceiverBaseType()
|
||||
}
|
||||
|
||||
/** Gets the type which this type is defined to be. */
|
||||
Type getBaseType() { underlying_type(this, result) }
|
||||
|
||||
@@ -580,6 +595,21 @@ class NamedType extends @namedtype, CompositeType {
|
||||
or
|
||||
methodhosts(result, this) and
|
||||
result.getName() = m
|
||||
or
|
||||
// handle promoted methods
|
||||
exists(StructType s, Type embedded |
|
||||
s = getBaseType() and
|
||||
s.hasOwnField(_, _, embedded, true) and
|
||||
// ensure `m` can be promoted
|
||||
not s.hasOwnField(_, m, _, _) and
|
||||
not exists(Method m2 | m2.getReceiverType() = this and m2.getName() = m)
|
||||
|
|
||||
// If S contains an embedded field T, the method set of S includes promoted methods with receiver T
|
||||
result = embedded.getMethod(m)
|
||||
or
|
||||
// If S contains an embedded field *T, the method set of S includes promoted methods with receiver T or *T
|
||||
result = embedded.(PointerType).getBaseType().getMethod(m)
|
||||
)
|
||||
}
|
||||
|
||||
override Type getUnderlyingType() { result = getBaseType().getUnderlyingType() }
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
| pkg1/embedding.go:19:23:19:26 | base | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
| pkg1/embedding.go:22:27:22:30 | base | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
| pkg1/embedding.go:25:24:25:31 | embedder | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
| pkg1/embedding.go:28:24:28:31 | embedder | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
| pkg1/embedding.go:36:2:36:5 | base | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
| pkg1/embedding.go:37:2:37:2 | f | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
| pkg1/tst.go:4:2:4:2 | f | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
| pkg1/tst.go:5:2:5:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
| pkg1/tst.go:6:2:6:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder | base |
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder2 | base |
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder3 | base |
|
||||
| pkg1/embedding.go:22:27:22:30 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.ptrembedder | base |
|
||||
| pkg1/embedding.go:25:24:25:31 | embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder2 | embedder |
|
||||
| pkg1/embedding.go:25:24:25:31 | embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder3 | embedder |
|
||||
| pkg1/embedding.go:28:24:28:31 | embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder2 | embedder |
|
||||
| pkg1/embedding.go:28:24:28:31 | embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder3 | embedder |
|
||||
| pkg1/embedding.go:36:2:36:5 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder4 | base |
|
||||
| pkg1/embedding.go:37:2:37:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder4 | f |
|
||||
| pkg1/tst.go:4:2:4:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | f |
|
||||
| pkg1/tst.go:5:2:5:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Foo |
|
||||
| pkg1/tst.go:6:2:6:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Bar |
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | base |
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | base |
|
||||
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | base |
|
||||
| pkg1/embedding.go:22:27:22:30 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | ptrembedder | base |
|
||||
| pkg1/embedding.go:25:24:25:31 | embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | embedder |
|
||||
| pkg1/embedding.go:25:24:25:31 | embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | embedder |
|
||||
| pkg1/embedding.go:28:24:28:31 | embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | embedder |
|
||||
| pkg1/embedding.go:28:24:28:31 | embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | embedder |
|
||||
| pkg1/embedding.go:36:2:36:5 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder4 | base |
|
||||
| pkg1/embedding.go:37:2:37:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder4 | f |
|
||||
| pkg1/tst.go:4:2:4:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | f |
|
||||
| pkg1/tst.go:5:2:5:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Foo |
|
||||
| pkg1/tst.go:6:2:6:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Bar |
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
| * Foo | 1 |
|
||||
| * base | 2 |
|
||||
| * embedder | 2 |
|
||||
| * embedder2 | 2 |
|
||||
| * embedder3 | 2 |
|
||||
| * embedder4 | 1 |
|
||||
| * ptrembedder | 2 |
|
||||
| A | 1 |
|
||||
| A2 | 1 |
|
||||
| AC | 3 |
|
||||
@@ -7,3 +13,11 @@
|
||||
| B | 2 |
|
||||
| C | 2 |
|
||||
| Foo | 1 |
|
||||
| T | 1 |
|
||||
| T3 | 1 |
|
||||
| T4 | 1 |
|
||||
| base | 1 |
|
||||
| embedder | 1 |
|
||||
| embedder2 | 1 |
|
||||
| embedder3 | 1 |
|
||||
| ptrembedder | 2 |
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
| Foo | half | pkg1/tst.go:33:1:35:1 | function declaration |
|
||||
@@ -1,4 +0,0 @@
|
||||
import go
|
||||
|
||||
from NamedType t, string m
|
||||
select t, m, t.getMethodDecl(m)
|
||||
@@ -13,3 +13,8 @@
|
||||
| T | half | func() Foo |
|
||||
| T3 | half | func() Foo |
|
||||
| T4 | half | func() Foo |
|
||||
| embedder | f | func() int |
|
||||
| embedder2 | f | func() int |
|
||||
| embedder3 | f | func() int |
|
||||
| ptrembedder | f | func() int |
|
||||
| ptrembedder | g | func() int |
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | base | f |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | f |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | f |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | ptrembedder | f |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | base | g |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | g |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | g |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | g |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder4 | g |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | ptrembedder | g |
|
||||
| pkg1/embedding.go:30:18:30:18 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | f |
|
||||
| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | A | m |
|
||||
| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AC | m |
|
||||
| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AEmbedded | m |
|
||||
| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AExtended | m |
|
||||
| pkg1/interfaces.go:8:2:8:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | B | m |
|
||||
| pkg1/interfaces.go:9:2:9:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | B | n |
|
||||
| pkg1/interfaces.go:13:2:13:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AC | n |
|
||||
| pkg1/interfaces.go:13:2:13:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | C | n |
|
||||
| pkg1/interfaces.go:14:2:14:2 | o | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AC | o |
|
||||
| pkg1/interfaces.go:14:2:14:2 | o | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | C | o |
|
||||
| pkg1/interfaces.go:28:2:28:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AExtended | n |
|
||||
| pkg1/interfaces.go:32:2:32:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | A2 | m |
|
||||
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | half |
|
||||
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | half |
|
||||
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | half |
|
||||
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | half |
|
||||
@@ -0,0 +1,5 @@
|
||||
import go
|
||||
|
||||
from Method meth, string pkg, string tp, string m
|
||||
where meth.hasQualifiedName(pkg, tp, m)
|
||||
select meth.getDeclaration(), pkg, tp, m
|
||||
@@ -0,0 +1,27 @@
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | base | f |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | f |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | f |
|
||||
| pkg1/embedding.go:10:13:10:13 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | ptrembedder | f |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | base | g |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | g |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | g |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | g |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder4 | g |
|
||||
| pkg1/embedding.go:14:14:14:14 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | ptrembedder | g |
|
||||
| pkg1/embedding.go:30:18:30:18 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | f |
|
||||
| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | A | m |
|
||||
| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AC | m |
|
||||
| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AEmbedded | m |
|
||||
| pkg1/interfaces.go:4:2:4:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AExtended | m |
|
||||
| pkg1/interfaces.go:8:2:8:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | B | m |
|
||||
| pkg1/interfaces.go:9:2:9:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | B | n |
|
||||
| pkg1/interfaces.go:13:2:13:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AC | n |
|
||||
| pkg1/interfaces.go:13:2:13:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | C | n |
|
||||
| pkg1/interfaces.go:14:2:14:2 | o | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AC | o |
|
||||
| pkg1/interfaces.go:14:2:14:2 | o | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | C | o |
|
||||
| pkg1/interfaces.go:28:2:28:2 | n | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | AExtended | n |
|
||||
| pkg1/interfaces.go:32:2:32:2 | m | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | A2 | m |
|
||||
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | half |
|
||||
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | half |
|
||||
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | half |
|
||||
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | half |
|
||||
@@ -0,0 +1,5 @@
|
||||
import go
|
||||
|
||||
from Method meth, string pkg, string tp, string m
|
||||
where meth.hasQualifiedName(pkg, tp, m)
|
||||
select meth.getDeclaration(), pkg, tp, m
|
||||
@@ -1,4 +1,15 @@
|
||||
| * Foo | half | pkg1/tst.go:33:16:33:19 | half |
|
||||
| * base | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||
| * base | g | pkg1/embedding.go:14:14:14:14 | g |
|
||||
| * embedder | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||
| * embedder | g | pkg1/embedding.go:14:14:14:14 | g |
|
||||
| * embedder2 | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||
| * embedder2 | g | pkg1/embedding.go:14:14:14:14 | g |
|
||||
| * embedder3 | f | pkg1/embedding.go:30:18:30:18 | f |
|
||||
| * embedder3 | g | pkg1/embedding.go:14:14:14:14 | g |
|
||||
| * embedder4 | g | pkg1/embedding.go:14:14:14:14 | g |
|
||||
| * ptrembedder | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||
| * ptrembedder | g | pkg1/embedding.go:14:14:14:14 | g |
|
||||
| A | m | pkg1/interfaces.go:4:2:4:2 | m |
|
||||
| A2 | m | pkg1/interfaces.go:32:2:32:2 | m |
|
||||
| AC | m | pkg1/interfaces.go:4:2:4:2 | m |
|
||||
@@ -12,3 +23,12 @@
|
||||
| C | n | pkg1/interfaces.go:13:2:13:2 | n |
|
||||
| C | o | pkg1/interfaces.go:14:2:14:2 | o |
|
||||
| Foo | half | pkg1/tst.go:33:16:33:19 | half |
|
||||
| T | half | pkg1/tst.go:33:16:33:19 | half |
|
||||
| T3 | half | pkg1/tst.go:33:16:33:19 | half |
|
||||
| T4 | half | pkg1/tst.go:33:16:33:19 | half |
|
||||
| base | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||
| embedder | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||
| embedder2 | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||
| embedder3 | f | pkg1/embedding.go:30:18:30:18 | f |
|
||||
| ptrembedder | f | pkg1/embedding.go:10:13:10:13 | f |
|
||||
| ptrembedder | g | pkg1/embedding.go:14:14:14:14 | g |
|
||||
|
||||
@@ -13,3 +13,9 @@
|
||||
| T2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 |
|
||||
| T3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 |
|
||||
| T4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 |
|
||||
| base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.base |
|
||||
| embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder |
|
||||
| embedder2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder2 |
|
||||
| embedder3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder3 |
|
||||
| embedder4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder4 |
|
||||
| ptrembedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.ptrembedder |
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
| main.go:5:1:5:30 | function declaration | 1 |
|
||||
| main.go:7:1:9:1 | function declaration | 2 |
|
||||
| main.go:11:1:11:14 | function declaration | 0 |
|
||||
| pkg1/embedding.go:10:1:12:1 | function declaration | 0 |
|
||||
| pkg1/embedding.go:14:1:16:1 | function declaration | 0 |
|
||||
| pkg1/embedding.go:30:1:32:1 | function declaration | 0 |
|
||||
| pkg1/embedding.go:40:1:61:1 | function declaration | 0 |
|
||||
| pkg1/tst.go:33:1:35:1 | function declaration | 0 |
|
||||
| pkg1/tst.go:37:1:37:26 | function declaration | 1 |
|
||||
| pkg1/tst.go:39:1:57:1 | function declaration | 2 |
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
| main.go:5:1:5:30 | function declaration | 0 |
|
||||
| main.go:7:1:9:1 | function declaration | 2 |
|
||||
| main.go:11:1:11:14 | function declaration | 0 |
|
||||
| pkg1/embedding.go:10:1:12:1 | function declaration | 1 |
|
||||
| pkg1/embedding.go:14:1:16:1 | function declaration | 1 |
|
||||
| pkg1/embedding.go:30:1:32:1 | function declaration | 1 |
|
||||
| pkg1/embedding.go:40:1:61:1 | function declaration | 0 |
|
||||
| pkg1/tst.go:33:1:35:1 | function declaration | 1 |
|
||||
| pkg1/tst.go:37:1:37:26 | function declaration | 0 |
|
||||
| pkg1/tst.go:39:1:57:1 | function declaration | 0 |
|
||||
|
||||
@@ -19,3 +19,15 @@
|
||||
| T4 | pkg1/tst.go:19:9:22:1 | struct type | Foo | * Foo |
|
||||
| T4 | pkg1/tst.go:19:9:22:1 | struct type | flag | bool |
|
||||
| T4 | pkg1/tst.go:19:9:22:1 | struct type | val | int |
|
||||
| embedder | pkg1/embedding.go:19:15:19:28 | struct type | base | base |
|
||||
| embedder2 | pkg1/embedding.go:25:16:25:33 | struct type | base | base |
|
||||
| embedder2 | pkg1/embedding.go:25:16:25:33 | struct type | embedder | embedder |
|
||||
| embedder2 | pkg1/embedding.go:28:16:28:33 | struct type | base | base |
|
||||
| embedder2 | pkg1/embedding.go:28:16:28:33 | struct type | embedder | embedder |
|
||||
| embedder3 | pkg1/embedding.go:25:16:25:33 | struct type | base | base |
|
||||
| embedder3 | pkg1/embedding.go:25:16:25:33 | struct type | embedder | embedder |
|
||||
| embedder3 | pkg1/embedding.go:28:16:28:33 | struct type | base | base |
|
||||
| embedder3 | pkg1/embedding.go:28:16:28:33 | struct type | embedder | embedder |
|
||||
| embedder4 | pkg1/embedding.go:35:16:38:1 | struct type | base | base |
|
||||
| embedder4 | pkg1/embedding.go:35:16:38:1 | struct type | f | int |
|
||||
| ptrembedder | pkg1/embedding.go:22:18:22:32 | struct type | base | * base |
|
||||
|
||||
@@ -13,3 +13,9 @@
|
||||
| T2 | T2 |
|
||||
| T3 | T3 |
|
||||
| T4 | T4 |
|
||||
| base | base |
|
||||
| embedder | embedder |
|
||||
| embedder2 | embedder2 |
|
||||
| embedder3 | embedder3 |
|
||||
| embedder4 | embedder4 |
|
||||
| ptrembedder | ptrembedder |
|
||||
|
||||
61
ql/test/library-tests/semmle/go/Types/pkg1/embedding.go
Normal file
61
ql/test/library-tests/semmle/go/Types/pkg1/embedding.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package pkg1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// `base` and `*base` have method `f`; `*base` also has method `g`
|
||||
type base struct{}
|
||||
|
||||
func (base) f() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (*base) g() int {
|
||||
return 2
|
||||
}
|
||||
|
||||
// `embedder` and `*embedder` have promoted method `f` from `base`; `*embedder` also has method `g` from `*base`
|
||||
type embedder struct{ base }
|
||||
|
||||
// `ptrembedder` and `*ptrembedder` have promoted methods `f` from `base` and `g` from `*base`
|
||||
type ptrembedder struct{ *base }
|
||||
|
||||
// `embedder2` and `*embedder2` have promoted method `f` from `base`; `*embedder2` also has method `g` from `*base`
|
||||
type embedder2 struct{ embedder }
|
||||
|
||||
// `embedder3` and `*embedder3` have their own version of `f`; `*embedder3` also has promoted method `g` from `*base`
|
||||
type embedder3 struct{ embedder }
|
||||
|
||||
func (embedder3) f() int {
|
||||
return 3
|
||||
}
|
||||
|
||||
// `embedder4` and `*embedder4` do not have a method `f`; `*embedder4` has promoted method `g` from `*base`
|
||||
type embedder4 struct {
|
||||
base
|
||||
f int
|
||||
}
|
||||
|
||||
func main() {
|
||||
var (
|
||||
b base
|
||||
bp *base = &b
|
||||
e embedder
|
||||
ep *embedder = &e
|
||||
pe ptrembedder = ptrembedder{bp}
|
||||
pep *ptrembedder = &pe
|
||||
e2 embedder2
|
||||
e2p *embedder2 = &e2
|
||||
e3 embedder3
|
||||
e3p *embedder3 = &e3
|
||||
e4 embedder4
|
||||
e4p *embedder4 = &e4
|
||||
)
|
||||
fmt.Println(base.f(b), (*base).f(bp) /*base.g(b),*/, (*base).g(bp))
|
||||
fmt.Println(embedder.f(e), (*embedder).f(ep) /*embedder.g(e),*/, (*embedder).g(ep))
|
||||
fmt.Println(ptrembedder.f(pe), (*ptrembedder).f(pep), ptrembedder.g(pe), (*ptrembedder).g(pep))
|
||||
fmt.Println(embedder2.f(e2), (*embedder2).f(e2p) /*embedder2.g(e2),*/, (*embedder2).g(e2p))
|
||||
fmt.Println(embedder3.f(e3), (*embedder3).f(e3p) /*embedder3.g(e3),*/, (*embedder3).g(e3p))
|
||||
fmt.Println( /*embedder4.f(e4), (*embedder4).f(e4p), embedder4.g(e3),*/ (*embedder4).g(e4p))
|
||||
}
|
||||
Reference in New Issue
Block a user