Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go: add tests regarding type aliasing #17369

Merged
merged 7 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
callTargets
| test.go:48:2:48:24 | call to ImplementMe | test.go:12:1:12:69 | function declaration | ImplementMe |
| test.go:48:2:48:24 | call to ImplementMe | test.go:17:1:17:64 | function declaration | ImplementMe |
| test.go:48:2:48:24 | call to ImplementMe | test.go:24:1:24:53 | function declaration | ImplementMe |
| test.go:48:2:48:24 | call to ImplementMe | test.go:31:1:31:59 | function declaration | ImplementMe |
| test.go:48:2:48:24 | call to ImplementMe | test.go:38:1:38:71 | function declaration | ImplementMe |
| test.go:48:2:48:24 | call to ImplementMe | test.go:45:1:45:69 | function declaration | ImplementMe |
#select
| file://:0:0:0:0 | basic interface type | file://:0:0:0:0 | basic interface type |
| file://:0:0:0:0 | basic interface type | test.go:10:6:10:10 | Impl1 |
| file://:0:0:0:0 | basic interface type | test.go:15:6:15:10 | Impl2 |
| file://:0:0:0:0 | basic interface type | test.go:20:6:20:10 | Impl3 |
| file://:0:0:0:0 | basic interface type | test.go:27:6:27:10 | Impl4 |
| file://:0:0:0:0 | basic interface type | test.go:34:6:34:10 | Impl5 |
| file://:0:0:0:0 | basic interface type | test.go:41:6:41:10 | Impl6 |
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package intfs

type IntAlias = int

type Target = interface {
ImplementMe(callable func(struct{ x IntAlias }))
}

// Simple direct implementation
type Impl1 struct{}

func (recv Impl1) ImplementMe(callable func(struct{ x IntAlias })) {}

// Implementation via unaliasing
type Impl2 struct{}

func (recv Impl2) ImplementMe(callable func(struct{ x int })) {}

// Implementation via top-level aliasing
type Impl3 struct{}

type Impl3Alias = func(struct{ x IntAlias })

func (recv Impl3) ImplementMe(callable Impl3Alias) {}

// Implementation via aliasing the struct
type Impl4 struct{}

type Impl4Alias = struct{ x IntAlias }

func (recv Impl4) ImplementMe(callable func(Impl4Alias)) {}

// Implementation via aliasing the struct member
type Impl5 struct{}

type Impl5Alias = IntAlias

func (recv Impl5) ImplementMe(callable func(struct{ x Impl5Alias })) {}

// Implementation via defining the method on an alias
type Impl6 struct{}

type Impl6Alias = Impl6

func (recv Impl6Alias) ImplementMe(callable func(struct{ x int })) {}

func Caller(target Target) {
target.ImplementMe(nil)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import go

query predicate callTargets(DataFlow::CallNode cn, FuncDef target, string targetName) {
target = cn.getACallee() and targetName = target.getName()
}

from InterfaceType i, Type impl
where
i.hasMethod("ImplementMe", _) and
impl.implements(i)
select i, impl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package aliases

type IntAlias = int

type S1 = struct{ x int }
type S2 = struct{ x IntAlias }

type I1 = interface{ F(int) }
type I2 = interface{ F(IntAlias) }
type I3 = interface{ F(S1) }
type I4 = interface{ F(S2) }

func Test1(param1 I1, param2 I3, arg int) {
param1.F(arg)
param2.F(S1{arg})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
distinctDefinedFs
| 2 |
declaredEntities
| methods.go:3:6:3:13 | IntAlias (1 declaration sites) |
| methods.go:5:6:5:7 | S1 (1 declaration sites) |
| methods.go:5:19:5:19 | x (2 declaration sites) |
| methods.go:6:6:6:7 | S2 (1 declaration sites) |
| methods.go:6:19:6:19 | x (2 declaration sites) |
| methods.go:8:6:8:7 | I1 (1 declaration sites) |
| methods.go:8:22:8:22 | F (2 declaration sites) |
| methods.go:9:6:9:7 | I2 (1 declaration sites) |
| methods.go:9:22:9:22 | F (2 declaration sites) |
| methods.go:10:6:10:7 | I3 (1 declaration sites) |
| methods.go:10:22:10:22 | F (2 declaration sites) |
| methods.go:11:6:11:7 | I4 (1 declaration sites) |
| methods.go:11:22:11:22 | F (2 declaration sites) |
| methods.go:13:6:13:10 | Test1 (1 declaration sites) |
| methods.go:13:12:13:17 | param1 (1 declaration sites) |
| methods.go:13:23:13:28 | param2 (1 declaration sites) |
| methods.go:13:34:13:36 | arg (1 declaration sites) |
23 changes: 23 additions & 0 deletions go/ql/test/library-tests/semmle/go/aliases/MethodDefs/test.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import go

newtype TEntityWithDeclInfo =
MkEntityWithDeclInfo(Entity e, int nDecls) { nDecls = count(e.getDeclaration()) and nDecls > 0 }

class EntityWithDeclInfo extends TEntityWithDeclInfo {
Entity e;
int nDecls;

EntityWithDeclInfo() { this = MkEntityWithDeclInfo(e, nDecls) }

string toString() { result = e.toString() + " (" + nDecls + " declaration sites)" }

predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
e.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}

query predicate distinctDefinedFs(int ct) { ct = count(DeclaredFunction e | e.toString() = "F") }

query predicate declaredEntities(EntityWithDeclInfo e) { any() }
16 changes: 16 additions & 0 deletions go/ql/test/library-tests/semmle/go/aliases/defsuses/defsuses.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package aliases

type IntAlias = int

type S1 = struct{ x int }
type S2 = struct{ x IntAlias }

func Test1() int {
obj := S1{1}
obj.x = 2

var ptr *S2
ptr = &obj

return ptr.x
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
lowLevelDefs
| defsuses.go:3:6:3:13 | IntAlias | defsuses.go:3:6:3:13 | IntAlias (1 declaration sites) |
| defsuses.go:5:6:5:7 | S1 | defsuses.go:5:6:5:7 | S1 (1 declaration sites) |
| defsuses.go:5:19:5:19 | x | defsuses.go:5:19:5:19 | x (2 declaration sites) |
| defsuses.go:5:19:5:19 | x | defsuses.go:6:19:6:19 | x (2 declaration sites) |
| defsuses.go:6:6:6:7 | S2 | defsuses.go:6:6:6:7 | S2 (1 declaration sites) |
| defsuses.go:6:19:6:19 | x | defsuses.go:5:19:5:19 | x (2 declaration sites) |
| defsuses.go:6:19:6:19 | x | defsuses.go:6:19:6:19 | x (2 declaration sites) |
| defsuses.go:8:6:8:10 | Test1 | defsuses.go:8:6:8:10 | Test1 (1 declaration sites) |
| defsuses.go:9:2:9:4 | obj | defsuses.go:9:2:9:4 | obj (1 declaration sites) |
| defsuses.go:12:6:12:8 | ptr | defsuses.go:12:6:12:8 | ptr (1 declaration sites) |
lowLevelUses
| defsuses.go:3:17:3:19 | int | file://:0:0:0:0 | int (0 declaration sites) |
| defsuses.go:5:21:5:23 | int | file://:0:0:0:0 | int (0 declaration sites) |
| defsuses.go:6:21:6:28 | IntAlias | defsuses.go:3:6:3:13 | IntAlias (1 declaration sites) |
| defsuses.go:8:14:8:16 | int | file://:0:0:0:0 | int (0 declaration sites) |
| defsuses.go:9:9:9:10 | S1 | defsuses.go:5:6:5:7 | S1 (1 declaration sites) |
| defsuses.go:10:2:10:4 | obj | defsuses.go:9:2:9:4 | obj (1 declaration sites) |
| defsuses.go:10:6:10:6 | x | defsuses.go:5:19:5:19 | x (2 declaration sites) |
| defsuses.go:10:6:10:6 | x | defsuses.go:6:19:6:19 | x (2 declaration sites) |
| defsuses.go:12:11:12:12 | S2 | defsuses.go:6:6:6:7 | S2 (1 declaration sites) |
| defsuses.go:13:2:13:4 | ptr | defsuses.go:12:6:12:8 | ptr (1 declaration sites) |
| defsuses.go:13:9:13:11 | obj | defsuses.go:9:2:9:4 | obj (1 declaration sites) |
| defsuses.go:15:9:15:11 | ptr | defsuses.go:12:6:12:8 | ptr (1 declaration sites) |
| defsuses.go:15:13:15:13 | x | defsuses.go:5:19:5:19 | x (2 declaration sites) |
| defsuses.go:15:13:15:13 | x | defsuses.go:6:19:6:19 | x (2 declaration sites) |
distinctDefinedXs
| 1 |
distinctUsedXs
| 1 |
fieldUseUsePairs
| defsuses.go:10:6:10:6 | x | defsuses.go:15:13:15:13 | x |
| defsuses.go:15:13:15:13 | x | defsuses.go:10:6:10:6 | x |
37 changes: 37 additions & 0 deletions go/ql/test/library-tests/semmle/go/aliases/defsuses/test.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import go

newtype TEntityWithDeclInfo = MkEntityWithDeclInfo(Entity e)

class EntityWithDeclInfo extends TEntityWithDeclInfo {
Entity e;

EntityWithDeclInfo() { this = MkEntityWithDeclInfo(e) }

string toString() {
result = e.toString() + " (" + count(e.getDeclaration()) + " declaration sites)"
}

predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
e.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}

query predicate lowLevelDefs(Ident i, EntityWithDeclInfo ewrapped) {
exists(Entity e | ewrapped = MkEntityWithDeclInfo(e) | defs(i, e))
}

query predicate lowLevelUses(Ident i, EntityWithDeclInfo ewrapped) {
exists(Entity e | ewrapped = MkEntityWithDeclInfo(e) | uses(i, e))
}

query predicate distinctDefinedXs(int ct) {
ct = count(Entity e | defs(_, e) and e.toString() = "x")
}

query predicate distinctUsedXs(int ct) { ct = count(Entity e | uses(_, e) and e.toString() = "x") }

query predicate fieldUseUsePairs(Ident i1, Ident i2) {
exists(Field e | uses(i1, e) and uses(i2, e) and i1 != i2)
}
Loading