From 2a5d567041c1c078c90e30ba2a084ceeed3a5682 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 16 Oct 2021 21:14:11 +0200 Subject: [PATCH 01/17] add test for type resolution --- ql/test/type/Test.qll | 13 +++++++++++++ ql/test/type/type.expected | 34 ++++++++++++++++++++++++++++++++++ ql/test/type/type.ql | 3 +++ 3 files changed, 50 insertions(+) create mode 100644 ql/test/type/Test.qll create mode 100644 ql/test/type/type.expected create mode 100644 ql/test/type/type.ql diff --git a/ql/test/type/Test.qll b/ql/test/type/Test.qll new file mode 100644 index 00000000000..484132c2005 --- /dev/null +++ b/ql/test/type/Test.qll @@ -0,0 +1,13 @@ +import ql + +class Strings extends string { + Strings() { this = ["", "f", "o", "foo", "bar", "b", "a", "r", "ba", "ar"] } +} + +class Floats extends float { + Floats() { this = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] } +} + +string conc(Strings a, Strings b) { result = a + b } + +float floats(Floats a, Floats b) { result = a + b } diff --git a/ql/test/type/type.expected b/ql/test/type/type.expected new file mode 100644 index 00000000000..06e2d5d4dbb --- /dev/null +++ b/ql/test/type/type.expected @@ -0,0 +1,34 @@ +| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings | +| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings.Strings | +| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings.extends | +| Test.qll:4:22:4:76 | Set | file://:0:0:0:0 | string | +| Test.qll:4:23:4:24 | String | file://:0:0:0:0 | string | +| Test.qll:4:27:4:29 | String | file://:0:0:0:0 | string | +| Test.qll:4:32:4:34 | String | file://:0:0:0:0 | string | +| Test.qll:4:37:4:41 | String | file://:0:0:0:0 | string | +| Test.qll:4:44:4:48 | String | file://:0:0:0:0 | string | +| Test.qll:4:51:4:53 | String | file://:0:0:0:0 | string | +| Test.qll:4:56:4:58 | String | file://:0:0:0:0 | string | +| Test.qll:4:61:4:63 | String | file://:0:0:0:0 | string | +| Test.qll:4:66:4:69 | String | file://:0:0:0:0 | string | +| Test.qll:4:72:4:75 | String | file://:0:0:0:0 | string | +| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats | +| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats.Floats | +| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats.extends | +| Test.qll:8:21:8:70 | Set | file://:0:0:0:0 | float | +| Test.qll:8:22:8:24 | Float | file://:0:0:0:0 | float | +| Test.qll:8:27:8:29 | Float | file://:0:0:0:0 | float | +| Test.qll:8:32:8:34 | Float | file://:0:0:0:0 | float | +| Test.qll:8:37:8:39 | Float | file://:0:0:0:0 | float | +| Test.qll:8:42:8:44 | Float | file://:0:0:0:0 | float | +| Test.qll:8:47:8:49 | Float | file://:0:0:0:0 | float | +| Test.qll:8:52:8:54 | Float | file://:0:0:0:0 | float | +| Test.qll:8:57:8:59 | Float | file://:0:0:0:0 | float | +| Test.qll:8:62:8:64 | Float | file://:0:0:0:0 | float | +| Test.qll:8:67:8:69 | Float | file://:0:0:0:0 | float | +| Test.qll:11:37:11:42 | result | file://:0:0:0:0 | string | +| Test.qll:11:46:11:46 | a | Test.qll:3:1:5:1 | Strings | +| Test.qll:11:50:11:50 | b | Test.qll:3:1:5:1 | Strings | +| Test.qll:13:36:13:41 | result | file://:0:0:0:0 | float | +| Test.qll:13:45:13:45 | a | Test.qll:7:1:9:1 | Floats | +| Test.qll:13:49:13:49 | b | Test.qll:7:1:9:1 | Floats | diff --git a/ql/test/type/type.ql b/ql/test/type/type.ql new file mode 100644 index 00000000000..d2dad5fa3ef --- /dev/null +++ b/ql/test/type/type.ql @@ -0,0 +1,3 @@ +import ql + +query Type getType(Expr e) { result = e.getType() } From c1b011d47cd0c031b37c79f076ddb295c49b5386 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 16 Oct 2021 21:35:02 +0200 Subject: [PATCH 02/17] better type resolution of add expressions --- ql/src/codeql_ql/ast/Ast.qll | 22 +++++++++++++++++----- ql/test/type/type.expected | 2 ++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index 94ca5c2a72b..e623a5ca8e2 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -1794,6 +1794,7 @@ class Negation extends TNegation, Formula { /** An expression, such as `x+4`. */ class Expr extends TExpr, AstNode { + cached Type getType() { none() } } @@ -1874,15 +1875,14 @@ class AddSubExpr extends TAddSubExpr, BinOpExpr { result = this.getLeftOperand().getType() and result = this.getRightOperand().getType() or - // Both operands are subtypes of `int` - result.getName() = "int" and - result = this.getLeftOperand().getType().getASuperType*() and - result = this.getRightOperand().getType().getASuperType*() + // Both operands are subtypes of `int` / `string` / `float` + exprOfPrimitiveAddType(result) = this.getLeftOperand() and + exprOfPrimitiveAddType(result) = this.getRightOperand() or // Coercion to from `int` to `float` exists(PrimitiveType i | result.getName() = "float" and i.getName() = "int" | this.getAnOperand().getType() = result and - this.getAnOperand().getType().getASuperType*() = i + this.getAnOperand() = exprOfPrimitiveAddType(i) ) or // Coercion to `string` @@ -1899,6 +1899,18 @@ class AddSubExpr extends TAddSubExpr, BinOpExpr { } } +pragma[noinline] +private Expr exprOfPrimitiveAddType(PrimitiveType t) { + result.getType() = getASubTypeOfAddPrimitive(t) +} + +private Type getASubTypeOfAddPrimitive(PrimitiveType prim) { + result = prim and + result.getName() = ["int", "string", "float"] + or + result.getASuperType() = getASubTypeOfAddPrimitive(prim) +} + /** * An addition expression, such as `x + y`. */ diff --git a/ql/test/type/type.expected b/ql/test/type/type.expected index 06e2d5d4dbb..ed05b1aac84 100644 --- a/ql/test/type/type.expected +++ b/ql/test/type/type.expected @@ -28,7 +28,9 @@ | Test.qll:8:67:8:69 | Float | file://:0:0:0:0 | float | | Test.qll:11:37:11:42 | result | file://:0:0:0:0 | string | | Test.qll:11:46:11:46 | a | Test.qll:3:1:5:1 | Strings | +| Test.qll:11:46:11:50 | AddExpr | file://:0:0:0:0 | string | | Test.qll:11:50:11:50 | b | Test.qll:3:1:5:1 | Strings | | Test.qll:13:36:13:41 | result | file://:0:0:0:0 | float | | Test.qll:13:45:13:45 | a | Test.qll:7:1:9:1 | Floats | +| Test.qll:13:45:13:49 | AddExpr | file://:0:0:0:0 | float | | Test.qll:13:49:13:49 | b | Test.qll:7:1:9:1 | Floats | From c43ff2f9d0b0317e16d2e0761e5d31f44d7d3c4c Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 16 Oct 2021 21:54:23 +0200 Subject: [PATCH 03/17] add test for super-types --- ql/test/type/Test.qll | 14 ++++++++++++++ ql/test/type/type.expected | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/ql/test/type/Test.qll b/ql/test/type/Test.qll index 484132c2005..acb2302572b 100644 --- a/ql/test/type/Test.qll +++ b/ql/test/type/Test.qll @@ -11,3 +11,17 @@ class Floats extends float { string conc(Strings a, Strings b) { result = a + b } float floats(Floats a, Floats b) { result = a + b } + +class Base extends string { + Base() { this = ["foo"] } + + int foo() { result = 1 } +} + +class Sub extends Base { + Sub() { this = ["bar"] } + + int bar() { result = Base.super.foo() } + + int bar2() { result = super.foo() } +} diff --git a/ql/test/type/type.expected b/ql/test/type/type.expected index ed05b1aac84..8da7ec49e84 100644 --- a/ql/test/type/type.expected +++ b/ql/test/type/type.expected @@ -34,3 +34,19 @@ | Test.qll:13:45:13:45 | a | Test.qll:7:1:9:1 | Floats | | Test.qll:13:45:13:49 | AddExpr | file://:0:0:0:0 | float | | Test.qll:13:49:13:49 | b | Test.qll:7:1:9:1 | Floats | +| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base | +| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base.Base | +| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base.extends | +| Test.qll:16:19:16:25 | Set | file://:0:0:0:0 | string | +| Test.qll:16:20:16:24 | String | file://:0:0:0:0 | string | +| Test.qll:18:15:18:20 | result | file://:0:0:0:0 | int | +| Test.qll:18:24:18:24 | Integer | file://:0:0:0:0 | int | +| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub | +| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub.Sub | +| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub.extends | +| Test.qll:22:18:22:24 | Set | file://:0:0:0:0 | string | +| Test.qll:22:19:22:23 | String | file://:0:0:0:0 | string | +| Test.qll:24:15:24:20 | result | file://:0:0:0:0 | int | +| Test.qll:24:24:24:39 | MemberCall | file://:0:0:0:0 | int | +| Test.qll:26:16:26:21 | result | file://:0:0:0:0 | int | +| Test.qll:26:25:26:35 | MemberCall | file://:0:0:0:0 | int | From f99ce113cb45d388e673314f694a06acfc1f47ae Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 16 Oct 2021 21:55:36 +0200 Subject: [PATCH 04/17] resolve super-expressions when the super-type is explicitly mentioned --- ql/src/codeql_ql/ast/Ast.qll | 9 ++++++++- ql/test/type/type.expected | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index e623a5ca8e2..ae0934f3d62 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -1758,9 +1758,16 @@ class ThisAccess extends Identifier { /** A use of `super`. */ class Super extends TSuper, Expr { - Super() { this = TSuper(_) } + QL::SuperRef ref; + + Super() { this = TSuper(ref) } override string getAPrimaryQlClass() { result = "Super" } + + override Type getType() { + exists(TypeExpr te | ref.getChild(0) = toQL(te) | result = te.getResolvedType()) + // TODO: Also resolve the type when there is no TypeExpr. + } } /** An access to `result`. */ diff --git a/ql/test/type/type.expected b/ql/test/type/type.expected index 8da7ec49e84..ee758234b31 100644 --- a/ql/test/type/type.expected +++ b/ql/test/type/type.expected @@ -47,6 +47,7 @@ | Test.qll:22:18:22:24 | Set | file://:0:0:0:0 | string | | Test.qll:22:19:22:23 | String | file://:0:0:0:0 | string | | Test.qll:24:15:24:20 | result | file://:0:0:0:0 | int | +| Test.qll:24:24:24:33 | Super | Test.qll:15:1:19:1 | Base | | Test.qll:24:24:24:39 | MemberCall | file://:0:0:0:0 | int | | Test.qll:26:16:26:21 | result | file://:0:0:0:0 | int | | Test.qll:26:25:26:35 | MemberCall | file://:0:0:0:0 | int | From b31ea30e852bb7a4ae0f57a3b2b7e4dfa1b9bc7c Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 16 Oct 2021 22:22:52 +0200 Subject: [PATCH 05/17] better support for getType on super --- ql/src/codeql_ql/ast/Ast.qll | 3 +-- ql/test/type/type.expected | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index ae0934f3d62..06713d30745 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -1765,8 +1765,7 @@ class Super extends TSuper, Expr { override string getAPrimaryQlClass() { result = "Super" } override Type getType() { - exists(TypeExpr te | ref.getChild(0) = toQL(te) | result = te.getResolvedType()) - // TODO: Also resolve the type when there is no TypeExpr. + exists(MemberCall call | call.getBase() = this | result = call.getTarget().getDeclaringType()) } } diff --git a/ql/test/type/type.expected b/ql/test/type/type.expected index ee758234b31..29f6076374f 100644 --- a/ql/test/type/type.expected +++ b/ql/test/type/type.expected @@ -50,4 +50,5 @@ | Test.qll:24:24:24:33 | Super | Test.qll:15:1:19:1 | Base | | Test.qll:24:24:24:39 | MemberCall | file://:0:0:0:0 | int | | Test.qll:26:16:26:21 | result | file://:0:0:0:0 | int | +| Test.qll:26:25:26:29 | Super | Test.qll:15:1:19:1 | Base | | Test.qll:26:25:26:35 | MemberCall | file://:0:0:0:0 | int | From 74b1c19a206af78ecbdd622132df3cbccb23a62e Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 16 Oct 2021 23:09:48 +0200 Subject: [PATCH 06/17] only resolve imports to qll files, and not e.g. dbschemes --- ql/src/codeql_ql/ast/internal/Module.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ql/src/codeql_ql/ast/internal/Module.qll b/ql/src/codeql_ql/ast/internal/Module.qll index 4c6d3d196c5..acf47a86017 100644 --- a/ql/src/codeql_ql/ast/internal/Module.qll +++ b/ql/src/codeql_ql/ast/internal/Module.qll @@ -139,6 +139,7 @@ private predicate resolveQualifiedName(Import imp, ContainerOrModule m, int i) { } private predicate resolveSelectionName(Import imp, ContainerOrModule m, int i) { + (m.(File_).getFile().getExtension() = "qll" or not m instanceof File_) and exists(int last | resolveQualifiedName(imp, m, last) and last = count(int j | exists(imp.getQualifiedName(j))) - 1 @@ -281,7 +282,11 @@ module ModConsistency { query predicate multipleResolve(Import imp, int c, ContainerOrModule m) { c = strictcount(ContainerOrModule m0 | resolve(imp, m0)) and c > 1 and - resolve(imp, m) + resolve(imp, m) and + not imp.getLocation() + .getFile() + .getAbsolutePath() + .regexpMatch(".*/(test|examples|ql-training|recorded-call-graph-metrics)/.*") } query predicate multipleResolveModuleExpr(ModuleExpr me, int c, ContainerOrModule m) { From 9d9663d8423a29b14f0fba648214b65b903beed0 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 16 Oct 2021 23:17:42 +0200 Subject: [PATCH 07/17] and consistency query that will highlight new consistency errors --- ql/src/codeql_ql/ast/internal/Variable.qll | 6 ++- .../queries/diagnostics/EmptyConsistencies.ql | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 ql/src/queries/diagnostics/EmptyConsistencies.ql diff --git a/ql/src/codeql_ql/ast/internal/Variable.qll b/ql/src/codeql_ql/ast/internal/Variable.qll index 634c4b1a3e8..9e9103d34f5 100644 --- a/ql/src/codeql_ql/ast/internal/Variable.qll +++ b/ql/src/codeql_ql/ast/internal/Variable.qll @@ -1,5 +1,5 @@ import ql -import codeql_ql.ast.internal.AstNodes +private import codeql_ql.ast.internal.AstNodes private class TScope = TClass or TAggregate or TQuantifier or TSelect or TPredicate or TNewTypeBranch; @@ -89,4 +89,8 @@ module VarConsistency { decl = f.getDeclaration() and strictcount(f.getDeclaration()) > 1 } + + query predicate noFieldDef(FieldAccess f) { not exists(f.getDeclaration()) } + + query predicate noVarDef(VarAccess v) { not exists(v.getDeclaration()) } } diff --git a/ql/src/queries/diagnostics/EmptyConsistencies.ql b/ql/src/queries/diagnostics/EmptyConsistencies.ql new file mode 100644 index 00000000000..e0e7a3ccf92 --- /dev/null +++ b/ql/src/queries/diagnostics/EmptyConsistencies.ql @@ -0,0 +1,37 @@ +/** + * @name Consistency predicate that should be empty + * @description This query should have no results on the CodeQL repos. + * It's marked as a warning query to make the results visible. + * @kind problem + * @problem.severity warning + * @precision very-high + * @id ql/diagnostics/empty-consitencies + */ + +import ql +import codeql_ql.ast.internal.Predicate::PredConsistency as PredConsistency +import codeql_ql.ast.internal.Type::TyConsistency as TypeConsistency +import codeql_ql.ast.internal.Builtins::BuildinsConsistency as BuildinsConsistency +import codeql_ql.ast.internal.Module::ModConsistency as ModConsistency +import codeql_ql.ast.internal.Variable::VarConsistency as VarConsistency + +from AstNode node, string msg +where + PredConsistency::noResolveCall(node) and msg = "PredConsistency::noResolveCall" + or + TypeConsistency::noResolve(node) and msg = "TypeConsistency::noResolve" + or + TypeConsistency::exprNoType(node) and msg = "TypeConsistency::exprNoType" + or + TypeConsistency::varDefNoType(node) and msg = "TypeConsistency::varDefNoType" + or + //or // has 1 result, but the CodeQL compiler also can't figure out that one. I suppoed the file is never imported. + //TypeConsistency::noResolve(node) and msg = "TypeConsistency::noResolve" + //or // has 1 result, but the CodeQL compiler also can't figure out that one. Same file as above. + //ModConsistency::noResolve(node) and msg = "ModConsistency::noResolve" + ModConsistency::noResolveModuleExpr(node) and msg = "ModConsistency::noResolveModuleExpr" + or + VarConsistency::noFieldDef(node) and msg = "VarConsistency::noFieldDef" + or + VarConsistency::noVarDef(node) and msg = "VarConsistency::noVarDef" +select node, msg From 2af3fb5ccaff3ba2dbc94ff14137f729402954d5 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 17 Oct 2021 08:40:55 +0200 Subject: [PATCH 08/17] add test for predicateExpr --- ql/test/callgraph/Foo.qll | 8 ++++++++ ql/test/callgraph/callgraph.expected | 4 ++++ ql/test/callgraph/callgraph.ql | 2 ++ 3 files changed, 14 insertions(+) diff --git a/ql/test/callgraph/Foo.qll b/ql/test/callgraph/Foo.qll index 3bd6484be12..1a2ac90e06e 100644 --- a/ql/test/callgraph/Foo.qll +++ b/ql/test/callgraph/Foo.qll @@ -37,3 +37,11 @@ module Buildins { predicate regexpCapture(string s) { "foo".regexpCapture("\\w", 1) = s } } + +cached +newtype TApiNode = MkRoot() + +private predicate edge(TApiNode a, TApiNode b) { a = b } + +cached +int distanceFromRoot(TApiNode nd) = shortestDistances(MkRoot/0, edge/2)(_, nd, result) diff --git a/ql/test/callgraph/callgraph.expected b/ql/test/callgraph/callgraph.expected index a931da5b1ff..4011cfb9925 100644 --- a/ql/test/callgraph/callgraph.expected +++ b/ql/test/callgraph/callgraph.expected @@ -22,3 +22,7 @@ getTarget | packs/src/SrcThing.qll:5:3:5:8 | PredicateCall | packs/src/SrcThing.qll:8:1:8:30 | ClasslessPredicate bar | dependsOn | packs/src/qlpack.yml:1:1:1:4 | ql-testing-src-pack | packs/lib/qlpack.yml:1:1:1:4 | ql-testing-lib-pack | +exprPredicate +| Foo.qll:24:22:24:31 | predicate | Foo.qll:22:3:22:32 | ClasslessPredicate myThing0 | +| Foo.qll:26:22:26:31 | predicate | Foo.qll:20:3:20:54 | ClasslessPredicate myThing2 | +| Foo.qll:47:65:47:70 | predicate | Foo.qll:44:9:44:56 | ClasslessPredicate edge | diff --git a/ql/test/callgraph/callgraph.ql b/ql/test/callgraph/callgraph.ql index 9ff79048b84..bf7f2ed1293 100644 --- a/ql/test/callgraph/callgraph.ql +++ b/ql/test/callgraph/callgraph.ql @@ -3,3 +3,5 @@ import ql query AstNode getTarget(Call call) { result = call.getTarget() } query YAML::QLPack dependsOn(YAML::QLPack pack) { result = pack.getADependency() } + +query Predicate exprPredicate(PredicateExpr expr) { result = expr.getResolvedPredicate() } From 055937eefb7b1088eddbffe237aec09c9c6d1cc5 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 17 Oct 2021 11:58:00 +0200 Subject: [PATCH 09/17] NewTypeBranches are Predicates --- ql/src/codeql_ql/ast/Ast.qll | 4 ++-- ql/src/codeql_ql/ast/internal/AstNodes.qll | 3 ++- ql/src/codeql_ql/ast/internal/Predicate.qll | 17 +++++------------ ql/test/callgraph/callgraph.expected | 1 + 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index 06713d30745..e11c43a569a 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -819,7 +819,7 @@ class NewType extends TNewType, TypeDeclaration, ModuleDeclaration { * A branch in a `newtype`. * E.g. `Bar()` or `Baz()` in `newtype Foo = Bar() or Baz()`. */ -class NewTypeBranch extends TNewTypeBranch, PredicateOrBuiltin, TypeDeclaration { +class NewTypeBranch extends TNewTypeBranch, Predicate, TypeDeclaration { QL::DatatypeBranch branch; NewTypeBranch() { this = TNewTypeBranch(branch) } @@ -835,7 +835,7 @@ class NewTypeBranch extends TNewTypeBranch, PredicateOrBuiltin, TypeDeclaration } /** Gets the body of this branch. */ - Formula getBody() { toQL(result) = branch.getChild(_).(QL::Body).getChild() } + override Formula getBody() { toQL(result) = branch.getChild(_).(QL::Body).getChild() } override NewTypeBranchType getReturnType() { result.getDeclaration() = this } diff --git a/ql/src/codeql_ql/ast/internal/AstNodes.qll b/ql/src/codeql_ql/ast/internal/AstNodes.qll index 1b0f92d014e..9e5b8cb99ab 100644 --- a/ql/src/codeql_ql/ast/internal/AstNodes.qll +++ b/ql/src/codeql_ql/ast/internal/AstNodes.qll @@ -193,7 +193,8 @@ QL::AstNode toQL(AST::AstNode n) { n = TAnnotationArg(result) } -class TPredicate = TCharPred or TClasslessPredicate or TClassPredicate or TDBRelation; +class TPredicate = + TCharPred or TClasslessPredicate or TClassPredicate or TDBRelation or TNewTypeBranch; class TPredOrBuiltin = TPredicate or TNewTypeBranch or TBuiltin; diff --git a/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/src/codeql_ql/ast/internal/Predicate.qll index 44715c1b0ff..fa0f55bf893 100644 --- a/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -3,20 +3,13 @@ private import Builtins private import codeql_ql.ast.internal.Module private import codeql_ql.ast.internal.AstNodes -private class TClasslessPredicateOrNewTypeBranch = TClasslessPredicate or TNewTypeBranch; - -private string getPredicateName(TClasslessPredicateOrNewTypeBranch p) { - result = p.(ClasslessPredicate).getName() or - result = p.(NewTypeBranch).getName() -} - private predicate definesPredicate( - FileOrModule m, string name, int arity, TClasslessPredicateOrNewTypeBranch p, boolean public + FileOrModule m, string name, int arity, Predicate p, boolean public ) { m = getEnclosingModule(p) and - name = getPredicateName(p) and + name = p.getName() and public = getPublicBool(p) and - arity = [p.(ClasslessPredicate).getArity(), count(p.(NewTypeBranch).getField(_))] + arity = p.getArity() or // import X exists(Import imp, FileOrModule m0 | @@ -40,7 +33,7 @@ private predicate definesPredicate( cached private module Cached { cached - predicate resolvePredicateExpr(PredicateExpr pe, ClasslessPredicate p) { + predicate resolvePredicateExpr(PredicateExpr pe, Predicate p) { exists(FileOrModule m, boolean public | not exists(pe.getQualifier()) and m = getEnclosingModule(pe).getEnclosing*() and @@ -49,7 +42,7 @@ private module Cached { m = pe.getQualifier().getResolvedModule() and public = true | - definesPredicate(m, pe.getName(), count(p.getParameter(_)), p, public) + definesPredicate(m, pe.getName(), p.getArity(), p, public) ) } diff --git a/ql/test/callgraph/callgraph.expected b/ql/test/callgraph/callgraph.expected index 4011cfb9925..33fb31cef9d 100644 --- a/ql/test/callgraph/callgraph.expected +++ b/ql/test/callgraph/callgraph.expected @@ -25,4 +25,5 @@ dependsOn exprPredicate | Foo.qll:24:22:24:31 | predicate | Foo.qll:22:3:22:32 | ClasslessPredicate myThing0 | | Foo.qll:26:22:26:31 | predicate | Foo.qll:20:3:20:54 | ClasslessPredicate myThing2 | +| Foo.qll:47:55:47:62 | predicate | Foo.qll:42:20:42:27 | NewTypeBranch MkRoot | | Foo.qll:47:65:47:70 | predicate | Foo.qll:44:9:44:56 | ClasslessPredicate edge | From dc354f8fbf6ae87b48cd768943d7950c514de5cd Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 17 Oct 2021 11:59:51 +0200 Subject: [PATCH 10/17] add `noResolvePredicateExpr` to the list of empty consistency predicates --- ql/src/queries/diagnostics/EmptyConsistencies.ql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ql/src/queries/diagnostics/EmptyConsistencies.ql b/ql/src/queries/diagnostics/EmptyConsistencies.ql index e0e7a3ccf92..61c1f6439fe 100644 --- a/ql/src/queries/diagnostics/EmptyConsistencies.ql +++ b/ql/src/queries/diagnostics/EmptyConsistencies.ql @@ -19,6 +19,8 @@ from AstNode node, string msg where PredConsistency::noResolveCall(node) and msg = "PredConsistency::noResolveCall" or + PredConsistency::noResolvePredicateExpr(node) and msg = "PredConsistency::noResolvePredicateExpr" + or TypeConsistency::noResolve(node) and msg = "TypeConsistency::noResolve" or TypeConsistency::exprNoType(node) and msg = "TypeConsistency::exprNoType" From 9127fa533a46c297cb9279f25fab4a5b03c6ed20 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 17 Oct 2021 12:53:49 +0200 Subject: [PATCH 11/17] fix predicate resolution --- ql/src/codeql_ql/ast/internal/Predicate.qll | 48 ++++++++++++--------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/src/codeql_ql/ast/internal/Predicate.qll index fa0f55bf893..3fa505e462f 100644 --- a/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -6,27 +6,33 @@ private import codeql_ql.ast.internal.AstNodes private predicate definesPredicate( FileOrModule m, string name, int arity, Predicate p, boolean public ) { - m = getEnclosingModule(p) and - name = p.getName() and - public = getPublicBool(p) and - arity = p.getArity() - or - // import X - exists(Import imp, FileOrModule m0 | - m = getEnclosingModule(imp) and - m0 = imp.getResolvedModule() and - not exists(imp.importedAs()) and - definesPredicate(m0, name, arity, p, true) and - public = getPublicBool(imp) - ) - or - // predicate X = Y - exists(ClasslessPredicate alias | - m = getEnclosingModule(alias) and - name = alias.getName() and - resolvePredicateExpr(alias.getAlias(), p) and - public = getPublicBool(alias) and - arity = alias.getArity() + ( + p instanceof NewTypeBranch or + p instanceof ClasslessPredicate + ) and + ( + m = getEnclosingModule(p) and + name = p.getName() and + public = getPublicBool(p) and + arity = p.getArity() + or + // import X + exists(Import imp, FileOrModule m0 | + m = getEnclosingModule(imp) and + m0 = imp.getResolvedModule() and + not exists(imp.importedAs()) and + definesPredicate(m0, name, arity, p, true) and + public = getPublicBool(imp) + ) + or + // predicate X = Y + exists(ClasslessPredicate alias | + m = getEnclosingModule(alias) and + name = alias.getName() and + resolvePredicateExpr(alias.getAlias(), p) and + public = getPublicBool(alias) and + arity = alias.getArity() + ) ) } From 18eede5597c4c46a50320ad16c9b4f21dcba9699 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 17 Oct 2021 13:38:40 +0200 Subject: [PATCH 12/17] fix some inconsistencies related to primitive types --- ql/src/codeql_ql/ast/Ast.qll | 32 ++++++++++++------- ql/src/codeql_ql/ast/internal/Type.qll | 12 +++++++ .../queries/diagnostics/EmptyConsistencies.ql | 7 ++-- ql/test/type/Test.qll | 3 ++ ql/test/type/type.expected | 4 +++ 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index e11c43a569a..25b174dd6ac 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -1551,7 +1551,7 @@ class ExprAggregate extends TExprAggregate, Aggregate { override Type getType() { exists(PrimitiveType prim | prim = result | - kind.regexpMatch("(strict)?count|sum|min|max|rank") and + kind.regexpMatch("(strict)?count") and result.getName() = "int" or kind.regexpMatch("(strict)?concat") and @@ -1615,16 +1615,16 @@ class FullAggregate extends TFullAggregate, Aggregate { override Type getType() { exists(PrimitiveType prim | prim = result | - kind.regexpMatch("(strict)?(count|sum|min|max|rank)") and + kind = ["count", "strictcount"] and result.getName() = "int" or kind.regexpMatch("(strict)?concat") and result.getName() = "string" ) or - kind = ["any", "min", "max", "unique"] and + kind = ["any", "min", "max", "unique", "rank", "sum", "strictsum"] and not exists(this.getExpr(_)) and - result = this.getArgument(0).getTypeExpr().getResolvedType() + result = this.getArgument(0).getType() or not kind = ["count", "strictcount"] and result = this.getExpr(0).getType() @@ -1910,11 +1910,18 @@ private Expr exprOfPrimitiveAddType(PrimitiveType t) { result.getType() = getASubTypeOfAddPrimitive(t) } +/** + * Gets a subtype of the given primitive type `prim`. + * This predicate does not consider float to be a supertype of int. + */ private Type getASubTypeOfAddPrimitive(PrimitiveType prim) { result = prim and result.getName() = ["int", "string", "float"] or - result.getASuperType() = getASubTypeOfAddPrimitive(prim) + exists(Type superType | superType = getASubTypeOfAddPrimitive(prim) | + result.getASuperType() = superType and + not (result.getName() = "int" and superType.getName() = "float") + ) } /** @@ -1957,15 +1964,18 @@ class MulDivModExpr extends TMulDivModExpr, BinOpExpr { this.getLeftOperand().getType() = result and this.getRightOperand().getType() = result or - // Both operands are subtypes of `int` - result.getName() = "int" and - result = this.getLeftOperand().getType().getASuperType*() and - result = this.getRightOperand().getType().getASuperType*() + // Both operands are subtypes of `int`/`float` + result.getName() = ["int", "float"] and + exprOfPrimitiveAddType(result) = this.getLeftOperand() and + exprOfPrimitiveAddType(result) = this.getRightOperand() or // Coercion from `int` to `float` exists(PrimitiveType i | result.getName() = "float" and i.getName() = "int" | - this.getAnOperand().getType() = result and - this.getAnOperand().getType().getASuperType*() = i + this.getLeftOperand() = exprOfPrimitiveAddType(result) and + this.getRightOperand() = exprOfPrimitiveAddType(i) + or + this.getRightOperand() = exprOfPrimitiveAddType(result) and + this.getLeftOperand() = exprOfPrimitiveAddType(i) ) } diff --git a/ql/src/codeql_ql/ast/internal/Type.qll b/ql/src/codeql_ql/ast/internal/Type.qll index bfd84ea9208..cbc76d56ecc 100644 --- a/ql/src/codeql_ql/ast/internal/Type.qll +++ b/ql/src/codeql_ql/ast/internal/Type.qll @@ -340,6 +340,12 @@ module TyConsistency { resolveTypeExpr(te, t) } + query predicate multiplePrimitives(TypeExpr te, int c, PrimitiveType t) { + c = strictcount(PrimitiveType t0 | resolveTypeExpr(te, t0)) and + c > 1 and + resolveTypeExpr(te, t) + } + query predicate varDefNoType(VarDef def) { not exists(def.getType()) and not def.getLocation() @@ -360,4 +366,10 @@ module TyConsistency { .getAbsolutePath() .regexpMatch(".*/(test|examples|ql-training|recorded-call-graph-metrics)/.*") } + + query predicate multiplePrimitivesExpr(Expr e, int c, PrimitiveType t) { + c = strictcount(PrimitiveType t0 | t0 = e.getType()) and + c > 1 and + t = e.getType() + } } diff --git a/ql/src/queries/diagnostics/EmptyConsistencies.ql b/ql/src/queries/diagnostics/EmptyConsistencies.ql index 61c1f6439fe..884ae0e60a0 100644 --- a/ql/src/queries/diagnostics/EmptyConsistencies.ql +++ b/ql/src/queries/diagnostics/EmptyConsistencies.ql @@ -21,12 +21,15 @@ where or PredConsistency::noResolvePredicateExpr(node) and msg = "PredConsistency::noResolvePredicateExpr" or - TypeConsistency::noResolve(node) and msg = "TypeConsistency::noResolve" - or TypeConsistency::exprNoType(node) and msg = "TypeConsistency::exprNoType" or TypeConsistency::varDefNoType(node) and msg = "TypeConsistency::varDefNoType" or + TypeConsistency::multiplePrimitives(node, _, _) and msg = "TypeConsistency::multiplePrimitives" + or + TypeConsistency::multiplePrimitivesExpr(node, _, _) and + msg = "TypeConsistency::multiplePrimitivesExpr" + or //or // has 1 result, but the CodeQL compiler also can't figure out that one. I suppoed the file is never imported. //TypeConsistency::noResolve(node) and msg = "TypeConsistency::noResolve" //or // has 1 result, but the CodeQL compiler also can't figure out that one. Same file as above. diff --git a/ql/test/type/Test.qll b/ql/test/type/Test.qll index acb2302572b..37f791b2c17 100644 --- a/ql/test/type/Test.qll +++ b/ql/test/type/Test.qll @@ -25,3 +25,6 @@ class Sub extends Base { int bar2() { result = super.foo() } } + +bindingset[result, a, b] +int integerMul(int a, int b) { result = a * b } diff --git a/ql/test/type/type.expected b/ql/test/type/type.expected index 29f6076374f..8b8a99553fd 100644 --- a/ql/test/type/type.expected +++ b/ql/test/type/type.expected @@ -52,3 +52,7 @@ | Test.qll:26:16:26:21 | result | file://:0:0:0:0 | int | | Test.qll:26:25:26:29 | Super | Test.qll:15:1:19:1 | Base | | Test.qll:26:25:26:35 | MemberCall | file://:0:0:0:0 | int | +| Test.qll:30:32:30:37 | result | file://:0:0:0:0 | int | +| Test.qll:30:41:30:41 | a | file://:0:0:0:0 | int | +| Test.qll:30:41:30:45 | MulExpr | file://:0:0:0:0 | int | +| Test.qll:30:45:30:45 | b | file://:0:0:0:0 | int | From 09f60f20fc3ff17829dafcd69fb27e0e39cdfb50 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 17 Oct 2021 14:00:26 +0200 Subject: [PATCH 13/17] fix code-scanning alert --- ql/test/type/Test.qll | 4 ++-- ql/test/type/type.expected | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ql/test/type/Test.qll b/ql/test/type/Test.qll index 37f791b2c17..2ff331cef04 100644 --- a/ql/test/type/Test.qll +++ b/ql/test/type/Test.qll @@ -13,13 +13,13 @@ string conc(Strings a, Strings b) { result = a + b } float floats(Floats a, Floats b) { result = a + b } class Base extends string { - Base() { this = ["foo"] } + Base() { this = "foo" } int foo() { result = 1 } } class Sub extends Base { - Sub() { this = ["bar"] } + Sub() { this = "bar" } int bar() { result = Base.super.foo() } diff --git a/ql/test/type/type.expected b/ql/test/type/type.expected index 8b8a99553fd..773a9244a22 100644 --- a/ql/test/type/type.expected +++ b/ql/test/type/type.expected @@ -37,15 +37,13 @@ | Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base | | Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base.Base | | Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base.extends | -| Test.qll:16:19:16:25 | Set | file://:0:0:0:0 | string | -| Test.qll:16:20:16:24 | String | file://:0:0:0:0 | string | +| Test.qll:16:19:16:23 | String | file://:0:0:0:0 | string | | Test.qll:18:15:18:20 | result | file://:0:0:0:0 | int | | Test.qll:18:24:18:24 | Integer | file://:0:0:0:0 | int | | Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub | | Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub.Sub | | Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub.extends | -| Test.qll:22:18:22:24 | Set | file://:0:0:0:0 | string | -| Test.qll:22:19:22:23 | String | file://:0:0:0:0 | string | +| Test.qll:22:18:22:22 | String | file://:0:0:0:0 | string | | Test.qll:24:15:24:20 | result | file://:0:0:0:0 | int | | Test.qll:24:24:24:33 | Super | Test.qll:15:1:19:1 | Base | | Test.qll:24:24:24:39 | MemberCall | file://:0:0:0:0 | int | From ade206184c24379c6ae0cb693245f916a192e3bd Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 17 Oct 2021 14:44:41 +0200 Subject: [PATCH 14/17] fix broken import in unused file --- ql/src/codeql_ql/printAstGenerated.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/src/codeql_ql/printAstGenerated.qll b/ql/src/codeql_ql/printAstGenerated.qll index e8029419713..caee0ab809a 100644 --- a/ql/src/codeql_ql/printAstGenerated.qll +++ b/ql/src/codeql_ql/printAstGenerated.qll @@ -8,7 +8,7 @@ * to hold for only the AST nodes you wish to view. */ -import ast.internal.TreeSitter::Generated +import ast.internal.TreeSitter::QL private import codeql.Locations /** From 9a73c363899e54a693f3384492f137599ff89e85 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 17 Oct 2021 14:51:00 +0200 Subject: [PATCH 15/17] add support for libraryPathDependencies in qlpacks --- ql/src/codeql_ql/ast/Ast.qll | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index 25b174dd6ac..1e7bf91aa3c 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -2309,6 +2309,8 @@ module YAML { ) } + YAMLListItem getListItem() { toQL(result).getParent() = yamle } + /** Gets the value of this YAML entry. */ YAMLValue getValue() { exists(QL::YamlKeyvaluepair pair | @@ -2421,7 +2423,7 @@ module YAML { deps.getLocation().getFile() = file and entry.getLocation().getFile() = file | deps.isRoot() and - deps.getKey().getQualifiedName() = "dependencies" and + deps.getKey().getQualifiedName() = ["dependencies", "libraryPathDependencies"] and entry.getLocation().getStartLine() = 1 + deps.getLocation().getStartLine() and entry.getLocation().getStartColumn() > deps.getLocation().getStartColumn() ) @@ -2436,8 +2438,11 @@ module YAML { predicate hasDependency(string name, string version) { exists(YAMLEntry entry | this.isADependency(entry) | - entry.getKey().getQualifiedName() = name and + entry.getKey().getQualifiedName().trim() = name and entry.getValue().getValue() = version + or + name = entry.getListItem().getValue().getValue().trim() and + version = "\"*\"" ) } @@ -2459,7 +2464,7 @@ module YAML { */ QLPack getADependency() { exists(string name | this.hasDependency(name, _) | - result.getName().replaceAll("-", "/") = name + result.getName().replaceAll("-", "/") = name.replaceAll("-", "/") ) } From 509e77bbdbbfe7353e59580a57e4a74f63cdaf3b Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 17 Oct 2021 15:09:30 +0200 Subject: [PATCH 16/17] add nonTotalGetParent to the list of empty consistency queries --- ql/consistency-queries/AstConsistency.ql | 11 +---------- ql/src/codeql_ql/ast/internal/AstNodes.qll | 13 +++++++++++++ ql/src/queries/diagnostics/EmptyConsistencies.ql | 3 +++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ql/consistency-queries/AstConsistency.ql b/ql/consistency-queries/AstConsistency.ql index 773b6c8b898..378c9554f66 100644 --- a/ql/consistency-queries/AstConsistency.ql +++ b/ql/consistency-queries/AstConsistency.ql @@ -1,10 +1 @@ -import ql -private import codeql_ql.ast.internal.AstNodes as AstNodes - -query AstNode nonTotalGetParent() { - exists(AstNodes::toQL(result).getParent()) and - not exists(result.getParent()) and - not result.getLocation().getStartColumn() = 1 and // startcolumn = 1 <=> top level in file <=> fine to have no parent - not result instanceof YAML::YAMLNode and // parents for YAML doens't work - not (result instanceof QLDoc and result.getLocation().getFile().getExtension() = "dbscheme") // qldoc in dbschemes are not hooked up -} +private import codeql_ql.ast.internal.AstNodes::AstConsistency diff --git a/ql/src/codeql_ql/ast/internal/AstNodes.qll b/ql/src/codeql_ql/ast/internal/AstNodes.qll index 9e5b8cb99ab..d6f1a97bb26 100644 --- a/ql/src/codeql_ql/ast/internal/AstNodes.qll +++ b/ql/src/codeql_ql/ast/internal/AstNodes.qll @@ -209,3 +209,16 @@ class TTypeDeclaration = TClass or TNewType or TNewTypeBranch; class TModuleDeclaration = TClasslessPredicate or TModule or TClass or TNewType; class TVarDef = TVarDecl or TAsExpr; + +module AstConsistency { + import ql + + query predicate nonTotalGetParent(AstNode node) { + exists(toQL(node).getParent()) and + not exists(node.getParent()) and + not node.getLocation().getStartColumn() = 1 and // startcolumn = 1 <=> top level in file <=> fine to have no parent + exists(node.toString()) and // <- there are a few parse errors in "global-data-flow-java-1.ql", this way we filter them out. + not node instanceof YAML::YAMLNode and // parents for YAML doens't work + not (node instanceof QLDoc and node.getLocation().getFile().getExtension() = "dbscheme") // qldoc in dbschemes are not hooked up + } +} diff --git a/ql/src/queries/diagnostics/EmptyConsistencies.ql b/ql/src/queries/diagnostics/EmptyConsistencies.ql index 884ae0e60a0..11ee9ccb4f8 100644 --- a/ql/src/queries/diagnostics/EmptyConsistencies.ql +++ b/ql/src/queries/diagnostics/EmptyConsistencies.ql @@ -14,6 +14,7 @@ import codeql_ql.ast.internal.Type::TyConsistency as TypeConsistency import codeql_ql.ast.internal.Builtins::BuildinsConsistency as BuildinsConsistency import codeql_ql.ast.internal.Module::ModConsistency as ModConsistency import codeql_ql.ast.internal.Variable::VarConsistency as VarConsistency +import codeql_ql.ast.internal.AstNodes::AstConsistency as AstConsistency from AstNode node, string msg where @@ -30,6 +31,8 @@ where TypeConsistency::multiplePrimitivesExpr(node, _, _) and msg = "TypeConsistency::multiplePrimitivesExpr" or + AstConsistency::nonTotalGetParent(node) and msg = "AstConsistency::nonTotalGetParent" + or //or // has 1 result, but the CodeQL compiler also can't figure out that one. I suppoed the file is never imported. //TypeConsistency::noResolve(node) and msg = "TypeConsistency::noResolve" //or // has 1 result, but the CodeQL compiler also can't figure out that one. Same file as above. From 631a503e550d5b5070e3ef80df76ef488394ec1d Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 19 Oct 2021 09:19:31 +0200 Subject: [PATCH 17/17] cleanup --- ql/src/codeql_ql/ast/Ast.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index 1e7bf91aa3c..ed6a8f59f07 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -1758,9 +1758,7 @@ class ThisAccess extends Identifier { /** A use of `super`. */ class Super extends TSuper, Expr { - QL::SuperRef ref; - - Super() { this = TSuper(ref) } + Super() { this = TSuper(_) } override string getAPrimaryQlClass() { result = "Super" }