mirror of
https://github.com/github/codeql.git
synced 2025-12-19 02:13:17 +01:00
We might want to unify some of these in future, but doing that correctly is easier than splitting them up correctly, so I've given each one its own QL class for now. I am not familiar with many of the libraries/queries that use CastExpr. I've briefly looked at them and updated them in a way that looks superficially reasonable, but some of the uses will probably want to be refined later.
141 lines
3.6 KiB
Plaintext
141 lines
3.6 KiB
Plaintext
/**
|
|
* Provides support for conversion contexts, in which an expression is converted
|
|
* (implicitly or explicitly) to a different type.
|
|
*
|
|
* See the Java Language Specification, Section 5, for details.
|
|
*/
|
|
|
|
import java
|
|
import semmle.code.java.arithmetic.Overflow
|
|
|
|
/**
|
|
* A expression where an implicit conversion can occur.
|
|
*
|
|
* See the Java Language Specification, Section 5.
|
|
*/
|
|
abstract class ConversionSite extends Expr {
|
|
/**
|
|
* Gets the type that is converted to.
|
|
*/
|
|
abstract Type getConversionTarget();
|
|
|
|
/**
|
|
* Gets the type that is converted from.
|
|
*/
|
|
Type getConversionSource() { result = this.getType() }
|
|
|
|
/**
|
|
* Whether this conversion site actually induces a conversion.
|
|
*/
|
|
predicate isTrivial() { this.getConversionTarget() = this.getConversionSource() }
|
|
|
|
/**
|
|
* Whether this conversion is implicit.
|
|
*/
|
|
predicate isImplicit() { any() }
|
|
|
|
abstract string kind();
|
|
}
|
|
|
|
/**
|
|
* An assignment conversion. For example, `x += b` converts `b`
|
|
* to be of the type of `x`.
|
|
*
|
|
* See the Java Language Specification, Section 5.2.
|
|
*/
|
|
class AssignmentConversionContext extends ConversionSite {
|
|
Variable v;
|
|
|
|
AssignmentConversionContext() {
|
|
this = v.getAnAssignedValue()
|
|
or
|
|
exists(Assignment a | a.getDest() = v.getAnAccess() and this = a.getSource())
|
|
}
|
|
|
|
override Type getConversionTarget() { result = v.getType() }
|
|
|
|
override string kind() { result = "assignment context" }
|
|
}
|
|
|
|
/**
|
|
* An return conversion. For example, `return b` converts `b`
|
|
* to be of the return type of the enclosing callable.
|
|
*
|
|
* Note that the Java Language Specification handles these as
|
|
* assignment conversions (section 5.2), but for clarity we split them out here.
|
|
*/
|
|
class ReturnConversionSite extends ConversionSite {
|
|
ReturnStmt r;
|
|
|
|
ReturnConversionSite() { this = r.getResult() }
|
|
|
|
override Type getConversionTarget() { result = r.getEnclosingCallable().getReturnType() }
|
|
|
|
override string kind() { result = "return context" }
|
|
}
|
|
|
|
/**
|
|
* An invocation conversion. For example `f(b)` converts `b` to
|
|
* have the type of the corresponding parameter of `f`.
|
|
*
|
|
* See the Java Language Specification, Section 5.3.
|
|
*/
|
|
class InvocationConversionContext extends ConversionSite {
|
|
Call c;
|
|
int index;
|
|
|
|
InvocationConversionContext() { this = c.getArgument(index) }
|
|
|
|
override Type getConversionTarget() { result = c.getCallee().getParameter(index).getType() }
|
|
|
|
override string kind() { result = "invocation context" }
|
|
}
|
|
|
|
/**
|
|
* A string conversion. For example `a + b`, where `a` is a
|
|
* `String`, converts `b` to have type `String`.
|
|
*
|
|
* See the Java Language Specification, Section 5.4.
|
|
*/
|
|
class StringConversionContext extends ConversionSite {
|
|
AddExpr a;
|
|
|
|
StringConversionContext() {
|
|
a.getAnOperand() = this and
|
|
not this.getType() instanceof TypeString and
|
|
a.getAnOperand().getType() instanceof TypeString
|
|
}
|
|
|
|
override Type getConversionTarget() { result instanceof TypeString }
|
|
|
|
override string kind() { result = "string context" }
|
|
}
|
|
|
|
class CastingConversionContext extends ConversionSite {
|
|
CastingExpr c;
|
|
|
|
CastingConversionContext() { this = c.getExpr() }
|
|
|
|
override Type getConversionTarget() { result = c.getType() }
|
|
|
|
override predicate isImplicit() { none() }
|
|
|
|
override string kind() { result = "casting context" }
|
|
}
|
|
|
|
/**
|
|
* A numeric conversion. For example, `a * b` converts `a` and
|
|
* `b` to have an appropriate numeric type.
|
|
*
|
|
* See the Java Language Specification, Section 5.4.
|
|
*/
|
|
class NumericConversionContext extends ConversionSite {
|
|
ArithExpr e;
|
|
|
|
NumericConversionContext() { this = e.getAnOperand() }
|
|
|
|
override Type getConversionTarget() { result = e.getType() }
|
|
|
|
override string kind() { result = "numeric context" }
|
|
}
|