mirror of
https://github.com/github/codeql.git
synced 2026-02-12 05:01:06 +01:00
C#: Implicit span conversion.
This commit is contained in:
@@ -28,6 +28,7 @@ private module Cached {
|
||||
*
|
||||
* - Identity conversions
|
||||
* - Implicit numeric conversions
|
||||
* - Implicit span conversions
|
||||
* - Implicit nullable conversions
|
||||
* - Implicit reference conversions
|
||||
* - Boxing conversions
|
||||
@@ -38,6 +39,8 @@ private module Cached {
|
||||
or
|
||||
convNumeric(fromType, toType)
|
||||
or
|
||||
convSpan(fromType, toType)
|
||||
or
|
||||
convNullableType(fromType, toType)
|
||||
or
|
||||
convRefTypeNonNull(fromType, toType)
|
||||
@@ -81,6 +84,7 @@ private predicate implicitConversionNonNull(Type fromType, Type toType) {
|
||||
*
|
||||
* - Identity conversions
|
||||
* - Implicit numeric conversions
|
||||
* - Implicit span conversions
|
||||
* - Implicit nullable conversions
|
||||
* - Implicit reference conversions
|
||||
* - Boxing conversions
|
||||
@@ -491,6 +495,53 @@ private predicate convNumericChar(SimpleType toType) {
|
||||
|
||||
private predicate convNumericFloat(SimpleType toType) { toType instanceof DoubleType }
|
||||
|
||||
private class SpanType extends GenericType {
|
||||
SpanType() { this.getUnboundGeneric() instanceof SystemSpanStruct }
|
||||
|
||||
Type getElementType() { result = this.getTypeArgument(0) }
|
||||
}
|
||||
|
||||
private class ReadOnlySpanType extends GenericType {
|
||||
ReadOnlySpanType() { this.getUnboundGeneric() instanceof SystemReadOnlySpanStruct }
|
||||
|
||||
Type getElementType() { result = this.getTypeArgument(0) }
|
||||
}
|
||||
|
||||
private class SimpleArrayType extends ArrayType {
|
||||
SimpleArrayType() {
|
||||
this.getRank() = 1 and
|
||||
this.getDimension() = 1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Holds if there is an implicit span conversion from `fromType` to `toType`.
|
||||
*
|
||||
* 10.2.1: Implicit span conversions (added in C# 14).
|
||||
* [Documentation](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-14.0/first-class-span-types#span-conversions)
|
||||
*/
|
||||
predicate convSpan(Type fromType, Type toType) {
|
||||
fromType.(SimpleArrayType).getElementType() = toType.(SpanType).getElementType()
|
||||
or
|
||||
exists(Type fromElementType, Type toElementType |
|
||||
(
|
||||
fromElementType = fromType.(SimpleArrayType).getElementType() or
|
||||
fromElementType = fromType.(SpanType).getElementType() or
|
||||
fromElementType = fromType.(ReadOnlySpanType).getElementType()
|
||||
) and
|
||||
toElementType = toType.(ReadOnlySpanType).getElementType()
|
||||
|
|
||||
convIdentity(fromElementType, toElementType)
|
||||
or
|
||||
convCovariance(fromElementType, toElementType)
|
||||
)
|
||||
or
|
||||
fromType instanceof SystemStringClass and
|
||||
toType.(ReadOnlySpanType).getElementType() instanceof CharType
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
@@ -784,8 +835,8 @@ predicate convConversionOperator(Type fromType, Type toType) {
|
||||
)
|
||||
}
|
||||
|
||||
/** 13.1.3.2: Variance conversion. */
|
||||
private predicate convVariance(GenericType fromType, GenericType toType) {
|
||||
pragma[nomagic]
|
||||
private predicate convVarianceAux(UnboundGenericType ugt, GenericType fromType, GenericType toType) {
|
||||
// Semantically equivalent with
|
||||
// ```ql
|
||||
// ugt = fromType.getUnboundGeneric()
|
||||
@@ -805,10 +856,23 @@ private predicate convVariance(GenericType fromType, GenericType toType) {
|
||||
// ```
|
||||
// but performance is improved by explicitly evaluating the `i`th argument
|
||||
// only when all preceding arguments are convertible.
|
||||
Variance::convVarianceSingle(_, fromType, toType)
|
||||
Variance::convVarianceSingle(ugt, fromType, toType)
|
||||
or
|
||||
Variance::convVarianceMultiple(ugt, fromType, toType, ugt.getNumberOfTypeParameters() - 1)
|
||||
}
|
||||
|
||||
/** 13.1.3.2: Variance conversion. */
|
||||
private predicate convVariance(GenericType fromType, GenericType toType) {
|
||||
convVarianceAux(_, fromType, toType)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds, if `fromType` is covariance convertible to `toType`.
|
||||
*/
|
||||
private predicate convCovariance(GenericType fromType, GenericType toType) {
|
||||
exists(UnboundGenericType ugt |
|
||||
Variance::convVarianceMultiple(ugt, fromType, toType, ugt.getNumberOfTypeParameters() - 1)
|
||||
convVarianceAux(ugt, fromType, toType) and
|
||||
forall(TypeParameter tp | tp = ugt.getATypeParameter() | tp.isOut())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user