mirror of
https://github.com/github/codeql.git
synced 2026-01-30 06:42:57 +01:00
Take promoted methods into account when computing method sets.
This commit is contained in:
@@ -441,11 +441,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,7 +584,7 @@ class SendRecvChanType extends @sendrcvchantype, ChanType {
|
||||
|
||||
/** A named type. */
|
||||
class NamedType extends @namedtype, CompositeType {
|
||||
/** Gets a method with name `m` defined on this type. */
|
||||
/** Gets a method with name `m` defined on this type or its pointer type. */
|
||||
MethodDecl getMethodDecl(string m) {
|
||||
result.getName() = m and
|
||||
this = result.getReceiverBaseType()
|
||||
@@ -580,6 +598,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() }
|
||||
|
||||
Reference in New Issue
Block a user