From fdcc11b10da6883e349b418acfbbf8342fbc068f Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 23 Sep 2026 14:53:56 +0200 Subject: [PATCH 1/3] Unified: Add static name binding for generic type expressions --- .../CONSISTENCY/CfgConsistency.expected | 4 ++++ .../library-tests/static-name-binding/generics.swift | 9 +++++++++ 2 files changed, 13 insertions(+) create mode 100644 unified/ql/test/library-tests/static-name-binding/CONSISTENCY/CfgConsistency.expected create mode 100644 unified/ql/test/library-tests/static-name-binding/generics.swift diff --git a/unified/ql/test/library-tests/static-name-binding/CONSISTENCY/CfgConsistency.expected b/unified/ql/test/library-tests/static-name-binding/CONSISTENCY/CfgConsistency.expected new file mode 100644 index 000000000000..943f915914c2 --- /dev/null +++ b/unified/ql/test/library-tests/static-name-binding/CONSISTENCY/CfgConsistency.expected @@ -0,0 +1,4 @@ +consistencyOverview +| deadEnd | 1 | +deadEnd +| generics.swift:3:10:3:17 | Entry | diff --git a/unified/ql/test/library-tests/static-name-binding/generics.swift b/unified/ql/test/library-tests/static-name-binding/generics.swift new file mode 100644 index 000000000000..f3e7b6de2d91 --- /dev/null +++ b/unified/ql/test/library-tests/static-name-binding/generics.swift @@ -0,0 +1,9 @@ +enum GenericEnum { + case novalue + case value(T) // $ access=T +} + +func testGenericEnum() { + let intValue = GenericEnum.value(42) // $ access=GenericEnum access=GenericEnum.value + let stringValue = GenericEnum.novalue // $ access=GenericEnum access=String $ MISSING: access=GenericEnum.novalue +} From 009d0c3310e095fe8e727be44700df9c7fd1b463 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 23 Sep 2026 14:04:31 +0200 Subject: [PATCH 2/3] Unified: Handle `GenericTypeExpr` in static name binding --- unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll | 2 ++ .../ql/test/library-tests/static-name-binding/generics.swift | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll b/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll index 6736e52da0bf..578ed784cfdc 100644 --- a/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll +++ b/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll @@ -121,6 +121,8 @@ class NameBindingNode extends TNameBindingNode { Identifier getIdentifierFromRef(AstNode n) { result = n.(PotentialLocalNameAccess) or + result = n.(GenericTypeExpr).getBase() + or result = n.(MemberAccessExpr).getMemberNameNode() } diff --git a/unified/ql/test/library-tests/static-name-binding/generics.swift b/unified/ql/test/library-tests/static-name-binding/generics.swift index f3e7b6de2d91..767cd5b2017b 100644 --- a/unified/ql/test/library-tests/static-name-binding/generics.swift +++ b/unified/ql/test/library-tests/static-name-binding/generics.swift @@ -5,5 +5,5 @@ enum GenericEnum { func testGenericEnum() { let intValue = GenericEnum.value(42) // $ access=GenericEnum access=GenericEnum.value - let stringValue = GenericEnum.novalue // $ access=GenericEnum access=String $ MISSING: access=GenericEnum.novalue + let stringValue = GenericEnum.novalue // $ access=GenericEnum access=String access=GenericEnum.novalue } From d7ef6723c5b407291853793a2bd0aded067f50b2 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 23 Sep 2026 15:09:49 +0200 Subject: [PATCH 3/3] Apply suggestion from @asgerf Co-authored-by: Asger F --- unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll b/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll index 578ed784cfdc..9ea85beb6448 100644 --- a/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll +++ b/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll @@ -121,7 +121,7 @@ class NameBindingNode extends TNameBindingNode { Identifier getIdentifierFromRef(AstNode n) { result = n.(PotentialLocalNameAccess) or - result = n.(GenericTypeExpr).getBase() + result = getIdentifierFromRef(n.(GenericTypeExpr).getBase()) or result = n.(MemberAccessExpr).getMemberNameNode() }