mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
Merge pull request #3151 from dbartol/dbartol/floats
C++: Better support for complex numbers in IR and AST
This commit is contained in:
@@ -12,7 +12,9 @@ private newtype TIRType =
|
||||
TIRBooleanType(int byteSize) { Language::hasBooleanType(byteSize) } or
|
||||
TIRSignedIntegerType(int byteSize) { Language::hasSignedIntegerType(byteSize) } or
|
||||
TIRUnsignedIntegerType(int byteSize) { Language::hasUnsignedIntegerType(byteSize) } or
|
||||
TIRFloatingPointType(int byteSize) { Language::hasFloatingPointType(byteSize) } or
|
||||
TIRFloatingPointType(int byteSize, int base, Language::TypeDomain domain) {
|
||||
Language::hasFloatingPointType(byteSize, base, domain)
|
||||
} or
|
||||
TIRAddressType(int byteSize) { Language::hasAddressType(byteSize) } or
|
||||
TIRFunctionAddressType(int byteSize) { Language::hasFunctionAddressType(byteSize) } or
|
||||
TIROpaqueType(Language::OpaqueTypeTag tag, int byteSize) {
|
||||
@@ -104,7 +106,7 @@ private class IRSizedType extends IRType {
|
||||
this = TIRBooleanType(byteSize) or
|
||||
this = TIRSignedIntegerType(byteSize) or
|
||||
this = TIRUnsignedIntegerType(byteSize) or
|
||||
this = TIRFloatingPointType(byteSize) or
|
||||
this = TIRFloatingPointType(byteSize, _, _) or
|
||||
this = TIRAddressType(byteSize) or
|
||||
this = TIRFunctionAddressType(byteSize) or
|
||||
this = TIROpaqueType(_, byteSize)
|
||||
@@ -133,7 +135,7 @@ class IRNumericType extends IRSizedType {
|
||||
IRNumericType() {
|
||||
this = TIRSignedIntegerType(byteSize) or
|
||||
this = TIRUnsignedIntegerType(byteSize) or
|
||||
this = TIRFloatingPointType(byteSize)
|
||||
this = TIRFloatingPointType(byteSize, _, _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,14 +173,43 @@ class IRUnsignedIntegerType extends IRNumericType, TIRUnsignedIntegerType {
|
||||
* A floating-point type.
|
||||
*/
|
||||
class IRFloatingPointType extends IRNumericType, TIRFloatingPointType {
|
||||
final override string toString() { result = "float" + byteSize.toString() }
|
||||
final private int base;
|
||||
final private Language::TypeDomain domain;
|
||||
|
||||
IRFloatingPointType() { this = TIRFloatingPointType(_, base, domain) }
|
||||
|
||||
final override string toString() {
|
||||
result = getDomainPrefix() + getBaseString() + byteSize.toString()
|
||||
}
|
||||
|
||||
final override Language::LanguageType getCanonicalLanguageType() {
|
||||
result = Language::getCanonicalFloatingPointType(byteSize)
|
||||
result = Language::getCanonicalFloatingPointType(byteSize, base, domain)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
final override int getByteSize() { result = byteSize }
|
||||
|
||||
/** Gets the numeric base of the type. Can be either 2 (binary) or 10 (decimal). */
|
||||
final int getBase() { result = base }
|
||||
|
||||
/**
|
||||
* Gets the type domain of the type. Can be `RealDomain`, `ComplexDomain`, or `ImaginaryDomain`.
|
||||
*/
|
||||
final Language::TypeDomain getDomain() { result = domain }
|
||||
|
||||
private string getBaseString() {
|
||||
base = 2 and result = "float"
|
||||
or
|
||||
base = 10 and result = "decimal"
|
||||
}
|
||||
|
||||
private string getDomainPrefix() {
|
||||
domain instanceof Language::RealDomain and result = ""
|
||||
or
|
||||
domain instanceof Language::ComplexDomain and result = "c"
|
||||
or
|
||||
domain instanceof Language::ImaginaryDomain and result = "i"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,9 +61,13 @@ predicate hasUnsignedIntegerType(int byteSize) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an `IRFloatingPointType` with the specified `byteSize` should exist.
|
||||
* Holds if an `IRFloatingPointType` with the specified size, base, and type domain should exist.
|
||||
*/
|
||||
predicate hasFloatingPointType(int byteSize) { byteSize = any(FloatingPointType type).getSize() }
|
||||
predicate hasFloatingPointType(int byteSize, int base, Language::TypeDomain domain) {
|
||||
byteSize = any(FloatingPointType type).getSize() and
|
||||
base = 2 and
|
||||
domain instanceof Language::RealDomain
|
||||
}
|
||||
|
||||
private predicate isPointerIshType(Type type) {
|
||||
type instanceof PointerType or
|
||||
@@ -314,9 +318,11 @@ CSharpPRValueType getCanonicalUnsignedIntegerType(int byteSize) {
|
||||
|
||||
/**
|
||||
* Gets the `CSharpType` that is the canonical type for an `IRFloatingPointType` with the specified
|
||||
* `byteSize`.
|
||||
* size, base, and type domain.
|
||||
*/
|
||||
CSharpPRValueType getCanonicalFloatingPointType(int byteSize) {
|
||||
CSharpPRValueType getCanonicalFloatingPointType(int byteSize, int base, Language::TypeDomain domain) {
|
||||
base = 2 and
|
||||
domain instanceof Language::RealDomain and
|
||||
result = TPRValueType(any(FloatingPointType type | type.getSize() = byteSize))
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,44 @@ class IntegralType = CSharp::IntegralType;
|
||||
|
||||
class FloatingPointType = CSharp::FloatingPointType;
|
||||
|
||||
private newtype TTypeDomain = TRealDomain()
|
||||
|
||||
/**
|
||||
* The type domain of a floating-point type. One of `RealDomain`, `ComplexDomain`, or
|
||||
* `ImaginaryDomain`.
|
||||
*/
|
||||
class TypeDomain extends TTypeDomain {
|
||||
/** Gets a textual representation of this type domain. */
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The type domain of a floating-point type that represents a real number.
|
||||
*/
|
||||
class RealDomain extends TypeDomain, TRealDomain {
|
||||
final override string toString() { result = "real" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The type domain of a floating-point type that represents a complex number. Not currently used in
|
||||
* C#.
|
||||
*/
|
||||
class ComplexDomain extends TypeDomain {
|
||||
ComplexDomain() { none() }
|
||||
|
||||
final override string toString() { result = "complex" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The type domain of a floating-point type that represents an imaginary number. Not currently used
|
||||
* in C#.
|
||||
*/
|
||||
class ImaginaryDomain extends TypeDomain {
|
||||
ImaginaryDomain() { none() }
|
||||
|
||||
final override string toString() { result = "imaginary" }
|
||||
}
|
||||
|
||||
private newtype TClassDerivation =
|
||||
// Note that this is the `Class` type exported from this module, not CSharp::Class.
|
||||
MkClassDerivation(Class base, Class derived) { derived.getABaseType() = base }
|
||||
|
||||
Reference in New Issue
Block a user