Skip to content

Commit 602c9e7

Browse files
authored
QL: Add more getType overrides
Mainly adds ones for primitive types. One peculiarity: the language specification states that the type of `super` is the same as the type of `this`, and _not_ the type of the superclass on which the method is actually accessed. This seems a bit strange to me, so I thought I would highlight it specifically. Also, I'm not entirely sure that the rules around type coercion for the various binary operators are 100% correct.
1 parent 08dd947 commit 602c9e7

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

ql/src/codeql_ql/ast/Ast.qll

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,8 @@ class String extends Literal {
10651065

10661066
override string getAPrimaryQlClass() { result = "String" }
10671067

1068+
override PrimitiveType getType() { result.getName() = "string" }
1069+
10681070
/** Gets the string value of this literal. */
10691071
string getValue() {
10701072
exists(string raw | raw = lit.getChild().(Generated::String).getValue() |
@@ -1079,6 +1081,8 @@ class Integer extends Literal {
10791081

10801082
override string getAPrimaryQlClass() { result = "Integer" }
10811083

1084+
override PrimitiveType getType() { result.getName() = "int" }
1085+
10821086
/** Gets the integer value of this literal. */
10831087
int getValue() { result = lit.getChild().(Generated::Integer).getValue().toInt() }
10841088
}
@@ -1089,6 +1093,8 @@ class Float extends Literal {
10891093

10901094
override string getAPrimaryQlClass() { result = "Float" }
10911095

1096+
override PrimitiveType getType() { result.getName() = "float" }
1097+
10921098
/** Gets the float value of this literal. */
10931099
float getValue() { result = lit.getChild().(Generated::Float).getValue().toFloat() }
10941100
}
@@ -1105,6 +1111,8 @@ class Boolean extends Literal {
11051111
/** Holds if the value is `false` */
11061112
predicate isFalse() { bool.getChild() instanceof Generated::False }
11071113

1114+
override PrimitiveType getType() { result.getName() = "boolean" }
1115+
11081116
override string getAPrimaryQlClass() { result = "Boolean" }
11091117
}
11101118

@@ -1643,6 +1651,8 @@ class ThisAccess extends Identifier {
16431651
class Super extends TSuper, Expr {
16441652
Super() { this = TSuper(_) }
16451653

1654+
override Type getType() { result = this.getParent+().(Class).getType() }
1655+
16461656
override string getAPrimaryQlClass() { result = "SuperAccess" }
16471657
}
16481658

@@ -1704,6 +1714,8 @@ class ExprAnnotation extends TExprAnnotation, Expr {
17041714
*/
17051715
Expr getExpression() { toGenerated(result) = expr_anno.getChild() }
17061716

1717+
override Type getType() { result = this.getExpression().getType() }
1718+
17071719
override string getAPrimaryQlClass() { result = "ExprAnnotation" }
17081720

17091721
override AstNode getAChild(string pred) {
@@ -1744,6 +1756,27 @@ class AddSubExpr extends TAddSubExpr, BinOpExpr {
17441756
/** Gets the operator of the binary expression. */
17451757
FunctionSymbol getOperator() { result = operator }
17461758

1759+
override PrimitiveType getType() {
1760+
// Both operands are the same type
1761+
result = this.getLeftOperand().getType() and
1762+
result = this.getRightOperand().getType()
1763+
or
1764+
// Both operands are subtypes of `int`
1765+
result.getName() = "int" and
1766+
result = this.getLeftOperand().getType().getASuperType*() and
1767+
result = this.getRightOperand().getType().getASuperType*()
1768+
or
1769+
// Coercion to from `int` to `float`
1770+
exists(PrimitiveType i | result.getName() = "float" and i.getName() = "int" |
1771+
this.getAnOperand().getType() = result and
1772+
this.getAnOperand().getType().getASuperType*() = i
1773+
)
1774+
or
1775+
// Coercion to `string`
1776+
result.getName() = "string" and
1777+
this.getAnOperand().getType() = result
1778+
}
1779+
17471780
override AstNode getAChild(string pred) {
17481781
result = super.getAChild(pred)
17491782
or
@@ -1792,6 +1825,23 @@ class MulDivModExpr extends TMulDivModExpr, BinOpExpr {
17921825
/** Gets the operator of the binary expression. */
17931826
FunctionSymbol getOperator() { result = operator }
17941827

1828+
override PrimitiveType getType() {
1829+
// Both operands are of the same type
1830+
this.getLeftOperand().getType() = result and
1831+
this.getRightOperand().getType() = result
1832+
or
1833+
// Both operands are subtypes of `int`
1834+
result.getName() = "int" and
1835+
result = this.getLeftOperand().getType().getASuperType*() and
1836+
result = this.getRightOperand().getType().getASuperType*()
1837+
or
1838+
// Coercion from `int` to `float`
1839+
exists(PrimitiveType i | result.getName() = "float" and i.getName() = "int" |
1840+
this.getAnOperand().getType() = result and
1841+
this.getAnOperand().getType().getASuperType*() = i
1842+
)
1843+
}
1844+
17951845
override AstNode getAChild(string pred) {
17961846
result = super.getAChild(pred)
17971847
or
@@ -1846,6 +1896,8 @@ class Range extends TRange, Expr {
18461896
*/
18471897
Expr getHighEndpoint() { toGenerated(result) = range.getUpper() }
18481898

1899+
override PrimitiveType getType() { result.getName() = "int" }
1900+
18491901
override string getAPrimaryQlClass() { result = "Range" }
18501902

18511903
override AstNode getAChild(string pred) {
@@ -1870,6 +1922,8 @@ class Set extends TSet, Expr {
18701922
*/
18711923
Expr getElement(int i) { toGenerated(result) = set.getChild(i) }
18721924

1925+
override Type getType() { result = this.getElement(0).getType() }
1926+
18731927
override string getAPrimaryQlClass() { result = "Set" }
18741928

18751929
override AstNode getAChild(string pred) {
@@ -1891,6 +1945,8 @@ class UnaryExpr extends TUnaryExpr, Expr {
18911945
/** Gets the operator of the unary expression as a string. */
18921946
FunctionSymbol getOperator() { result = unaryexpr.getChild(0).toString() }
18931947

1948+
override Type getType() { result = this.getOperand().getType() }
1949+
18941950
override string getAPrimaryQlClass() { result = "UnaryExpr" }
18951951

18961952
override AstNode getAChild(string pred) {
@@ -1906,6 +1962,8 @@ class DontCare extends TDontCare, Expr {
19061962

19071963
DontCare() { this = TDontCare(dontcare) }
19081964

1965+
override DontCareType getType() { any() }
1966+
19091967
override string getAPrimaryQlClass() { result = "DontCare" }
19101968
}
19111969

0 commit comments

Comments
 (0)