From 8ad05b778deb73895bd12e322b3a32020c59219a Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 29 May 2021 08:20:16 +0000 Subject: [PATCH 1/9] add support for boolean literals --- ql/src/codeql_ql/ast/Ast.qll | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index dc378cf190e..fc96dabb75c 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -990,6 +990,21 @@ class Float extends Literal { float getValue() { result = lit.getChild().(Generated::Float).getValue().toFloat() } } +/** A boolean literal */ +class Boolean extends Literal { + Generated::Bool bool; + + Boolean() { lit.getChild() = bool } + + /** Holds if the value is `true` */ + predicate isTrue() { bool.getChild() instanceof Generated::True } + + /** Holds if the value is `false` */ + predicate isFalse() { bool.getChild() instanceof Generated::False } + + override string getAPrimaryQlClass() { result = "Boolean" } +} + /** A comparison symbol, such as `"<"` or `"="`. */ class ComparisonSymbol extends string { ComparisonSymbol() { From fb50ba407da70d1bb33c56c551c8dfde4e4234a2 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 29 May 2021 08:25:05 +0000 Subject: [PATCH 2/9] add test for boolean literals in the ast --- ql/test/printAst/Foo.qll | 2 + ql/test/printAst/printAst.expected | 210 ++++++++++++++++------------- 2 files changed, 117 insertions(+), 95 deletions(-) diff --git a/ql/test/printAst/Foo.qll b/ql/test/printAst/Foo.qll index de9ecbe1133..17e4a4d636d 100644 --- a/ql/test/printAst/Foo.qll +++ b/ql/test/printAst/Foo.qll @@ -22,4 +22,6 @@ predicate calls(Foo f) { f = any(Foo f) or 2 = 1 + (2 + (3 + 4)) + or + true = false } diff --git a/ql/test/printAst/printAst.expected b/ql/test/printAst/printAst.expected index ddff8033d5a..1a69604ae1a 100644 --- a/ql/test/printAst/printAst.expected +++ b/ql/test/printAst/printAst.expected @@ -1,8 +1,8 @@ nodes | Foo.qll:1:1:1:17 | Import | semmle.label | [Import] Import | | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | -| Foo.qll:1:1:25:2 | TopLevel | semmle.label | [TopLevel] TopLevel | -| Foo.qll:1:1:25:2 | TopLevel | semmle.order | 1 | +| Foo.qll:1:1:27:2 | TopLevel | semmle.label | [TopLevel] TopLevel | +| Foo.qll:1:1:27:2 | TopLevel | semmle.order | 1 | | Foo.qll:3:1:7:1 | Foo | semmle.label | [Class] Foo | | Foo.qll:3:1:7:1 | Foo | semmle.order | 3 | | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | @@ -65,8 +65,8 @@ nodes | Foo.qll:10:69:10:73 | inner | semmle.order | 32 | | Foo.qll:10:69:10:84 | MemberCall | semmle.label | [MemberCall] MemberCall | | Foo.qll:10:69:10:84 | MemberCall | semmle.order | 32 | -| Foo.qll:13:1:25:1 | calls | semmle.label | [ClasslessPredicate] calls | -| Foo.qll:13:1:25:1 | calls | semmle.order | 34 | +| Foo.qll:13:1:27:1 | calls | semmle.label | [ClasslessPredicate] calls | +| Foo.qll:13:1:27:1 | calls | semmle.order | 34 | | Foo.qll:13:17:13:19 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 35 | | Foo.qll:13:17:13:21 | f | semmle.label | [VarDecl] f | @@ -83,95 +83,105 @@ nodes | Foo.qll:14:3:22:16 | Disjunction | semmle.order | 37 | | Foo.qll:14:3:24:23 | Disjunction | semmle.label | [Disjunction] Disjunction | | Foo.qll:14:3:24:23 | Disjunction | semmle.order | 37 | +| Foo.qll:14:3:26:14 | Disjunction | semmle.label | [Disjunction] Disjunction | +| Foo.qll:14:3:26:14 | Disjunction | semmle.order | 37 | | Foo.qll:14:9:14:9 | f | semmle.label | [VarAccess] f | -| Foo.qll:14:9:14:9 | f | semmle.order | 43 | +| Foo.qll:14:9:14:9 | f | semmle.order | 44 | | Foo.qll:16:3:16:7 | String | semmle.label | [String] String | -| Foo.qll:16:3:16:7 | String | semmle.order | 44 | +| Foo.qll:16:3:16:7 | String | semmle.order | 45 | | Foo.qll:16:3:16:29 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | -| Foo.qll:16:3:16:29 | ComparisonFormula | semmle.order | 44 | +| Foo.qll:16:3:16:29 | ComparisonFormula | semmle.order | 45 | | Foo.qll:16:9:16:9 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp | -| Foo.qll:16:9:16:9 | ComparisonOp | semmle.order | 46 | +| Foo.qll:16:9:16:9 | ComparisonOp | semmle.order | 47 | | Foo.qll:16:11:16:11 | f | semmle.label | [VarAccess] f | -| Foo.qll:16:11:16:11 | f | semmle.order | 47 | +| Foo.qll:16:11:16:11 | f | semmle.order | 48 | | Foo.qll:16:11:16:29 | MemberCall | semmle.label | [MemberCall] MemberCall | -| Foo.qll:16:11:16:29 | MemberCall | semmle.order | 47 | +| Foo.qll:16:11:16:29 | MemberCall | semmle.order | 48 | | Foo.qll:16:22:16:22 | Integer | semmle.label | [Integer] Integer | -| Foo.qll:16:22:16:22 | Integer | semmle.order | 49 | +| Foo.qll:16:22:16:22 | Integer | semmle.order | 50 | | Foo.qll:16:25:16:25 | Integer | semmle.label | [Integer] Integer | -| Foo.qll:16:25:16:25 | Integer | semmle.order | 50 | +| Foo.qll:16:25:16:25 | Integer | semmle.order | 51 | | Foo.qll:16:28:16:28 | Integer | semmle.label | [Integer] Integer | -| Foo.qll:16:28:16:28 | Integer | semmle.order | 51 | +| Foo.qll:16:28:16:28 | Integer | semmle.order | 52 | | Foo.qll:18:3:18:3 | f | semmle.label | [VarAccess] f | -| Foo.qll:18:3:18:3 | f | semmle.order | 52 | +| Foo.qll:18:3:18:3 | f | semmle.order | 53 | | Foo.qll:18:3:18:9 | InlineCast | semmle.label | [InlineCast] InlineCast | -| Foo.qll:18:3:18:9 | InlineCast | semmle.order | 52 | +| Foo.qll:18:3:18:9 | InlineCast | semmle.order | 53 | | Foo.qll:18:3:18:20 | MemberCall | semmle.label | [MemberCall] MemberCall | -| Foo.qll:18:3:18:20 | MemberCall | semmle.order | 52 | +| Foo.qll:18:3:18:20 | MemberCall | semmle.order | 53 | | Foo.qll:18:3:18:28 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | -| Foo.qll:18:3:18:28 | ComparisonFormula | semmle.order | 52 | +| Foo.qll:18:3:18:28 | ComparisonFormula | semmle.order | 53 | | Foo.qll:18:6:18:8 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | -| Foo.qll:18:6:18:8 | TypeExpr | semmle.order | 56 | +| Foo.qll:18:6:18:8 | TypeExpr | semmle.order | 57 | | Foo.qll:18:22:18:22 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp | -| Foo.qll:18:22:18:22 | ComparisonOp | semmle.order | 57 | +| Foo.qll:18:22:18:22 | ComparisonOp | semmle.order | 58 | | Foo.qll:18:24:18:28 | String | semmle.label | [String] String | -| Foo.qll:18:24:18:28 | String | semmle.order | 58 | +| Foo.qll:18:24:18:28 | String | semmle.order | 59 | | Foo.qll:20:3:20:3 | f | semmle.label | [VarAccess] f | -| Foo.qll:20:3:20:3 | f | semmle.order | 59 | +| Foo.qll:20:3:20:3 | f | semmle.order | 60 | | Foo.qll:20:3:20:9 | InlineCast | semmle.label | [InlineCast] InlineCast | -| Foo.qll:20:3:20:9 | InlineCast | semmle.order | 59 | +| Foo.qll:20:3:20:9 | InlineCast | semmle.order | 60 | | Foo.qll:20:3:20:13 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | -| Foo.qll:20:3:20:13 | ComparisonFormula | semmle.order | 59 | +| Foo.qll:20:3:20:13 | ComparisonFormula | semmle.order | 60 | | Foo.qll:20:6:20:8 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | -| Foo.qll:20:6:20:8 | TypeExpr | semmle.order | 62 | +| Foo.qll:20:6:20:8 | TypeExpr | semmle.order | 63 | | Foo.qll:20:11:20:11 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp | -| Foo.qll:20:11:20:11 | ComparisonOp | semmle.order | 63 | +| Foo.qll:20:11:20:11 | ComparisonOp | semmle.order | 64 | | Foo.qll:20:13:20:13 | f | semmle.label | [VarAccess] f | -| Foo.qll:20:13:20:13 | f | semmle.order | 64 | +| Foo.qll:20:13:20:13 | f | semmle.order | 65 | | Foo.qll:22:3:22:3 | f | semmle.label | [VarAccess] f | -| Foo.qll:22:3:22:3 | f | semmle.order | 65 | +| Foo.qll:22:3:22:3 | f | semmle.order | 66 | | Foo.qll:22:3:22:16 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | -| Foo.qll:22:3:22:16 | ComparisonFormula | semmle.order | 65 | +| Foo.qll:22:3:22:16 | ComparisonFormula | semmle.order | 66 | | Foo.qll:22:5:22:5 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp | -| Foo.qll:22:5:22:5 | ComparisonOp | semmle.order | 67 | +| Foo.qll:22:5:22:5 | ComparisonOp | semmle.order | 68 | | Foo.qll:22:7:22:16 | Aggregate[any] | semmle.label | [Aggregate[any]] Aggregate[any] | -| Foo.qll:22:7:22:16 | Aggregate[any] | semmle.order | 68 | +| Foo.qll:22:7:22:16 | Aggregate[any] | semmle.order | 69 | | Foo.qll:22:11:22:13 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | -| Foo.qll:22:11:22:13 | TypeExpr | semmle.order | 69 | +| Foo.qll:22:11:22:13 | TypeExpr | semmle.order | 70 | | Foo.qll:22:11:22:15 | f | semmle.label | [VarDecl] f | -| Foo.qll:22:11:22:15 | f | semmle.order | 69 | +| Foo.qll:22:11:22:15 | f | semmle.order | 70 | | Foo.qll:24:3:24:3 | Integer | semmle.label | [Integer] Integer | -| Foo.qll:24:3:24:3 | Integer | semmle.order | 71 | +| Foo.qll:24:3:24:3 | Integer | semmle.order | 72 | | Foo.qll:24:3:24:23 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | -| Foo.qll:24:3:24:23 | ComparisonFormula | semmle.order | 71 | +| Foo.qll:24:3:24:23 | ComparisonFormula | semmle.order | 72 | | Foo.qll:24:5:24:5 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp | -| Foo.qll:24:5:24:5 | ComparisonOp | semmle.order | 73 | +| Foo.qll:24:5:24:5 | ComparisonOp | semmle.order | 74 | | Foo.qll:24:7:24:7 | Integer | semmle.label | [Integer] Integer | -| Foo.qll:24:7:24:7 | Integer | semmle.order | 74 | +| Foo.qll:24:7:24:7 | Integer | semmle.order | 75 | | Foo.qll:24:7:24:23 | AddExpr | semmle.label | [AddExpr] AddExpr | -| Foo.qll:24:7:24:23 | AddExpr | semmle.order | 74 | +| Foo.qll:24:7:24:23 | AddExpr | semmle.order | 75 | | Foo.qll:24:12:24:12 | Integer | semmle.label | [Integer] Integer | -| Foo.qll:24:12:24:12 | Integer | semmle.order | 76 | +| Foo.qll:24:12:24:12 | Integer | semmle.order | 77 | | Foo.qll:24:12:24:22 | AddExpr | semmle.label | [AddExpr] AddExpr | -| Foo.qll:24:12:24:22 | AddExpr | semmle.order | 76 | +| Foo.qll:24:12:24:22 | AddExpr | semmle.order | 77 | | Foo.qll:24:17:24:17 | Integer | semmle.label | [Integer] Integer | -| Foo.qll:24:17:24:17 | Integer | semmle.order | 78 | +| Foo.qll:24:17:24:17 | Integer | semmle.order | 79 | | Foo.qll:24:17:24:21 | AddExpr | semmle.label | [AddExpr] AddExpr | -| Foo.qll:24:17:24:21 | AddExpr | semmle.order | 78 | +| Foo.qll:24:17:24:21 | AddExpr | semmle.order | 79 | | Foo.qll:24:21:24:21 | Integer | semmle.label | [Integer] Integer | -| Foo.qll:24:21:24:21 | Integer | semmle.order | 80 | +| Foo.qll:24:21:24:21 | Integer | semmle.order | 81 | +| Foo.qll:26:3:26:6 | Boolean | semmle.label | [Boolean] Boolean | +| Foo.qll:26:3:26:6 | Boolean | semmle.order | 82 | +| Foo.qll:26:3:26:14 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | +| Foo.qll:26:3:26:14 | ComparisonFormula | semmle.order | 82 | +| Foo.qll:26:8:26:8 | ComparisonOp | semmle.label | [ComparisonOp] ComparisonOp | +| Foo.qll:26:8:26:8 | ComparisonOp | semmle.order | 84 | +| Foo.qll:26:10:26:14 | Boolean | semmle.label | [Boolean] Boolean | +| Foo.qll:26:10:26:14 | Boolean | semmle.order | 85 | | printAst.ql:1:1:1:28 | Import | semmle.label | [Import] Import | -| printAst.ql:1:1:1:28 | Import | semmle.order | 81 | +| printAst.ql:1:1:1:28 | Import | semmle.order | 86 | | printAst.ql:1:1:1:29 | TopLevel | semmle.label | [TopLevel] TopLevel | -| printAst.ql:1:1:1:29 | TopLevel | semmle.order | 81 | +| printAst.ql:1:1:1:29 | TopLevel | semmle.order | 86 | edges -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAMember() | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:3:1:7:1 | Foo | semmle.label | getAMember() | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:3:1:7:1 | Foo | semmle.order | 3 | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:9:7:11:1 | foo | semmle.label | getAMember() | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:9:7:11:1 | foo | semmle.order | 16 | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:13:1:25:1 | calls | semmle.label | getAMember() | -| Foo.qll:1:1:25:2 | TopLevel | Foo.qll:13:1:25:1 | calls | semmle.order | 34 | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAMember() | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:1:7:1 | Foo | semmle.label | getAMember() | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:1:7:1 | Foo | semmle.order | 3 | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:7:11:1 | foo | semmle.label | getAMember() | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:7:11:1 | foo | semmle.order | 16 | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:1:27:1 | calls | semmle.label | getAMember() | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:1:27:1 | calls | semmle.order | 34 | | Foo.qll:3:1:7:1 | Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() | | Foo.qll:3:1:7:1 | Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 | | Foo.qll:3:1:7:1 | Foo | Foo.qll:4:3:4:17 | CharPred | semmle.label | getCharPred() | @@ -230,99 +240,109 @@ edges | Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:46:10:50 | String | semmle.order | 30 | | Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.label | getBase() | | Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.order | 32 | -| Foo.qll:13:1:25:1 | calls | Foo.qll:13:17:13:21 | f | semmle.label | getParameter(_) | -| Foo.qll:13:1:25:1 | calls | Foo.qll:13:17:13:21 | f | semmle.order | 35 | -| Foo.qll:13:1:25:1 | calls | Foo.qll:14:3:24:23 | Disjunction | semmle.label | getBody() | -| Foo.qll:13:1:25:1 | calls | Foo.qll:14:3:24:23 | Disjunction | semmle.order | 37 | +| Foo.qll:13:1:27:1 | calls | Foo.qll:13:17:13:21 | f | semmle.label | getParameter(_) | +| Foo.qll:13:1:27:1 | calls | Foo.qll:13:17:13:21 | f | semmle.order | 35 | +| Foo.qll:13:1:27:1 | calls | Foo.qll:14:3:26:14 | Disjunction | semmle.label | getBody() | +| Foo.qll:13:1:27:1 | calls | Foo.qll:14:3:26:14 | Disjunction | semmle.order | 37 | | Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.label | getTypeExpr() | | Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 35 | | Foo.qll:14:3:14:10 | PredicateCall | Foo.qll:14:9:14:9 | f | semmle.label | getArgument(_) | -| Foo.qll:14:3:14:10 | PredicateCall | Foo.qll:14:9:14:9 | f | semmle.order | 43 | +| Foo.qll:14:3:14:10 | PredicateCall | Foo.qll:14:9:14:9 | f | semmle.order | 44 | | Foo.qll:14:3:16:29 | Disjunction | Foo.qll:14:3:14:10 | PredicateCall | semmle.label | getAnOperand() | | Foo.qll:14:3:16:29 | Disjunction | Foo.qll:14:3:14:10 | PredicateCall | semmle.order | 37 | | Foo.qll:14:3:16:29 | Disjunction | Foo.qll:16:3:16:29 | ComparisonFormula | semmle.label | getAnOperand() | -| Foo.qll:14:3:16:29 | Disjunction | Foo.qll:16:3:16:29 | ComparisonFormula | semmle.order | 44 | +| Foo.qll:14:3:16:29 | Disjunction | Foo.qll:16:3:16:29 | ComparisonFormula | semmle.order | 45 | | Foo.qll:14:3:18:28 | Disjunction | Foo.qll:14:3:16:29 | Disjunction | semmle.label | getAnOperand() | | Foo.qll:14:3:18:28 | Disjunction | Foo.qll:14:3:16:29 | Disjunction | semmle.order | 37 | | Foo.qll:14:3:18:28 | Disjunction | Foo.qll:18:3:18:28 | ComparisonFormula | semmle.label | getAnOperand() | -| Foo.qll:14:3:18:28 | Disjunction | Foo.qll:18:3:18:28 | ComparisonFormula | semmle.order | 52 | +| Foo.qll:14:3:18:28 | Disjunction | Foo.qll:18:3:18:28 | ComparisonFormula | semmle.order | 53 | | Foo.qll:14:3:20:13 | Disjunction | Foo.qll:14:3:18:28 | Disjunction | semmle.label | getAnOperand() | | Foo.qll:14:3:20:13 | Disjunction | Foo.qll:14:3:18:28 | Disjunction | semmle.order | 37 | | Foo.qll:14:3:20:13 | Disjunction | Foo.qll:20:3:20:13 | ComparisonFormula | semmle.label | getAnOperand() | -| Foo.qll:14:3:20:13 | Disjunction | Foo.qll:20:3:20:13 | ComparisonFormula | semmle.order | 59 | +| Foo.qll:14:3:20:13 | Disjunction | Foo.qll:20:3:20:13 | ComparisonFormula | semmle.order | 60 | | Foo.qll:14:3:22:16 | Disjunction | Foo.qll:14:3:20:13 | Disjunction | semmle.label | getAnOperand() | | Foo.qll:14:3:22:16 | Disjunction | Foo.qll:14:3:20:13 | Disjunction | semmle.order | 37 | | Foo.qll:14:3:22:16 | Disjunction | Foo.qll:22:3:22:16 | ComparisonFormula | semmle.label | getAnOperand() | -| Foo.qll:14:3:22:16 | Disjunction | Foo.qll:22:3:22:16 | ComparisonFormula | semmle.order | 65 | +| Foo.qll:14:3:22:16 | Disjunction | Foo.qll:22:3:22:16 | ComparisonFormula | semmle.order | 66 | | Foo.qll:14:3:24:23 | Disjunction | Foo.qll:14:3:22:16 | Disjunction | semmle.label | getAnOperand() | | Foo.qll:14:3:24:23 | Disjunction | Foo.qll:14:3:22:16 | Disjunction | semmle.order | 37 | | Foo.qll:14:3:24:23 | Disjunction | Foo.qll:24:3:24:23 | ComparisonFormula | semmle.label | getAnOperand() | -| Foo.qll:14:3:24:23 | Disjunction | Foo.qll:24:3:24:23 | ComparisonFormula | semmle.order | 71 | +| Foo.qll:14:3:24:23 | Disjunction | Foo.qll:24:3:24:23 | ComparisonFormula | semmle.order | 72 | +| Foo.qll:14:3:26:14 | Disjunction | Foo.qll:14:3:24:23 | Disjunction | semmle.label | getAnOperand() | +| Foo.qll:14:3:26:14 | Disjunction | Foo.qll:14:3:24:23 | Disjunction | semmle.order | 37 | +| Foo.qll:14:3:26:14 | Disjunction | Foo.qll:26:3:26:14 | ComparisonFormula | semmle.label | getAnOperand() | +| Foo.qll:14:3:26:14 | Disjunction | Foo.qll:26:3:26:14 | ComparisonFormula | semmle.order | 82 | | Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:3:16:7 | String | semmle.label | getLeftOperand() | -| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:3:16:7 | String | semmle.order | 44 | +| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:3:16:7 | String | semmle.order | 45 | | Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:9:16:9 | ComparisonOp | semmle.label | getOperator() | -| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:9:16:9 | ComparisonOp | semmle.order | 46 | +| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:9:16:9 | ComparisonOp | semmle.order | 47 | | Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:11:16:29 | MemberCall | semmle.label | getRightOperand() | -| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:11:16:29 | MemberCall | semmle.order | 47 | +| Foo.qll:16:3:16:29 | ComparisonFormula | Foo.qll:16:11:16:29 | MemberCall | semmle.order | 48 | | Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:11:16:11 | f | semmle.label | getBase() | -| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:11:16:11 | f | semmle.order | 47 | +| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:11:16:11 | f | semmle.order | 48 | | Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:22:16:22 | Integer | semmle.label | getArgument(_) | -| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:22:16:22 | Integer | semmle.order | 49 | +| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:22:16:22 | Integer | semmle.order | 50 | | Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:25:16:25 | Integer | semmle.label | getArgument(_) | -| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:25:16:25 | Integer | semmle.order | 50 | +| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:25:16:25 | Integer | semmle.order | 51 | | Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:28:16:28 | Integer | semmle.label | getArgument(_) | -| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:28:16:28 | Integer | semmle.order | 51 | +| Foo.qll:16:11:16:29 | MemberCall | Foo.qll:16:28:16:28 | Integer | semmle.order | 52 | | Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:3:18:3 | f | semmle.label | getBase() | -| Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:3:18:3 | f | semmle.order | 52 | +| Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:3:18:3 | f | semmle.order | 53 | | Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:6:18:8 | TypeExpr | semmle.label | getTypeExpr() | -| Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:6:18:8 | TypeExpr | semmle.order | 56 | +| Foo.qll:18:3:18:9 | InlineCast | Foo.qll:18:6:18:8 | TypeExpr | semmle.order | 57 | | Foo.qll:18:3:18:20 | MemberCall | Foo.qll:18:3:18:9 | InlineCast | semmle.label | getBase() | -| Foo.qll:18:3:18:20 | MemberCall | Foo.qll:18:3:18:9 | InlineCast | semmle.order | 52 | +| Foo.qll:18:3:18:20 | MemberCall | Foo.qll:18:3:18:9 | InlineCast | semmle.order | 53 | | Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:3:18:20 | MemberCall | semmle.label | getLeftOperand() | -| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:3:18:20 | MemberCall | semmle.order | 52 | +| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:3:18:20 | MemberCall | semmle.order | 53 | | Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:22:18:22 | ComparisonOp | semmle.label | getOperator() | -| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:22:18:22 | ComparisonOp | semmle.order | 57 | +| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:22:18:22 | ComparisonOp | semmle.order | 58 | | Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:24:18:28 | String | semmle.label | getRightOperand() | -| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:24:18:28 | String | semmle.order | 58 | +| Foo.qll:18:3:18:28 | ComparisonFormula | Foo.qll:18:24:18:28 | String | semmle.order | 59 | | Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:3:20:3 | f | semmle.label | getBase() | -| Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:3:20:3 | f | semmle.order | 59 | +| Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:3:20:3 | f | semmle.order | 60 | | Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:6:20:8 | TypeExpr | semmle.label | getTypeExpr() | -| Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:6:20:8 | TypeExpr | semmle.order | 62 | +| Foo.qll:20:3:20:9 | InlineCast | Foo.qll:20:6:20:8 | TypeExpr | semmle.order | 63 | | Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:3:20:9 | InlineCast | semmle.label | getLeftOperand() | -| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:3:20:9 | InlineCast | semmle.order | 59 | +| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:3:20:9 | InlineCast | semmle.order | 60 | | Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:11:20:11 | ComparisonOp | semmle.label | getOperator() | -| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:11:20:11 | ComparisonOp | semmle.order | 63 | +| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:11:20:11 | ComparisonOp | semmle.order | 64 | | Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:13:20:13 | f | semmle.label | getRightOperand() | -| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:13:20:13 | f | semmle.order | 64 | +| Foo.qll:20:3:20:13 | ComparisonFormula | Foo.qll:20:13:20:13 | f | semmle.order | 65 | | Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:3:22:3 | f | semmle.label | getLeftOperand() | -| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:3:22:3 | f | semmle.order | 65 | +| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:3:22:3 | f | semmle.order | 66 | | Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:5:22:5 | ComparisonOp | semmle.label | getOperator() | -| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:5:22:5 | ComparisonOp | semmle.order | 67 | +| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:5:22:5 | ComparisonOp | semmle.order | 68 | | Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:7:22:16 | Aggregate[any] | semmle.label | getRightOperand() | -| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:7:22:16 | Aggregate[any] | semmle.order | 68 | +| Foo.qll:22:3:22:16 | ComparisonFormula | Foo.qll:22:7:22:16 | Aggregate[any] | semmle.order | 69 | | Foo.qll:22:7:22:16 | Aggregate[any] | Foo.qll:22:11:22:15 | f | semmle.label | getArgument(_) | -| Foo.qll:22:7:22:16 | Aggregate[any] | Foo.qll:22:11:22:15 | f | semmle.order | 69 | +| Foo.qll:22:7:22:16 | Aggregate[any] | Foo.qll:22:11:22:15 | f | semmle.order | 70 | | Foo.qll:22:11:22:15 | f | Foo.qll:22:11:22:13 | TypeExpr | semmle.label | getTypeExpr() | -| Foo.qll:22:11:22:15 | f | Foo.qll:22:11:22:13 | TypeExpr | semmle.order | 69 | +| Foo.qll:22:11:22:15 | f | Foo.qll:22:11:22:13 | TypeExpr | semmle.order | 70 | | Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:3:24:3 | Integer | semmle.label | getLeftOperand() | -| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:3:24:3 | Integer | semmle.order | 71 | +| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:3:24:3 | Integer | semmle.order | 72 | | Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:5:24:5 | ComparisonOp | semmle.label | getOperator() | -| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:5:24:5 | ComparisonOp | semmle.order | 73 | +| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:5:24:5 | ComparisonOp | semmle.order | 74 | | Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:7:24:23 | AddExpr | semmle.label | getRightOperand() | -| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:7:24:23 | AddExpr | semmle.order | 74 | +| Foo.qll:24:3:24:23 | ComparisonFormula | Foo.qll:24:7:24:23 | AddExpr | semmle.order | 75 | | Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:7:24:7 | Integer | semmle.label | getLeftOperand() | -| Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:7:24:7 | Integer | semmle.order | 74 | +| Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:7:24:7 | Integer | semmle.order | 75 | | Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:12:24:22 | AddExpr | semmle.label | getRightOperand() | -| Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:12:24:22 | AddExpr | semmle.order | 76 | +| Foo.qll:24:7:24:23 | AddExpr | Foo.qll:24:12:24:22 | AddExpr | semmle.order | 77 | | Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:12:24:12 | Integer | semmle.label | getLeftOperand() | -| Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:12:24:12 | Integer | semmle.order | 76 | +| Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:12:24:12 | Integer | semmle.order | 77 | | Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:17:24:21 | AddExpr | semmle.label | getRightOperand() | -| Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:17:24:21 | AddExpr | semmle.order | 78 | +| Foo.qll:24:12:24:22 | AddExpr | Foo.qll:24:17:24:21 | AddExpr | semmle.order | 79 | | Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:17:24:17 | Integer | semmle.label | getLeftOperand() | -| Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:17:24:17 | Integer | semmle.order | 78 | +| Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:17:24:17 | Integer | semmle.order | 79 | | Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:21:24:21 | Integer | semmle.label | getRightOperand() | -| Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:21:24:21 | Integer | semmle.order | 80 | +| Foo.qll:24:17:24:21 | AddExpr | Foo.qll:24:21:24:21 | Integer | semmle.order | 81 | +| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:3:26:6 | Boolean | semmle.label | getLeftOperand() | +| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:3:26:6 | Boolean | semmle.order | 82 | +| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:8:26:8 | ComparisonOp | semmle.label | getOperator() | +| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:8:26:8 | ComparisonOp | semmle.order | 84 | +| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:10:26:14 | Boolean | semmle.label | getRightOperand() | +| Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:10:26:14 | Boolean | semmle.order | 85 | | printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.label | getAMember() | -| printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.order | 81 | +| printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.order | 86 | graphProperties | semmle.graphKind | tree | From 5dcc161f2da9faadecb955748e0f164eaca85f81 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 29 May 2021 08:25:56 +0000 Subject: [PATCH 3/9] add getEnclosingPredicate utility predicate --- ql/src/codeql_ql/ast/Ast.qll | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index fc96dabb75c..3ef2a87a7f4 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -56,6 +56,15 @@ class AstNode extends TAstNode { * Gets the primary QL class for the ast node. */ string getAPrimaryQlClass() { result = "???" } + + /** + * Gets the predicate that contains this AST node. + */ + pragma[noinline] + Predicate getEnclosingPredicate() { + not this instanceof Predicate and + toGenerated(result) = toGenerated(this).getParent+() + } } /** A toplevel QL program, i.e. a file. */ From 2d86b13d443e770bf173de075b1b930f42337756 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 29 May 2021 08:27:00 +0000 Subject: [PATCH 4/9] add `super` nodes --- ql/src/codeql_ql/ast/Ast.qll | 7 +++++++ ql/src/codeql_ql/ast/internal/AstNodes.qll | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index 3ef2a87a7f4..70d0d8307a2 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -1523,6 +1523,13 @@ class ThisAccess extends Identifier { override string getAPrimaryQlClass() { result = "ThisAccess" } } +/** A use of `super`. */ +class Super extends TSuper, Expr { + Super() { this = TSuper(_) } + + override string getAPrimaryQlClass() { result = "SuperAccess" } +} + /** An access to `result`. */ class ResultAccess extends Identifier { ResultAccess() { any(Generated::Result r).getParent() = id } diff --git a/ql/src/codeql_ql/ast/internal/AstNodes.qll b/ql/src/codeql_ql/ast/internal/AstNodes.qll index d3f5bb6e2e3..c21b77f7a53 100644 --- a/ql/src/codeql_ql/ast/internal/AstNodes.qll +++ b/ql/src/codeql_ql/ast/internal/AstNodes.qll @@ -24,6 +24,7 @@ newtype TAstNode = TExprAggregate(Generated::Aggregate agg) { agg.getChild(_) instanceof Generated::ExprAggregateBody } or + TSuper(Generated::SuperRef sup) or TIdentifier(Generated::Variable var) or TAsExpr(Generated::AsExpr asExpr) { asExpr.getChild(1) instanceof Generated::VarName } or TPredicateCall(Generated::CallOrUnqualAggExpr call) or @@ -63,7 +64,7 @@ class TBinOpExpr = TAddSubExpr or TMulDivModExpr; class TExpr = TBinOpExpr or TLiteral or TAggregate or TExprAggregate or TIdentifier or TInlineCast or TCall or - TUnaryExpr or TExprAnnotation or TDontCare or TRange or TSet or TAsExpr; + TUnaryExpr or TExprAnnotation or TDontCare or TRange or TSet or TAsExpr or TSuper; class TCall = TPredicateCall or TMemberCall or TNoneCall or TAnyCall; @@ -154,6 +155,8 @@ Generated::AstNode toGenerated(AST::AstNode n) { n = TNoneCall(result) or n = TAnyCall(result) + or + n = TSuper(result) } class TPredicate = TCharPred or TClasslessPredicate or TClassPredicate; From 068c57acdd46ebbbe94dd3ecdeff24705dd847fa Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 29 May 2021 08:27:30 +0000 Subject: [PATCH 5/9] add super calls to the callgraph --- ql/src/codeql_ql/ast/internal/Predicate.qll | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/src/codeql_ql/ast/internal/Predicate.qll index 069dd69974c..96e4b5e5dec 100644 --- a/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -79,6 +79,13 @@ private module Cached { t = mc.getBase().getType() and p = t.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments()) ) + or + // super calls + exists(Super sup, ClassType type | + mc.getBase() = sup and + sup.getEnclosingPredicate().(ClassPredicate).getParent().getType() = type and + p = type.getASuperType().getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments()) + ) } cached From c8d03849074e269af449d7728a8cafe45f3b9e38 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 29 May 2021 08:34:09 +0000 Subject: [PATCH 6/9] add callgraph test --- ql/test/callgraph/Foo.qll | 15 +++++++++++++++ ql/test/callgraph/callgraph.expected | 3 +++ ql/test/callgraph/callgraph.ql | 3 +++ 3 files changed, 21 insertions(+) create mode 100644 ql/test/callgraph/Foo.qll create mode 100644 ql/test/callgraph/callgraph.expected create mode 100644 ql/test/callgraph/callgraph.ql diff --git a/ql/test/callgraph/Foo.qll b/ql/test/callgraph/Foo.qll new file mode 100644 index 00000000000..b289193b5e8 --- /dev/null +++ b/ql/test/callgraph/Foo.qll @@ -0,0 +1,15 @@ +import ql + +predicate foo() { none() } + +query predicate test() { foo() } + +class Foo extends AstNode { + predicate bar() { none() } + + predicate baz() { bar() } +} + +class Sub extends Foo { + override predicate baz() { super.baz() } +} diff --git a/ql/test/callgraph/callgraph.expected b/ql/test/callgraph/callgraph.expected new file mode 100644 index 00000000000..497b6e6591e --- /dev/null +++ b/ql/test/callgraph/callgraph.expected @@ -0,0 +1,3 @@ +| Foo.qll:5:26:5:30 | PredicateCall | Foo.qll:3:1:3:26 | foo | +| Foo.qll:10:21:10:25 | PredicateCall | Foo.qll:8:3:8:28 | ClassPredicate | +| Foo.qll:14:30:14:40 | MemberCall | Foo.qll:10:3:10:27 | ClassPredicate | diff --git a/ql/test/callgraph/callgraph.ql b/ql/test/callgraph/callgraph.ql new file mode 100644 index 00000000000..ef5aecf1bbc --- /dev/null +++ b/ql/test/callgraph/callgraph.ql @@ -0,0 +1,3 @@ +import ql + +query AstNode getTarget(Call call) { result = call.getTarget().getDeclaration() } From 8dc39482218878eeefe9db9c81ad0a9b891eb201 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 29 May 2021 17:31:53 +0000 Subject: [PATCH 7/9] support more types on aggregates --- ql/src/codeql_ql/ast/Ast.qll | 32 +++++++++++++++++++++++----- ql/test/callgraph/Foo.qll | 2 ++ ql/test/callgraph/callgraph.expected | 1 + 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index 70d0d8307a2..d682d05f0ee 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -1339,6 +1339,19 @@ class ExprAggregate extends TExprAggregate, Expr { pred = indexedMember("getOrderBy", i) and result = this.getOrderBy(i) ) } + + override Type getType() { + exists(PrimitiveType prim | prim = result | + kind.regexpMatch("(strict)?count|sum|min|max|rank") and + result.getName() = "int" + or + kind.regexpMatch("(strict)?concat") and + result.getName() = "string" + ) + or + not kind = ["count", "strictcount"] and + result = getExpr(0).getType() + } } /** An aggregate expression, such as `count` or `sum`. */ @@ -1389,12 +1402,21 @@ class Aggregate extends TAggregate, Expr { override string getAPrimaryQlClass() { result = "Aggregate[" + kind + "]" } - override PrimitiveType getType() { - kind.regexpMatch("(strict)?count|sum|min|max|rank") and - result.getName() = "int" + override Type getType() { + exists(PrimitiveType prim | prim = result | + kind.regexpMatch("(strict)?count|sum|min|max|rank") and + result.getName() = "int" + or + kind.regexpMatch("(strict)?concat") and + result.getName() = "string" + ) or - kind.regexpMatch("(strict)?concat") and - result.getName() = "string" + kind = ["any", "min", "max"] and + not exists(getExpr(_)) and + result = getArgument(0).getTypeExpr().getResolvedType() + or + not kind = ["count", "strictcount"] and + result = getExpr(0).getType() } override AstNode getAChild(string pred) { diff --git a/ql/test/callgraph/Foo.qll b/ql/test/callgraph/Foo.qll index b289193b5e8..e76d6c18bb2 100644 --- a/ql/test/callgraph/Foo.qll +++ b/ql/test/callgraph/Foo.qll @@ -13,3 +13,5 @@ class Foo extends AstNode { class Sub extends Foo { override predicate baz() { super.baz() } } + +query predicate test2() { any(Foo f).bar() } diff --git a/ql/test/callgraph/callgraph.expected b/ql/test/callgraph/callgraph.expected index 497b6e6591e..b3fc75af731 100644 --- a/ql/test/callgraph/callgraph.expected +++ b/ql/test/callgraph/callgraph.expected @@ -1,3 +1,4 @@ | Foo.qll:5:26:5:30 | PredicateCall | Foo.qll:3:1:3:26 | foo | | Foo.qll:10:21:10:25 | PredicateCall | Foo.qll:8:3:8:28 | ClassPredicate | | Foo.qll:14:30:14:40 | MemberCall | Foo.qll:10:3:10:27 | ClassPredicate | +| Foo.qll:17:27:17:42 | MemberCall | Foo.qll:8:3:8:28 | ClassPredicate | From bd86ffb35b638f7c5ee7e88965cc162dbfa243db Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 29 May 2021 19:20:55 +0000 Subject: [PATCH 8/9] fix the arity of predicate aliases --- ql/src/codeql_ql/ast/Ast.qll | 9 ++++++++- ql/src/codeql_ql/ast/internal/Predicate.qll | 1 + ql/test/callgraph/Foo.qll | 16 ++++++++++++++++ ql/test/callgraph/callgraph.expected | 4 ++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/ql/src/codeql_ql/ast/Ast.qll b/ql/src/codeql_ql/ast/Ast.qll index d682d05f0ee..418e4102d72 100644 --- a/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/src/codeql_ql/ast/Ast.qll @@ -154,7 +154,14 @@ class Predicate extends TPredicate, AstNode { /** * Gets the number of parameters. */ - int getArity() { result = count(getParameter(_)) } + int getArity() { + not this.(ClasslessPredicate).getAlias() instanceof PredicateExpr and + result = count(getParameter(_)) + or + exists(PredicateExpr alias | alias = this.(ClasslessPredicate).getAlias() | + result = alias.getArity() + ) + } /** * Gets the return type (if any) of the predicate. diff --git a/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/src/codeql_ql/ast/internal/Predicate.qll index 96e4b5e5dec..5c1fc61a961 100644 --- a/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -240,6 +240,7 @@ module PredConsistency { query predicate noResolveCall(Call c) { not resolveCall(c, _) and not c instanceof NoneCall and + not c instanceof AnyCall and not c.getLocation().getFile().getAbsolutePath().regexpMatch(".*/(test|examples)/.*") } diff --git a/ql/test/callgraph/Foo.qll b/ql/test/callgraph/Foo.qll index e76d6c18bb2..d9a00db69bc 100644 --- a/ql/test/callgraph/Foo.qll +++ b/ql/test/callgraph/Foo.qll @@ -15,3 +15,19 @@ class Sub extends Foo { } query predicate test2() { any(Foo f).bar() } + +module Aliases { + predicate myThing2(int i, int j) { i = 2 and j = 3 } + + predicate myThing0() { any() } + + predicate alias0 = myThing0/0; + + predicate alias2 = myThing2/2; + + query predicate test3() { + alias2(3, 4) // doesn't work. + or + alias0() // <- works + } +} diff --git a/ql/test/callgraph/callgraph.expected b/ql/test/callgraph/callgraph.expected index b3fc75af731..b760eff532c 100644 --- a/ql/test/callgraph/callgraph.expected +++ b/ql/test/callgraph/callgraph.expected @@ -2,3 +2,7 @@ | Foo.qll:10:21:10:25 | PredicateCall | Foo.qll:8:3:8:28 | ClassPredicate | | Foo.qll:14:30:14:40 | MemberCall | Foo.qll:10:3:10:27 | ClassPredicate | | Foo.qll:17:27:17:42 | MemberCall | Foo.qll:8:3:8:28 | ClassPredicate | +| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:20:3:20:54 | myThing2 | +| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:26:3:26:32 | alias2 | +| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:22:3:22:32 | myThing0 | +| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:24:3:24:32 | alias0 | From 48170f5ce05132368adce0882bb4dee1a4953f99 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 29 May 2021 19:30:40 +0000 Subject: [PATCH 9/9] change `multipleResolveCall` to ignore aliases --- ql/src/codeql_ql/ast/internal/Predicate.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/src/codeql_ql/ast/internal/Predicate.qll index 5c1fc61a961..a66aa14d623 100644 --- a/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -251,7 +251,12 @@ module PredConsistency { } query predicate multipleResolveCall(Call call, int c, PredicateOrBuiltin p) { - c = strictcount(PredicateOrBuiltin p0 | resolveCall(call, p0)) and + c = + strictcount(PredicateOrBuiltin p0 | + resolveCall(call, p0) and + // aliases are expected to resolve to multiple. + not exists(p0.getDeclaration().(ClasslessPredicate).getAlias()) + ) and c > 1 and resolveCall(call, p) }