mirror of
https://github.com/github/codeql.git
synced 2026-01-29 14:23:03 +01:00
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 CastConversionContext extends ConversionSite {
|
|
CastExpr c;
|
|
|
|
CastConversionContext() { this = c.getExpr() }
|
|
|
|
override Type getConversionTarget() { result = c.getType() }
|
|
|
|
override predicate isImplicit() { none() }
|
|
|
|
override string kind() { result = "cast 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" }
|
|
}
|