Merge pull request #3151 from dbartol/dbartol/floats

C++: Better support for complex numbers in IR and AST
This commit is contained in:
Jonas Jensen
2020-04-20 16:27:20 +02:00
committed by GitHub
16 changed files with 2691 additions and 61 deletions

View File

@@ -697,28 +697,188 @@ class Int128Type extends IntegralType {
override string getCanonicalQLClass() { result = "Int128Type" }
}
private newtype TTypeDomain =
TRealDomain() or
TComplexDomain() or
TImaginaryDomain()
/**
* The C/C++ floating point types. See 4.5. This includes `float`,
* `double` and `long double` types.
* ```
* float f;
* double d;
* long double ld;
* ```
* 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.
*/
class ComplexDomain extends TypeDomain, TComplexDomain {
final override string toString() { result = "complex" }
}
/**
* The type domain of a floating-point type that represents an imaginary number.
*/
class ImaginaryDomain extends TypeDomain, TImaginaryDomain {
final override string toString() { result = "imaginary" }
}
/**
* Data for floating-point types.
*
* kind: The original type kind. Can be any floating-point type kind.
* base: The numeric base of the number's representation. Can be 2 (binary) or 10 (decimal).
* domain: The type domain of the type. Can be `RealDomain`, `ComplexDomain`, or `ImaginaryDomain`.
* realKind: The type kind of the corresponding real type. For example, the corresponding real type
* of `_Complex double` is `double`.
* extended: `true` if the number is an extended-precision floating-point number, such as
* `_Float32x`.
*/
private predicate floatingPointTypeMapping(
int kind, int base, TTypeDomain domain, int realKind, boolean extended
) {
// float
kind = 24 and base = 2 and domain = TRealDomain() and realKind = 24 and extended = false
or
// double
kind = 25 and base = 2 and domain = TRealDomain() and realKind = 25 and extended = false
or
// long double
kind = 26 and base = 2 and domain = TRealDomain() and realKind = 26 and extended = false
or
// _Complex float
kind = 27 and base = 2 and domain = TComplexDomain() and realKind = 24 and extended = false
or
// _Complex double
kind = 28 and base = 2 and domain = TComplexDomain() and realKind = 25 and extended = false
or
// _Complex long double
kind = 29 and base = 2 and domain = TComplexDomain() and realKind = 26 and extended = false
or
// _Imaginary float
kind = 30 and base = 2 and domain = TImaginaryDomain() and realKind = 24 and extended = false
or
// _Imaginary double
kind = 31 and base = 2 and domain = TImaginaryDomain() and realKind = 25 and extended = false
or
// _Imaginary long double
kind = 32 and base = 2 and domain = TImaginaryDomain() and realKind = 26 and extended = false
or
// __float128
kind = 38 and base = 2 and domain = TRealDomain() and realKind = 38 and extended = false
or
// _Complex __float128
kind = 39 and base = 2 and domain = TComplexDomain() and realKind = 38 and extended = false
or
// _Decimal32
kind = 40 and base = 10 and domain = TRealDomain() and realKind = 40 and extended = false
or
// _Decimal64
kind = 41 and base = 10 and domain = TRealDomain() and realKind = 41 and extended = false
or
// _Decimal128
kind = 42 and base = 10 and domain = TRealDomain() and realKind = 42 and extended = false
or
// _Float32
kind = 45 and base = 2 and domain = TRealDomain() and realKind = 45 and extended = false
or
// _Float32x
kind = 46 and base = 2 and domain = TRealDomain() and realKind = 46 and extended = true
or
// _Float64
kind = 47 and base = 2 and domain = TRealDomain() and realKind = 47 and extended = false
or
// _Float64x
kind = 48 and base = 2 and domain = TRealDomain() and realKind = 48 and extended = true
or
// _Float128
kind = 49 and base = 2 and domain = TRealDomain() and realKind = 49 and extended = false
or
// _Float128x
kind = 50 and base = 2 and domain = TRealDomain() and realKind = 50 and extended = true
}
/**
* The C/C++ floating point types. See 4.5. This includes `float`, `double` and `long double`, the
* fixed-size floating-point types like `_Float32`, the extended-precision floating-point types like
* `_Float64x`, and the decimal floating-point types like `_Decimal32`. It also includes the complex
* and imaginary versions of all of these types.
*/
class FloatingPointType extends ArithmeticType {
final int base;
final TypeDomain domain;
final int realKind;
final boolean extended;
FloatingPointType() {
exists(int kind |
builtintypes(underlyingElement(this), _, kind, _, _, _) and
(
kind >= 24 and kind <= 32
or
kind >= 38 and kind <= 42
or
kind >= 45 and kind <= 50
)
floatingPointTypeMapping(kind, base, domain, realKind, extended)
)
}
/** Gets the numeric base of this type's representation: 2 (binary) or 10 (decimal). */
final int getBase() { result = base }
/**
* Gets the type domain of this type. Can be `RealDomain`, `ComplexDomain`, or `ImaginaryDomain`.
*/
final TypeDomain getDomain() { result = domain }
/**
* Gets the corresponding real type of this type. For example, the corresponding real type of
* `_Complex double` is `double`.
*/
final RealNumberType getRealType() {
builtintypes(unresolveElement(result), _, realKind, _, _, _)
}
/** Holds if this type is an extended precision floating-point type, such as `_Float32x`. */
final predicate isExtendedPrecision() { extended = true }
}
/**
* A floating-point type representing a real number.
*/
class RealNumberType extends FloatingPointType {
RealNumberType() { domain instanceof RealDomain }
}
/**
* A floating-point type representing a complex number.
*/
class ComplexNumberType extends FloatingPointType {
ComplexNumberType() { domain instanceof ComplexDomain }
}
/**
* A floating-point type representing an imaginary number.
*/
class ImaginaryNumberType extends FloatingPointType {
ImaginaryNumberType() { domain instanceof ImaginaryDomain }
}
/**
* A floating-point type whose representation is base 2.
*/
class BinaryFloatingPointType extends FloatingPointType {
BinaryFloatingPointType() { base = 2 }
}
/**
* A floating-point type whose representation is base 10.
*/
class DecimalFloatingPointType extends FloatingPointType {
DecimalFloatingPointType() { base = 10 }
}
/**
@@ -727,7 +887,7 @@ class FloatingPointType extends ArithmeticType {
* float f;
* ```
*/
class FloatType extends FloatingPointType {
class FloatType extends RealNumberType, BinaryFloatingPointType {
FloatType() { builtintypes(underlyingElement(this), _, 24, _, _, _) }
override string getCanonicalQLClass() { result = "FloatType" }
@@ -739,7 +899,7 @@ class FloatType extends FloatingPointType {
* double d;
* ```
*/
class DoubleType extends FloatingPointType {
class DoubleType extends RealNumberType, BinaryFloatingPointType {
DoubleType() { builtintypes(underlyingElement(this), _, 25, _, _, _) }
override string getCanonicalQLClass() { result = "DoubleType" }
@@ -751,7 +911,7 @@ class DoubleType extends FloatingPointType {
* long double ld;
* ```
*/
class LongDoubleType extends FloatingPointType {
class LongDoubleType extends RealNumberType, BinaryFloatingPointType {
LongDoubleType() { builtintypes(underlyingElement(this), _, 26, _, _, _) }
override string getCanonicalQLClass() { result = "LongDoubleType" }
@@ -763,7 +923,7 @@ class LongDoubleType extends FloatingPointType {
* __float128 f128;
* ```
*/
class Float128Type extends FloatingPointType {
class Float128Type extends RealNumberType, BinaryFloatingPointType {
Float128Type() { builtintypes(underlyingElement(this), _, 38, _, _, _) }
override string getCanonicalQLClass() { result = "Float128Type" }
@@ -775,7 +935,7 @@ class Float128Type extends FloatingPointType {
* _Decimal32 d32;
* ```
*/
class Decimal32Type extends FloatingPointType {
class Decimal32Type extends RealNumberType, DecimalFloatingPointType {
Decimal32Type() { builtintypes(underlyingElement(this), _, 40, _, _, _) }
override string getCanonicalQLClass() { result = "Decimal32Type" }
@@ -787,7 +947,7 @@ class Decimal32Type extends FloatingPointType {
* _Decimal64 d64;
* ```
*/
class Decimal64Type extends FloatingPointType {
class Decimal64Type extends RealNumberType, DecimalFloatingPointType {
Decimal64Type() { builtintypes(underlyingElement(this), _, 41, _, _, _) }
override string getCanonicalQLClass() { result = "Decimal64Type" }
@@ -799,7 +959,7 @@ class Decimal64Type extends FloatingPointType {
* _Decimal128 d128;
* ```
*/
class Decimal128Type extends FloatingPointType {
class Decimal128Type extends RealNumberType, DecimalFloatingPointType {
Decimal128Type() { builtintypes(underlyingElement(this), _, 42, _, _, _) }
override string getCanonicalQLClass() { result = "Decimal128Type" }

View File

@@ -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"
}
}
/**

View File

@@ -1100,13 +1100,36 @@ private Opcode binaryBitwiseOpcode(BinaryBitwiseOperation expr) {
}
private Opcode binaryArithmeticOpcode(BinaryArithmeticOperation expr) {
expr instanceof AddExpr and result instanceof Opcode::Add
(
expr instanceof AddExpr
or
expr instanceof ImaginaryRealAddExpr
or
expr instanceof RealImaginaryAddExpr
) and
result instanceof Opcode::Add
or
expr instanceof SubExpr and result instanceof Opcode::Sub
(
expr instanceof SubExpr
or
expr instanceof ImaginaryRealSubExpr
or
expr instanceof RealImaginarySubExpr
) and
result instanceof Opcode::Sub
or
expr instanceof MulExpr and result instanceof Opcode::Mul
(
expr instanceof MulExpr
or
expr instanceof ImaginaryMulExpr
) and
result instanceof Opcode::Mul
or
expr instanceof DivExpr and result instanceof Opcode::Div
(
expr instanceof DivExpr or
expr instanceof ImaginaryDivExpr
) and
result instanceof Opcode::Div
or
expr instanceof RemExpr and result instanceof Opcode::Rem
or

View File

@@ -86,9 +86,15 @@ 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, TypeDomain domain) {
exists(FloatingPointType type |
byteSize = type.getSize() and
base = type.getBase() and
domain = type.getDomain()
)
}
private predicate isPointerIshType(Type type) {
type instanceof PointerType
@@ -159,8 +165,13 @@ private IRType getIRTypeForPRValue(Type type) {
isUnsignedIntegerType(unspecifiedType) and
result.(IRUnsignedIntegerType).getByteSize() = type.getSize()
or
unspecifiedType instanceof FloatingPointType and
result.(IRFloatingPointType).getByteSize() = type.getSize()
exists(FloatingPointType floatType, IRFloatingPointType irFloatType |
floatType = unspecifiedType and
irFloatType = result and
irFloatType.getByteSize() = floatType.getSize() and
irFloatType.getBase() = floatType.getBase() and
irFloatType.getDomain() = floatType.getDomain()
)
or
isPointerIshType(unspecifiedType) and result.(IRAddressType).getByteSize() = getTypeSize(type)
or
@@ -438,15 +449,37 @@ CppPRValueType getCanonicalUnsignedIntegerType(int byteSize) {
}
/**
* Gets the `CppType` that is the canonical type for an `IRFloatingPointType` with the specified
* `byteSize`.
* Gets the sort priority of a `RealNumberType` base on its precision.
*/
CppPRValueType getCanonicalFloatingPointType(int byteSize) {
private int getPrecisionPriority(RealNumberType type) {
// Prefer `double`, `float`, `long double` in that order.
if type instanceof DoubleType
then result = 4
else
if type instanceof FloatType
then result = 3
else
if type instanceof LongDoubleType
then result = 2
else
// If we get this far, prefer non-extended-precision types.
if not type.isExtendedPrecision()
then result = 1
else result = 0
}
/**
* Gets the `CppType` that is the canonical type for an `IRFloatingPointType` with the specified
* size, base, and type domain.
*/
CppPRValueType getCanonicalFloatingPointType(int byteSize, int base, TypeDomain domain) {
result =
TPRValueType(max(FloatingPointType type |
type.getSize() = byteSize
type.getSize() = byteSize and
type.getBase() = base and
type.getDomain() = domain
|
type order by type.toString() desc
type order by getPrecisionPriority(type.getRealType()), type.toString() desc
))
}

View File

@@ -9,6 +9,14 @@ class LanguageType = CppType;
class OpaqueTypeTag = Cpp::Type;
class TypeDomain = Cpp::TypeDomain;
class RealDomain = Cpp::RealDomain;
class ComplexDomain = Cpp::ComplexDomain;
class ImaginaryDomain = Cpp::ImaginaryDomain;
class Function = Cpp::Function;
class Location = Cpp::Location;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,147 @@
void complex_literals(void) {
_Complex float cf = 2.0;
cf = __I__;
_Complex double cd = 3.0;
cd = __I__;
_Complex long double cld = 5.0;
cld = __I__;
_Imaginary float jf = __I__;
_Imaginary double jd = __I__;
_Imaginary long double jld = __I__;
}
void complex_arithmetic(void) {
float f1 = 5.0;
float f2 = 7.0;
float f3;
_Complex float cf1 = 2.0;
_Complex float cf2 = __I__;
_Complex float cf3;
_Imaginary float jf1 = __I__;
_Imaginary float jf2 = __I__;
_Imaginary float jf3;
// unaryop _Complex
cf3 = +cf1;
cf3 = -cf1;
// _Complex binaryop _Complex
cf3 = cf1 + cf2;
cf3 = cf1 - cf2;
cf3 = cf1 * cf2;
cf3 = cf1 / cf2;
// unaryop _Imaginary
jf3 = +jf1;
jf3 = -jf1;
// _Imaginary binaryop _Imaginary
jf3 = jf1 + jf2;
jf3 = jf1 - jf2;
f3 = jf1 * jf2; // Result is _Real
f3 = jf1 / jf2; // Result is _Real
// _Imaginary binaryop _Real
cf3 = jf1 + f2;
cf3 = jf1 - f2;
jf3 = jf1 * f2; // Result is _Imaginary
jf3 = jf1 / f2; // Result is _Imaginary
// _Real binaryop _Imaginary
cf3 = f1 + jf2;
cf3 = f1 - jf2;
jf3 = f1 * jf2; // Result is _Imaginary
jf3 = f1 / jf2; // Result is _Imaginary
}
void complex_conversions(void) {
float f = 2.0;
double d = 3.0;
long double ld = 5.0;
_Complex float cf = 7.0;
_Complex double cd = 11.0;
_Complex long double cld = 13.0;
_Imaginary float jf = __I__;
_Imaginary double jd = __I__;
_Imaginary long double jld = __I__;
// _Complex to _Complex
cf = cf;
cf = cd;
cf = cld;
cd = cf;
cd = cd;
cd = cld;
cld = cf;
cld = cd;
cld = cld;
// _Real to _Complex
cf = f;
cf = d;
cf = ld;
cd = f;
cd = d;
cd = ld;
cld = f;
cld = d;
cld = ld;
// _Complex to _Real
f = cf;
f = cd;
f = cld;
d = cf;
d = cd;
d = cld;
ld = cf;
ld = cd;
ld = cld;
// _Imaginary to _Complex
cf = jf;
cf = jd;
cf = jld;
cd = jf;
cd = jd;
cd = jld;
cld = jf;
cld = jd;
cld = jld;
// _Complex to _Imaginary
jf = cf;
jf = cd;
jf = cld;
jd = cf;
jd = cd;
jd = cld;
jld = cf;
jld = cd;
jld = cld;
// _Real to _Imaginary
jf = f;
jf = d;
jf = ld;
jd = f;
jd = d;
jd = ld;
jld = f;
jld = d;
jld = ld;
// _Imaginary to _Real
f = jf;
f = jd;
f = jld;
d = jf;
d = jd;
d = jld;
ld = jf;
ld = jd;
ld = jld;
}
// semmle-extractor-options: --microsoft --edg --c99

View File

@@ -124,6 +124,580 @@ clang.cpp:
# 5| v5_8(void) = AliasedUse : ~mu5_4
# 5| v5_9(void) = ExitFunction :
complex.c:
# 1| void complex_literals()
# 1| Block 0
# 1| v1_1(void) = EnterFunction :
# 1| mu1_2(unknown) = AliasedDefinition :
# 1| mu1_3(unknown) = InitializeNonLocal :
# 1| mu1_4(unknown) = UnmodeledDefinition :
# 2| r2_1(glval<_Complex float>) = VariableAddress[cf] :
# 2| r2_2(double) = Constant[2.0] :
# 2| r2_3(_Complex float) = Convert : r2_2
# 2| mu2_4(_Complex float) = Store : &:r2_1, r2_3
# 3| r3_1(_Imaginary float) = Constant[1.0i] :
# 3| r3_2(_Complex float) = Convert : r3_1
# 3| r3_3(glval<_Complex float>) = VariableAddress[cf] :
# 3| mu3_4(_Complex float) = Store : &:r3_3, r3_2
# 4| r4_1(glval<_Complex double>) = VariableAddress[cd] :
# 4| r4_2(double) = Constant[3.0] :
# 4| r4_3(_Complex double) = Convert : r4_2
# 4| mu4_4(_Complex double) = Store : &:r4_1, r4_3
# 5| r5_1(_Imaginary float) = Constant[1.0i] :
# 5| r5_2(_Complex double) = Convert : r5_1
# 5| r5_3(glval<_Complex double>) = VariableAddress[cd] :
# 5| mu5_4(_Complex double) = Store : &:r5_3, r5_2
# 6| r6_1(glval<_Complex long double>) = VariableAddress[cld] :
# 6| r6_2(double) = Constant[5.0] :
# 6| r6_3(_Complex long double) = Convert : r6_2
# 6| mu6_4(_Complex long double) = Store : &:r6_1, r6_3
# 7| r7_1(_Imaginary float) = Constant[1.0i] :
# 7| r7_2(_Complex long double) = Convert : r7_1
# 7| r7_3(glval<_Complex long double>) = VariableAddress[cld] :
# 7| mu7_4(_Complex long double) = Store : &:r7_3, r7_2
# 9| r9_1(glval<_Imaginary float>) = VariableAddress[jf] :
# 9| r9_2(_Imaginary float) = Constant[1.0i] :
# 9| mu9_3(_Imaginary float) = Store : &:r9_1, r9_2
# 10| r10_1(glval<_Imaginary double>) = VariableAddress[jd] :
# 10| r10_2(_Imaginary float) = Constant[1.0i] :
# 10| r10_3(_Imaginary double) = Convert : r10_2
# 10| mu10_4(_Imaginary double) = Store : &:r10_1, r10_3
# 11| r11_1(glval<_Imaginary long double>) = VariableAddress[jld] :
# 11| r11_2(_Imaginary float) = Constant[1.0i] :
# 11| r11_3(_Imaginary long double) = Convert : r11_2
# 11| mu11_4(_Imaginary long double) = Store : &:r11_1, r11_3
# 12| v12_1(void) = NoOp :
# 1| v1_5(void) = ReturnVoid :
# 1| v1_6(void) = UnmodeledUse : mu*
# 1| v1_7(void) = AliasedUse : ~mu1_4
# 1| v1_8(void) = ExitFunction :
# 14| void complex_arithmetic()
# 14| Block 0
# 14| v14_1(void) = EnterFunction :
# 14| mu14_2(unknown) = AliasedDefinition :
# 14| mu14_3(unknown) = InitializeNonLocal :
# 14| mu14_4(unknown) = UnmodeledDefinition :
# 15| r15_1(glval<float>) = VariableAddress[f1] :
# 15| r15_2(float) = Constant[5.0] :
# 15| mu15_3(float) = Store : &:r15_1, r15_2
# 16| r16_1(glval<float>) = VariableAddress[f2] :
# 16| r16_2(float) = Constant[7.0] :
# 16| mu16_3(float) = Store : &:r16_1, r16_2
# 17| r17_1(glval<float>) = VariableAddress[f3] :
# 17| mu17_2(float) = Uninitialized[f3] : &:r17_1
# 18| r18_1(glval<_Complex float>) = VariableAddress[cf1] :
# 18| r18_2(double) = Constant[2.0] :
# 18| r18_3(_Complex float) = Convert : r18_2
# 18| mu18_4(_Complex float) = Store : &:r18_1, r18_3
# 19| r19_1(glval<_Complex float>) = VariableAddress[cf2] :
# 19| r19_2(_Imaginary float) = Constant[1.0i] :
# 19| r19_3(_Complex float) = Convert : r19_2
# 19| mu19_4(_Complex float) = Store : &:r19_1, r19_3
# 20| r20_1(glval<_Complex float>) = VariableAddress[cf3] :
# 20| mu20_2(_Complex float) = Uninitialized[cf3] : &:r20_1
# 21| r21_1(glval<_Imaginary float>) = VariableAddress[jf1] :
# 21| r21_2(_Imaginary float) = Constant[1.0i] :
# 21| mu21_3(_Imaginary float) = Store : &:r21_1, r21_2
# 22| r22_1(glval<_Imaginary float>) = VariableAddress[jf2] :
# 22| r22_2(_Imaginary float) = Constant[1.0i] :
# 22| mu22_3(_Imaginary float) = Store : &:r22_1, r22_2
# 23| r23_1(glval<_Imaginary float>) = VariableAddress[jf3] :
# 23| mu23_2(_Imaginary float) = Uninitialized[jf3] : &:r23_1
# 26| r26_1(glval<_Complex float>) = VariableAddress[cf1] :
# 26| r26_2(_Complex float) = Load : &:r26_1, ~mu14_4
# 26| r26_3(_Complex float) = CopyValue : r26_2
# 26| r26_4(glval<_Complex float>) = VariableAddress[cf3] :
# 26| mu26_5(_Complex float) = Store : &:r26_4, r26_3
# 27| r27_1(glval<_Complex float>) = VariableAddress[cf1] :
# 27| r27_2(_Complex float) = Load : &:r27_1, ~mu14_4
# 27| r27_3(_Complex float) = Negate : r27_2
# 27| r27_4(glval<_Complex float>) = VariableAddress[cf3] :
# 27| mu27_5(_Complex float) = Store : &:r27_4, r27_3
# 30| r30_1(glval<_Complex float>) = VariableAddress[cf1] :
# 30| r30_2(_Complex float) = Load : &:r30_1, ~mu14_4
# 30| r30_3(glval<_Complex float>) = VariableAddress[cf2] :
# 30| r30_4(_Complex float) = Load : &:r30_3, ~mu14_4
# 30| r30_5(_Complex float) = Add : r30_2, r30_4
# 30| r30_6(glval<_Complex float>) = VariableAddress[cf3] :
# 30| mu30_7(_Complex float) = Store : &:r30_6, r30_5
# 31| r31_1(glval<_Complex float>) = VariableAddress[cf1] :
# 31| r31_2(_Complex float) = Load : &:r31_1, ~mu14_4
# 31| r31_3(glval<_Complex float>) = VariableAddress[cf2] :
# 31| r31_4(_Complex float) = Load : &:r31_3, ~mu14_4
# 31| r31_5(_Complex float) = Sub : r31_2, r31_4
# 31| r31_6(glval<_Complex float>) = VariableAddress[cf3] :
# 31| mu31_7(_Complex float) = Store : &:r31_6, r31_5
# 32| r32_1(glval<_Complex float>) = VariableAddress[cf1] :
# 32| r32_2(_Complex float) = Load : &:r32_1, ~mu14_4
# 32| r32_3(glval<_Complex float>) = VariableAddress[cf2] :
# 32| r32_4(_Complex float) = Load : &:r32_3, ~mu14_4
# 32| r32_5(_Complex float) = Mul : r32_2, r32_4
# 32| r32_6(glval<_Complex float>) = VariableAddress[cf3] :
# 32| mu32_7(_Complex float) = Store : &:r32_6, r32_5
# 33| r33_1(glval<_Complex float>) = VariableAddress[cf1] :
# 33| r33_2(_Complex float) = Load : &:r33_1, ~mu14_4
# 33| r33_3(glval<_Complex float>) = VariableAddress[cf2] :
# 33| r33_4(_Complex float) = Load : &:r33_3, ~mu14_4
# 33| r33_5(_Complex float) = Div : r33_2, r33_4
# 33| r33_6(glval<_Complex float>) = VariableAddress[cf3] :
# 33| mu33_7(_Complex float) = Store : &:r33_6, r33_5
# 36| r36_1(glval<_Imaginary float>) = VariableAddress[jf1] :
# 36| r36_2(_Imaginary float) = Load : &:r36_1, ~mu14_4
# 36| r36_3(_Imaginary float) = CopyValue : r36_2
# 36| r36_4(glval<_Imaginary float>) = VariableAddress[jf3] :
# 36| mu36_5(_Imaginary float) = Store : &:r36_4, r36_3
# 37| r37_1(glval<_Imaginary float>) = VariableAddress[jf1] :
# 37| r37_2(_Imaginary float) = Load : &:r37_1, ~mu14_4
# 37| r37_3(_Imaginary float) = Negate : r37_2
# 37| r37_4(glval<_Imaginary float>) = VariableAddress[jf3] :
# 37| mu37_5(_Imaginary float) = Store : &:r37_4, r37_3
# 40| r40_1(glval<_Imaginary float>) = VariableAddress[jf1] :
# 40| r40_2(_Imaginary float) = Load : &:r40_1, ~mu14_4
# 40| r40_3(glval<_Imaginary float>) = VariableAddress[jf2] :
# 40| r40_4(_Imaginary float) = Load : &:r40_3, ~mu14_4
# 40| r40_5(_Imaginary float) = Add : r40_2, r40_4
# 40| r40_6(glval<_Imaginary float>) = VariableAddress[jf3] :
# 40| mu40_7(_Imaginary float) = Store : &:r40_6, r40_5
# 41| r41_1(glval<_Imaginary float>) = VariableAddress[jf1] :
# 41| r41_2(_Imaginary float) = Load : &:r41_1, ~mu14_4
# 41| r41_3(glval<_Imaginary float>) = VariableAddress[jf2] :
# 41| r41_4(_Imaginary float) = Load : &:r41_3, ~mu14_4
# 41| r41_5(_Imaginary float) = Sub : r41_2, r41_4
# 41| r41_6(glval<_Imaginary float>) = VariableAddress[jf3] :
# 41| mu41_7(_Imaginary float) = Store : &:r41_6, r41_5
# 42| r42_1(glval<_Imaginary float>) = VariableAddress[jf1] :
# 42| r42_2(_Imaginary float) = Load : &:r42_1, ~mu14_4
# 42| r42_3(glval<_Imaginary float>) = VariableAddress[jf2] :
# 42| r42_4(_Imaginary float) = Load : &:r42_3, ~mu14_4
# 42| r42_5(float) = Mul : r42_2, r42_4
# 42| r42_6(glval<float>) = VariableAddress[f3] :
# 42| mu42_7(float) = Store : &:r42_6, r42_5
# 43| r43_1(glval<_Imaginary float>) = VariableAddress[jf1] :
# 43| r43_2(_Imaginary float) = Load : &:r43_1, ~mu14_4
# 43| r43_3(glval<_Imaginary float>) = VariableAddress[jf2] :
# 43| r43_4(_Imaginary float) = Load : &:r43_3, ~mu14_4
# 43| r43_5(float) = Div : r43_2, r43_4
# 43| r43_6(glval<float>) = VariableAddress[f3] :
# 43| mu43_7(float) = Store : &:r43_6, r43_5
# 46| r46_1(glval<_Imaginary float>) = VariableAddress[jf1] :
# 46| r46_2(_Imaginary float) = Load : &:r46_1, ~mu14_4
# 46| r46_3(glval<float>) = VariableAddress[f2] :
# 46| r46_4(float) = Load : &:r46_3, ~mu14_4
# 46| r46_5(_Complex float) = Add : r46_2, r46_4
# 46| r46_6(glval<_Complex float>) = VariableAddress[cf3] :
# 46| mu46_7(_Complex float) = Store : &:r46_6, r46_5
# 47| r47_1(glval<_Imaginary float>) = VariableAddress[jf1] :
# 47| r47_2(_Imaginary float) = Load : &:r47_1, ~mu14_4
# 47| r47_3(glval<float>) = VariableAddress[f2] :
# 47| r47_4(float) = Load : &:r47_3, ~mu14_4
# 47| r47_5(_Complex float) = Sub : r47_2, r47_4
# 47| r47_6(glval<_Complex float>) = VariableAddress[cf3] :
# 47| mu47_7(_Complex float) = Store : &:r47_6, r47_5
# 48| r48_1(glval<_Imaginary float>) = VariableAddress[jf1] :
# 48| r48_2(_Imaginary float) = Load : &:r48_1, ~mu14_4
# 48| r48_3(glval<float>) = VariableAddress[f2] :
# 48| r48_4(float) = Load : &:r48_3, ~mu14_4
# 48| r48_5(_Imaginary float) = Mul : r48_2, r48_4
# 48| r48_6(glval<_Imaginary float>) = VariableAddress[jf3] :
# 48| mu48_7(_Imaginary float) = Store : &:r48_6, r48_5
# 49| r49_1(glval<_Imaginary float>) = VariableAddress[jf1] :
# 49| r49_2(_Imaginary float) = Load : &:r49_1, ~mu14_4
# 49| r49_3(glval<float>) = VariableAddress[f2] :
# 49| r49_4(float) = Load : &:r49_3, ~mu14_4
# 49| r49_5(_Imaginary float) = Div : r49_2, r49_4
# 49| r49_6(glval<_Imaginary float>) = VariableAddress[jf3] :
# 49| mu49_7(_Imaginary float) = Store : &:r49_6, r49_5
# 52| r52_1(glval<float>) = VariableAddress[f1] :
# 52| r52_2(float) = Load : &:r52_1, ~mu14_4
# 52| r52_3(glval<_Imaginary float>) = VariableAddress[jf2] :
# 52| r52_4(_Imaginary float) = Load : &:r52_3, ~mu14_4
# 52| r52_5(_Complex float) = Add : r52_2, r52_4
# 52| r52_6(glval<_Complex float>) = VariableAddress[cf3] :
# 52| mu52_7(_Complex float) = Store : &:r52_6, r52_5
# 53| r53_1(glval<float>) = VariableAddress[f1] :
# 53| r53_2(float) = Load : &:r53_1, ~mu14_4
# 53| r53_3(glval<_Imaginary float>) = VariableAddress[jf2] :
# 53| r53_4(_Imaginary float) = Load : &:r53_3, ~mu14_4
# 53| r53_5(_Complex float) = Sub : r53_2, r53_4
# 53| r53_6(glval<_Complex float>) = VariableAddress[cf3] :
# 53| mu53_7(_Complex float) = Store : &:r53_6, r53_5
# 54| r54_1(glval<float>) = VariableAddress[f1] :
# 54| r54_2(float) = Load : &:r54_1, ~mu14_4
# 54| r54_3(glval<_Imaginary float>) = VariableAddress[jf2] :
# 54| r54_4(_Imaginary float) = Load : &:r54_3, ~mu14_4
# 54| r54_5(_Imaginary float) = Mul : r54_2, r54_4
# 54| r54_6(glval<_Imaginary float>) = VariableAddress[jf3] :
# 54| mu54_7(_Imaginary float) = Store : &:r54_6, r54_5
# 55| r55_1(glval<float>) = VariableAddress[f1] :
# 55| r55_2(float) = Load : &:r55_1, ~mu14_4
# 55| r55_3(glval<_Imaginary float>) = VariableAddress[jf2] :
# 55| r55_4(_Imaginary float) = Load : &:r55_3, ~mu14_4
# 55| r55_5(_Imaginary float) = Div : r55_2, r55_4
# 55| r55_6(glval<_Imaginary float>) = VariableAddress[jf3] :
# 55| mu55_7(_Imaginary float) = Store : &:r55_6, r55_5
# 56| v56_1(void) = NoOp :
# 14| v14_5(void) = ReturnVoid :
# 14| v14_6(void) = UnmodeledUse : mu*
# 14| v14_7(void) = AliasedUse : ~mu14_4
# 14| v14_8(void) = ExitFunction :
# 58| void complex_conversions()
# 58| Block 0
# 58| v58_1(void) = EnterFunction :
# 58| mu58_2(unknown) = AliasedDefinition :
# 58| mu58_3(unknown) = InitializeNonLocal :
# 58| mu58_4(unknown) = UnmodeledDefinition :
# 59| r59_1(glval<float>) = VariableAddress[f] :
# 59| r59_2(float) = Constant[2.0] :
# 59| mu59_3(float) = Store : &:r59_1, r59_2
# 60| r60_1(glval<double>) = VariableAddress[d] :
# 60| r60_2(double) = Constant[3.0] :
# 60| mu60_3(double) = Store : &:r60_1, r60_2
# 61| r61_1(glval<long double>) = VariableAddress[ld] :
# 61| r61_2(long double) = Constant[5.0] :
# 61| mu61_3(long double) = Store : &:r61_1, r61_2
# 62| r62_1(glval<_Complex float>) = VariableAddress[cf] :
# 62| r62_2(double) = Constant[7.0] :
# 62| r62_3(_Complex float) = Convert : r62_2
# 62| mu62_4(_Complex float) = Store : &:r62_1, r62_3
# 63| r63_1(glval<_Complex double>) = VariableAddress[cd] :
# 63| r63_2(double) = Constant[11.0] :
# 63| r63_3(_Complex double) = Convert : r63_2
# 63| mu63_4(_Complex double) = Store : &:r63_1, r63_3
# 64| r64_1(glval<_Complex long double>) = VariableAddress[cld] :
# 64| r64_2(double) = Constant[13.0] :
# 64| r64_3(_Complex long double) = Convert : r64_2
# 64| mu64_4(_Complex long double) = Store : &:r64_1, r64_3
# 65| r65_1(glval<_Imaginary float>) = VariableAddress[jf] :
# 65| r65_2(_Imaginary float) = Constant[1.0i] :
# 65| mu65_3(_Imaginary float) = Store : &:r65_1, r65_2
# 66| r66_1(glval<_Imaginary double>) = VariableAddress[jd] :
# 66| r66_2(_Imaginary float) = Constant[1.0i] :
# 66| r66_3(_Imaginary double) = Convert : r66_2
# 66| mu66_4(_Imaginary double) = Store : &:r66_1, r66_3
# 67| r67_1(glval<_Imaginary long double>) = VariableAddress[jld] :
# 67| r67_2(_Imaginary float) = Constant[1.0i] :
# 67| r67_3(_Imaginary long double) = Convert : r67_2
# 67| mu67_4(_Imaginary long double) = Store : &:r67_1, r67_3
# 70| r70_1(glval<_Complex float>) = VariableAddress[cf] :
# 70| r70_2(_Complex float) = Load : &:r70_1, ~mu58_4
# 70| r70_3(glval<_Complex float>) = VariableAddress[cf] :
# 70| mu70_4(_Complex float) = Store : &:r70_3, r70_2
# 71| r71_1(glval<_Complex double>) = VariableAddress[cd] :
# 71| r71_2(_Complex double) = Load : &:r71_1, ~mu58_4
# 71| r71_3(_Complex float) = Convert : r71_2
# 71| r71_4(glval<_Complex float>) = VariableAddress[cf] :
# 71| mu71_5(_Complex float) = Store : &:r71_4, r71_3
# 72| r72_1(glval<_Complex long double>) = VariableAddress[cld] :
# 72| r72_2(_Complex long double) = Load : &:r72_1, ~mu58_4
# 72| r72_3(_Complex float) = Convert : r72_2
# 72| r72_4(glval<_Complex float>) = VariableAddress[cf] :
# 72| mu72_5(_Complex float) = Store : &:r72_4, r72_3
# 73| r73_1(glval<_Complex float>) = VariableAddress[cf] :
# 73| r73_2(_Complex float) = Load : &:r73_1, ~mu58_4
# 73| r73_3(_Complex double) = Convert : r73_2
# 73| r73_4(glval<_Complex double>) = VariableAddress[cd] :
# 73| mu73_5(_Complex double) = Store : &:r73_4, r73_3
# 74| r74_1(glval<_Complex double>) = VariableAddress[cd] :
# 74| r74_2(_Complex double) = Load : &:r74_1, ~mu58_4
# 74| r74_3(glval<_Complex double>) = VariableAddress[cd] :
# 74| mu74_4(_Complex double) = Store : &:r74_3, r74_2
# 75| r75_1(glval<_Complex long double>) = VariableAddress[cld] :
# 75| r75_2(_Complex long double) = Load : &:r75_1, ~mu58_4
# 75| r75_3(_Complex double) = Convert : r75_2
# 75| r75_4(glval<_Complex double>) = VariableAddress[cd] :
# 75| mu75_5(_Complex double) = Store : &:r75_4, r75_3
# 76| r76_1(glval<_Complex float>) = VariableAddress[cf] :
# 76| r76_2(_Complex float) = Load : &:r76_1, ~mu58_4
# 76| r76_3(_Complex long double) = Convert : r76_2
# 76| r76_4(glval<_Complex long double>) = VariableAddress[cld] :
# 76| mu76_5(_Complex long double) = Store : &:r76_4, r76_3
# 77| r77_1(glval<_Complex double>) = VariableAddress[cd] :
# 77| r77_2(_Complex double) = Load : &:r77_1, ~mu58_4
# 77| r77_3(_Complex long double) = Convert : r77_2
# 77| r77_4(glval<_Complex long double>) = VariableAddress[cld] :
# 77| mu77_5(_Complex long double) = Store : &:r77_4, r77_3
# 78| r78_1(glval<_Complex long double>) = VariableAddress[cld] :
# 78| r78_2(_Complex long double) = Load : &:r78_1, ~mu58_4
# 78| r78_3(glval<_Complex long double>) = VariableAddress[cld] :
# 78| mu78_4(_Complex long double) = Store : &:r78_3, r78_2
# 81| r81_1(glval<float>) = VariableAddress[f] :
# 81| r81_2(float) = Load : &:r81_1, ~mu58_4
# 81| r81_3(_Complex float) = Convert : r81_2
# 81| r81_4(glval<_Complex float>) = VariableAddress[cf] :
# 81| mu81_5(_Complex float) = Store : &:r81_4, r81_3
# 82| r82_1(glval<double>) = VariableAddress[d] :
# 82| r82_2(double) = Load : &:r82_1, ~mu58_4
# 82| r82_3(_Complex float) = Convert : r82_2
# 82| r82_4(glval<_Complex float>) = VariableAddress[cf] :
# 82| mu82_5(_Complex float) = Store : &:r82_4, r82_3
# 83| r83_1(glval<long double>) = VariableAddress[ld] :
# 83| r83_2(long double) = Load : &:r83_1, ~mu58_4
# 83| r83_3(_Complex float) = Convert : r83_2
# 83| r83_4(glval<_Complex float>) = VariableAddress[cf] :
# 83| mu83_5(_Complex float) = Store : &:r83_4, r83_3
# 84| r84_1(glval<float>) = VariableAddress[f] :
# 84| r84_2(float) = Load : &:r84_1, ~mu58_4
# 84| r84_3(_Complex double) = Convert : r84_2
# 84| r84_4(glval<_Complex double>) = VariableAddress[cd] :
# 84| mu84_5(_Complex double) = Store : &:r84_4, r84_3
# 85| r85_1(glval<double>) = VariableAddress[d] :
# 85| r85_2(double) = Load : &:r85_1, ~mu58_4
# 85| r85_3(_Complex double) = Convert : r85_2
# 85| r85_4(glval<_Complex double>) = VariableAddress[cd] :
# 85| mu85_5(_Complex double) = Store : &:r85_4, r85_3
# 86| r86_1(glval<long double>) = VariableAddress[ld] :
# 86| r86_2(long double) = Load : &:r86_1, ~mu58_4
# 86| r86_3(_Complex double) = Convert : r86_2
# 86| r86_4(glval<_Complex double>) = VariableAddress[cd] :
# 86| mu86_5(_Complex double) = Store : &:r86_4, r86_3
# 87| r87_1(glval<float>) = VariableAddress[f] :
# 87| r87_2(float) = Load : &:r87_1, ~mu58_4
# 87| r87_3(_Complex long double) = Convert : r87_2
# 87| r87_4(glval<_Complex long double>) = VariableAddress[cld] :
# 87| mu87_5(_Complex long double) = Store : &:r87_4, r87_3
# 88| r88_1(glval<double>) = VariableAddress[d] :
# 88| r88_2(double) = Load : &:r88_1, ~mu58_4
# 88| r88_3(_Complex long double) = Convert : r88_2
# 88| r88_4(glval<_Complex long double>) = VariableAddress[cld] :
# 88| mu88_5(_Complex long double) = Store : &:r88_4, r88_3
# 89| r89_1(glval<long double>) = VariableAddress[ld] :
# 89| r89_2(long double) = Load : &:r89_1, ~mu58_4
# 89| r89_3(_Complex long double) = Convert : r89_2
# 89| r89_4(glval<_Complex long double>) = VariableAddress[cld] :
# 89| mu89_5(_Complex long double) = Store : &:r89_4, r89_3
# 92| r92_1(glval<_Complex float>) = VariableAddress[cf] :
# 92| r92_2(_Complex float) = Load : &:r92_1, ~mu58_4
# 92| r92_3(float) = Convert : r92_2
# 92| r92_4(glval<float>) = VariableAddress[f] :
# 92| mu92_5(float) = Store : &:r92_4, r92_3
# 93| r93_1(glval<_Complex double>) = VariableAddress[cd] :
# 93| r93_2(_Complex double) = Load : &:r93_1, ~mu58_4
# 93| r93_3(float) = Convert : r93_2
# 93| r93_4(glval<float>) = VariableAddress[f] :
# 93| mu93_5(float) = Store : &:r93_4, r93_3
# 94| r94_1(glval<_Complex long double>) = VariableAddress[cld] :
# 94| r94_2(_Complex long double) = Load : &:r94_1, ~mu58_4
# 94| r94_3(float) = Convert : r94_2
# 94| r94_4(glval<float>) = VariableAddress[f] :
# 94| mu94_5(float) = Store : &:r94_4, r94_3
# 95| r95_1(glval<_Complex float>) = VariableAddress[cf] :
# 95| r95_2(_Complex float) = Load : &:r95_1, ~mu58_4
# 95| r95_3(double) = Convert : r95_2
# 95| r95_4(glval<double>) = VariableAddress[d] :
# 95| mu95_5(double) = Store : &:r95_4, r95_3
# 96| r96_1(glval<_Complex double>) = VariableAddress[cd] :
# 96| r96_2(_Complex double) = Load : &:r96_1, ~mu58_4
# 96| r96_3(double) = Convert : r96_2
# 96| r96_4(glval<double>) = VariableAddress[d] :
# 96| mu96_5(double) = Store : &:r96_4, r96_3
# 97| r97_1(glval<_Complex long double>) = VariableAddress[cld] :
# 97| r97_2(_Complex long double) = Load : &:r97_1, ~mu58_4
# 97| r97_3(double) = Convert : r97_2
# 97| r97_4(glval<double>) = VariableAddress[d] :
# 97| mu97_5(double) = Store : &:r97_4, r97_3
# 98| r98_1(glval<_Complex float>) = VariableAddress[cf] :
# 98| r98_2(_Complex float) = Load : &:r98_1, ~mu58_4
# 98| r98_3(long double) = Convert : r98_2
# 98| r98_4(glval<long double>) = VariableAddress[ld] :
# 98| mu98_5(long double) = Store : &:r98_4, r98_3
# 99| r99_1(glval<_Complex double>) = VariableAddress[cd] :
# 99| r99_2(_Complex double) = Load : &:r99_1, ~mu58_4
# 99| r99_3(long double) = Convert : r99_2
# 99| r99_4(glval<long double>) = VariableAddress[ld] :
# 99| mu99_5(long double) = Store : &:r99_4, r99_3
# 100| r100_1(glval<_Complex long double>) = VariableAddress[cld] :
# 100| r100_2(_Complex long double) = Load : &:r100_1, ~mu58_4
# 100| r100_3(long double) = Convert : r100_2
# 100| r100_4(glval<long double>) = VariableAddress[ld] :
# 100| mu100_5(long double) = Store : &:r100_4, r100_3
# 103| r103_1(glval<_Imaginary float>) = VariableAddress[jf] :
# 103| r103_2(_Imaginary float) = Load : &:r103_1, ~mu58_4
# 103| r103_3(_Complex float) = Convert : r103_2
# 103| r103_4(glval<_Complex float>) = VariableAddress[cf] :
# 103| mu103_5(_Complex float) = Store : &:r103_4, r103_3
# 104| r104_1(glval<_Imaginary double>) = VariableAddress[jd] :
# 104| r104_2(_Imaginary double) = Load : &:r104_1, ~mu58_4
# 104| r104_3(_Complex float) = Convert : r104_2
# 104| r104_4(glval<_Complex float>) = VariableAddress[cf] :
# 104| mu104_5(_Complex float) = Store : &:r104_4, r104_3
# 105| r105_1(glval<_Imaginary long double>) = VariableAddress[jld] :
# 105| r105_2(_Imaginary long double) = Load : &:r105_1, ~mu58_4
# 105| r105_3(_Complex float) = Convert : r105_2
# 105| r105_4(glval<_Complex float>) = VariableAddress[cf] :
# 105| mu105_5(_Complex float) = Store : &:r105_4, r105_3
# 106| r106_1(glval<_Imaginary float>) = VariableAddress[jf] :
# 106| r106_2(_Imaginary float) = Load : &:r106_1, ~mu58_4
# 106| r106_3(_Complex double) = Convert : r106_2
# 106| r106_4(glval<_Complex double>) = VariableAddress[cd] :
# 106| mu106_5(_Complex double) = Store : &:r106_4, r106_3
# 107| r107_1(glval<_Imaginary double>) = VariableAddress[jd] :
# 107| r107_2(_Imaginary double) = Load : &:r107_1, ~mu58_4
# 107| r107_3(_Complex double) = Convert : r107_2
# 107| r107_4(glval<_Complex double>) = VariableAddress[cd] :
# 107| mu107_5(_Complex double) = Store : &:r107_4, r107_3
# 108| r108_1(glval<_Imaginary long double>) = VariableAddress[jld] :
# 108| r108_2(_Imaginary long double) = Load : &:r108_1, ~mu58_4
# 108| r108_3(_Complex double) = Convert : r108_2
# 108| r108_4(glval<_Complex double>) = VariableAddress[cd] :
# 108| mu108_5(_Complex double) = Store : &:r108_4, r108_3
# 109| r109_1(glval<_Imaginary float>) = VariableAddress[jf] :
# 109| r109_2(_Imaginary float) = Load : &:r109_1, ~mu58_4
# 109| r109_3(_Complex long double) = Convert : r109_2
# 109| r109_4(glval<_Complex long double>) = VariableAddress[cld] :
# 109| mu109_5(_Complex long double) = Store : &:r109_4, r109_3
# 110| r110_1(glval<_Imaginary double>) = VariableAddress[jd] :
# 110| r110_2(_Imaginary double) = Load : &:r110_1, ~mu58_4
# 110| r110_3(_Complex long double) = Convert : r110_2
# 110| r110_4(glval<_Complex long double>) = VariableAddress[cld] :
# 110| mu110_5(_Complex long double) = Store : &:r110_4, r110_3
# 111| r111_1(glval<_Imaginary long double>) = VariableAddress[jld] :
# 111| r111_2(_Imaginary long double) = Load : &:r111_1, ~mu58_4
# 111| r111_3(_Complex long double) = Convert : r111_2
# 111| r111_4(glval<_Complex long double>) = VariableAddress[cld] :
# 111| mu111_5(_Complex long double) = Store : &:r111_4, r111_3
# 114| r114_1(glval<_Complex float>) = VariableAddress[cf] :
# 114| r114_2(_Complex float) = Load : &:r114_1, ~mu58_4
# 114| r114_3(_Imaginary float) = Convert : r114_2
# 114| r114_4(glval<_Imaginary float>) = VariableAddress[jf] :
# 114| mu114_5(_Imaginary float) = Store : &:r114_4, r114_3
# 115| r115_1(glval<_Complex double>) = VariableAddress[cd] :
# 115| r115_2(_Complex double) = Load : &:r115_1, ~mu58_4
# 115| r115_3(_Imaginary float) = Convert : r115_2
# 115| r115_4(glval<_Imaginary float>) = VariableAddress[jf] :
# 115| mu115_5(_Imaginary float) = Store : &:r115_4, r115_3
# 116| r116_1(glval<_Complex long double>) = VariableAddress[cld] :
# 116| r116_2(_Complex long double) = Load : &:r116_1, ~mu58_4
# 116| r116_3(_Imaginary float) = Convert : r116_2
# 116| r116_4(glval<_Imaginary float>) = VariableAddress[jf] :
# 116| mu116_5(_Imaginary float) = Store : &:r116_4, r116_3
# 117| r117_1(glval<_Complex float>) = VariableAddress[cf] :
# 117| r117_2(_Complex float) = Load : &:r117_1, ~mu58_4
# 117| r117_3(_Imaginary double) = Convert : r117_2
# 117| r117_4(glval<_Imaginary double>) = VariableAddress[jd] :
# 117| mu117_5(_Imaginary double) = Store : &:r117_4, r117_3
# 118| r118_1(glval<_Complex double>) = VariableAddress[cd] :
# 118| r118_2(_Complex double) = Load : &:r118_1, ~mu58_4
# 118| r118_3(_Imaginary double) = Convert : r118_2
# 118| r118_4(glval<_Imaginary double>) = VariableAddress[jd] :
# 118| mu118_5(_Imaginary double) = Store : &:r118_4, r118_3
# 119| r119_1(glval<_Complex long double>) = VariableAddress[cld] :
# 119| r119_2(_Complex long double) = Load : &:r119_1, ~mu58_4
# 119| r119_3(_Imaginary double) = Convert : r119_2
# 119| r119_4(glval<_Imaginary double>) = VariableAddress[jd] :
# 119| mu119_5(_Imaginary double) = Store : &:r119_4, r119_3
# 120| r120_1(glval<_Complex float>) = VariableAddress[cf] :
# 120| r120_2(_Complex float) = Load : &:r120_1, ~mu58_4
# 120| r120_3(_Imaginary long double) = Convert : r120_2
# 120| r120_4(glval<_Imaginary long double>) = VariableAddress[jld] :
# 120| mu120_5(_Imaginary long double) = Store : &:r120_4, r120_3
# 121| r121_1(glval<_Complex double>) = VariableAddress[cd] :
# 121| r121_2(_Complex double) = Load : &:r121_1, ~mu58_4
# 121| r121_3(_Imaginary long double) = Convert : r121_2
# 121| r121_4(glval<_Imaginary long double>) = VariableAddress[jld] :
# 121| mu121_5(_Imaginary long double) = Store : &:r121_4, r121_3
# 122| r122_1(glval<_Complex long double>) = VariableAddress[cld] :
# 122| r122_2(_Complex long double) = Load : &:r122_1, ~mu58_4
# 122| r122_3(_Imaginary long double) = Convert : r122_2
# 122| r122_4(glval<_Imaginary long double>) = VariableAddress[jld] :
# 122| mu122_5(_Imaginary long double) = Store : &:r122_4, r122_3
# 125| r125_1(glval<float>) = VariableAddress[f] :
# 125| r125_2(float) = Load : &:r125_1, ~mu58_4
# 125| r125_3(_Imaginary float) = Convert : r125_2
# 125| r125_4(glval<_Imaginary float>) = VariableAddress[jf] :
# 125| mu125_5(_Imaginary float) = Store : &:r125_4, r125_3
# 126| r126_1(glval<double>) = VariableAddress[d] :
# 126| r126_2(double) = Load : &:r126_1, ~mu58_4
# 126| r126_3(_Imaginary float) = Convert : r126_2
# 126| r126_4(glval<_Imaginary float>) = VariableAddress[jf] :
# 126| mu126_5(_Imaginary float) = Store : &:r126_4, r126_3
# 127| r127_1(glval<long double>) = VariableAddress[ld] :
# 127| r127_2(long double) = Load : &:r127_1, ~mu58_4
# 127| r127_3(_Imaginary float) = Convert : r127_2
# 127| r127_4(glval<_Imaginary float>) = VariableAddress[jf] :
# 127| mu127_5(_Imaginary float) = Store : &:r127_4, r127_3
# 128| r128_1(glval<float>) = VariableAddress[f] :
# 128| r128_2(float) = Load : &:r128_1, ~mu58_4
# 128| r128_3(_Imaginary double) = Convert : r128_2
# 128| r128_4(glval<_Imaginary double>) = VariableAddress[jd] :
# 128| mu128_5(_Imaginary double) = Store : &:r128_4, r128_3
# 129| r129_1(glval<double>) = VariableAddress[d] :
# 129| r129_2(double) = Load : &:r129_1, ~mu58_4
# 129| r129_3(_Imaginary double) = Convert : r129_2
# 129| r129_4(glval<_Imaginary double>) = VariableAddress[jd] :
# 129| mu129_5(_Imaginary double) = Store : &:r129_4, r129_3
# 130| r130_1(glval<long double>) = VariableAddress[ld] :
# 130| r130_2(long double) = Load : &:r130_1, ~mu58_4
# 130| r130_3(_Imaginary double) = Convert : r130_2
# 130| r130_4(glval<_Imaginary double>) = VariableAddress[jd] :
# 130| mu130_5(_Imaginary double) = Store : &:r130_4, r130_3
# 131| r131_1(glval<float>) = VariableAddress[f] :
# 131| r131_2(float) = Load : &:r131_1, ~mu58_4
# 131| r131_3(_Imaginary long double) = Convert : r131_2
# 131| r131_4(glval<_Imaginary long double>) = VariableAddress[jld] :
# 131| mu131_5(_Imaginary long double) = Store : &:r131_4, r131_3
# 132| r132_1(glval<double>) = VariableAddress[d] :
# 132| r132_2(double) = Load : &:r132_1, ~mu58_4
# 132| r132_3(_Imaginary long double) = Convert : r132_2
# 132| r132_4(glval<_Imaginary long double>) = VariableAddress[jld] :
# 132| mu132_5(_Imaginary long double) = Store : &:r132_4, r132_3
# 133| r133_1(glval<long double>) = VariableAddress[ld] :
# 133| r133_2(long double) = Load : &:r133_1, ~mu58_4
# 133| r133_3(_Imaginary long double) = Convert : r133_2
# 133| r133_4(glval<_Imaginary long double>) = VariableAddress[jld] :
# 133| mu133_5(_Imaginary long double) = Store : &:r133_4, r133_3
# 136| r136_1(glval<_Imaginary float>) = VariableAddress[jf] :
# 136| r136_2(_Imaginary float) = Load : &:r136_1, ~mu58_4
# 136| r136_3(float) = Convert : r136_2
# 136| r136_4(glval<float>) = VariableAddress[f] :
# 136| mu136_5(float) = Store : &:r136_4, r136_3
# 137| r137_1(glval<_Imaginary double>) = VariableAddress[jd] :
# 137| r137_2(_Imaginary double) = Load : &:r137_1, ~mu58_4
# 137| r137_3(float) = Convert : r137_2
# 137| r137_4(glval<float>) = VariableAddress[f] :
# 137| mu137_5(float) = Store : &:r137_4, r137_3
# 138| r138_1(glval<_Imaginary long double>) = VariableAddress[jld] :
# 138| r138_2(_Imaginary long double) = Load : &:r138_1, ~mu58_4
# 138| r138_3(float) = Convert : r138_2
# 138| r138_4(glval<float>) = VariableAddress[f] :
# 138| mu138_5(float) = Store : &:r138_4, r138_3
# 139| r139_1(glval<_Imaginary float>) = VariableAddress[jf] :
# 139| r139_2(_Imaginary float) = Load : &:r139_1, ~mu58_4
# 139| r139_3(double) = Convert : r139_2
# 139| r139_4(glval<double>) = VariableAddress[d] :
# 139| mu139_5(double) = Store : &:r139_4, r139_3
# 140| r140_1(glval<_Imaginary double>) = VariableAddress[jd] :
# 140| r140_2(_Imaginary double) = Load : &:r140_1, ~mu58_4
# 140| r140_3(double) = Convert : r140_2
# 140| r140_4(glval<double>) = VariableAddress[d] :
# 140| mu140_5(double) = Store : &:r140_4, r140_3
# 141| r141_1(glval<_Imaginary long double>) = VariableAddress[jld] :
# 141| r141_2(_Imaginary long double) = Load : &:r141_1, ~mu58_4
# 141| r141_3(double) = Convert : r141_2
# 141| r141_4(glval<double>) = VariableAddress[d] :
# 141| mu141_5(double) = Store : &:r141_4, r141_3
# 142| r142_1(glval<_Imaginary float>) = VariableAddress[jf] :
# 142| r142_2(_Imaginary float) = Load : &:r142_1, ~mu58_4
# 142| r142_3(long double) = Convert : r142_2
# 142| r142_4(glval<long double>) = VariableAddress[ld] :
# 142| mu142_5(long double) = Store : &:r142_4, r142_3
# 143| r143_1(glval<_Imaginary double>) = VariableAddress[jd] :
# 143| r143_2(_Imaginary double) = Load : &:r143_1, ~mu58_4
# 143| r143_3(long double) = Convert : r143_2
# 143| r143_4(glval<long double>) = VariableAddress[ld] :
# 143| mu143_5(long double) = Store : &:r143_4, r143_3
# 144| r144_1(glval<_Imaginary long double>) = VariableAddress[jld] :
# 144| r144_2(_Imaginary long double) = Load : &:r144_1, ~mu58_4
# 144| r144_3(long double) = Convert : r144_2
# 144| r144_4(glval<long double>) = VariableAddress[ld] :
# 144| mu144_5(long double) = Store : &:r144_4, r144_3
# 145| v145_1(void) = NoOp :
# 58| v58_5(void) = ReturnVoid :
# 58| v58_6(void) = UnmodeledUse : mu*
# 58| v58_7(void) = AliasedUse : ~mu58_4
# 58| v58_8(void) = ExitFunction :
ir.cpp:
# 1| void Constants()
# 1| Block 0

View File

@@ -0,0 +1,15 @@
void Complex(void) {
_Complex float cf; //$irtype=cfloat8
_Complex double cd; //$irtype=cfloat16
_Complex long double cld; //$irtype=cfloat32
// _Complex __float128 cf128;
}
void Imaginary(void) {
_Imaginary float jf; //$irtype=ifloat4
_Imaginary double jd; //$irtype=ifloat8
_Imaginary long double jld; //$irtype=ifloat16
// _Imaginary __float128 jf128;
}
// semmle-extractor-options: --microsoft --edg --c99

View File

@@ -0,0 +1,65 @@
struct A {
int f_a;
};
struct B {
double f_a;
float f_b;
};
enum E {
Zero,
One,
Two,
Three
};
enum class ScopedE {
Zero,
One,
Two,
Three
};
void IRTypes() {
char c; //$irtype=int1
signed char sc; //$irtype=int1
unsigned char uc; //$irtype=uint1
short s; //$irtype=int2
signed short ss; //$irtype=int2
unsigned short us; //$irtype=uint2
int i; //$irtype=int4
signed int si; //$irtype=int4
unsigned int ui; //$irtype=uint4
long l; //$irtype=int8
signed long sl; //$irtype=int8
unsigned long ul; //$irtype=uint8
long long ll; //$irtype=int8
signed long long sll; //$irtype=int8
unsigned long long ull; //$irtype=uint8
bool b; //$irtype=bool1
float f; //$irtype=float4
double d; //$irtype=float8
long double ld; //$irtype=float16
__float128 f128; //$irtype=float16
wchar_t wc; //$irtype=uint4
// char8_t c8; //$irtype=uint1
char16_t c16; //$irtype=uint2
char32_t c32; //$irtype=uint4
int* pi; //$irtype=addr8
int& ri = i; //$irtype=addr8
void (*pfn)() = nullptr; //$irtype=func8
void (&rfn)() = IRTypes; //$irtype=func8
A s_a; //$irtype=opaque4{A}
B s_b; //$irtype=opaque16{B}
E e; //$irtype=uint4
ScopedE se; //$irtype=uint4
B a_b[10]; //$irtype=opaque160{B[10]}
}
// semmle-extractor-options: -std=c++17 --clang

View File

@@ -0,0 +1,18 @@
private import cpp
private import semmle.code.cpp.ir.implementation.raw.IR
import TestUtilities.InlineExpectationsTest
class IRTypesTest extends InlineExpectationsTest {
IRTypesTest() { this = "IRTypesTest" }
override string getARelevantTag() { result = "irtype" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(IRUserVariable irVar |
location = irVar.getLocation() and
element = irVar.toString() and
tag = "irtype" and
value = irVar.getIRType().toString()
)
}
}

View File

@@ -1,21 +1,21 @@
| ..()(..) | RoutineType | | | | |
| ..(*)(..) | FunctionPointerType | | ..()(..) | | |
| _Complex __float128 | FloatingPointType | | | | |
| _Complex double | FloatingPointType | | | | |
| _Complex float | FloatingPointType | | | | |
| _Complex long double | FloatingPointType | | | | |
| _Complex __float128 | BinaryFloatingPointType, ComplexNumberType | | | | |
| _Complex double | BinaryFloatingPointType, ComplexNumberType | | | | |
| _Complex float | BinaryFloatingPointType, ComplexNumberType | | | | |
| _Complex long double | BinaryFloatingPointType, ComplexNumberType | | | | |
| _Decimal32 | Decimal32Type | | | | |
| _Decimal64 | Decimal64Type | | | | |
| _Decimal128 | Decimal128Type | | | | |
| _Float32 | FloatingPointType | | | | |
| _Float32x | FloatingPointType | | | | |
| _Float64 | FloatingPointType | | | | |
| _Float64x | FloatingPointType | | | | |
| _Float128 | FloatingPointType | | | | |
| _Float128x | FloatingPointType | | | | |
| _Imaginary double | FloatingPointType | | | | |
| _Imaginary float | FloatingPointType | | | | |
| _Imaginary long double | FloatingPointType | | | | |
| _Float32 | BinaryFloatingPointType, RealNumberType | | | | |
| _Float32x | BinaryFloatingPointType, RealNumberType | | | | |
| _Float64 | BinaryFloatingPointType, RealNumberType | | | | |
| _Float64x | BinaryFloatingPointType, RealNumberType | | | | |
| _Float128 | BinaryFloatingPointType, RealNumberType | | | | |
| _Float128x | BinaryFloatingPointType, RealNumberType | | | | |
| _Imaginary double | BinaryFloatingPointType, ImaginaryNumberType | | | | |
| _Imaginary float | BinaryFloatingPointType, ImaginaryNumberType | | | | |
| _Imaginary long double | BinaryFloatingPointType, ImaginaryNumberType | | | | |
| __float128 | Float128Type | | | | |
| __int128 | Int128Type | | | | |
| __va_list_tag | DirectAccessHolder, MetricClass, Struct, StructLikeClass | | | | |