Merge pull request #2000 from AndreiDiaconu1/ircsharp-fixes

C# IR: Minor fixes and changes
This commit is contained in:
Calum Grant
2019-09-23 18:14:50 +01:00
committed by GitHub
4 changed files with 91 additions and 79 deletions

View File

@@ -194,8 +194,9 @@ predicate needsLoad(Expr expr) {
* Holds if we should ignore the `Load` instruction for `expr` when generating IR.
*/
private predicate ignoreLoad(Expr expr) {
// No load needed for the qualifier
// in an array access
// No load needed for the qualifier of an array access,
// since we use the instruction `ElementsAddress`
// to get the address of the first element in an array
expr = any(ArrayAccess aa).getQualifier()
or
// No load is needed for the lvalue in an assignment such as:
@@ -211,6 +212,9 @@ private predicate ignoreLoad(Expr expr) {
// address is the final value of the expression
expr.getParent() instanceof AddressOfExpr
or
// A property access does not need a load since it is a call
expr instanceof PropertyAccess
or
// If expr is a variable access used as the qualifier for a field access and
// its target variable is a value type variable,
// ignore the load since the address of a variable that is a value type is

View File

@@ -414,7 +414,7 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
this.getOpcode() instanceof Opcode::PointerAdd or
this.getOpcode() instanceof Opcode::PointerSub
) and
result = 4 //max(getResultType().(PointerType).getSize())
result = Language::getTypeSize(this.getResultType().(PointerType).getReferentType())
}
final TranslatedExpr getOperand() { result = getTranslatedExpr(expr.getOperand()) }
@@ -578,7 +578,6 @@ class TranslatedArrayAccess extends TranslatedNonConstantExpr {
(
// The successor of a `PointerAdd` is an `ElementsAddress` if
// that `PointerAdd` is not the last `PointerAdd` instruction.
index < getRank() - 1 and
tag = PointerAddTag(index) and
result = this.getInstruction(ElementsAddressTag(index + 1))
or
@@ -607,10 +606,7 @@ class TranslatedArrayAccess extends TranslatedNonConstantExpr {
result = this.getInstruction(PointerAddTag(child.getAST().getIndex()))
}
override Instruction getResult() {
result = this.getInstruction(PointerAddTag(getRank() - 1)) //and
//result.getResultType() = expr.getType()
}
override Instruction getResult() { result = this.getInstruction(PointerAddTag(getRank() - 1)) }
override predicate hasInstruction(
Opcode opcode, InstructionTag tag, Type resultType, boolean isLValue
@@ -663,12 +659,14 @@ class TranslatedArrayAccess extends TranslatedNonConstantExpr {
}
override int getInstructionElementSize(InstructionTag tag) {
tag = PointerAddTag(_) and
// TODO: Fix sizes once we have type sizes
result = 4
exists(int index |
inBounds(index) and
tag = PointerAddTag(index) and
result = Language::getTypeSize(expr.getQualifier().getType().(ArrayType).getElementType())
)
}
private TranslatedExpr getBaseOperand() { result = getTranslatedExpr(expr.getChild(-1)) }
private TranslatedExpr getBaseOperand() { result = getTranslatedExpr(expr.getQualifier()) }
private TranslatedExpr getOffsetOperand(int index) {
this.inBounds(index) and
@@ -1248,16 +1246,14 @@ class TranslatedBinaryOperation extends TranslatedSingleInstructionExpr {
opcode instanceof Opcode::PointerSub or
opcode instanceof Opcode::PointerDiff
) and
result = 8 //max(getPointerOperand().getResultType().(PointerType).getReferentType().getSize()) TODO: SIZE AGAIN
result = Language::getTypeSize(this.getPointerOperand().getResultType())
)
}
// private TranslatedExpr getPointerOperand() {
// if swapOperandsOnOp() then
// result = this.getRightOperand()
// else
// result = this.getLeftOperand()
// }
private TranslatedExpr getPointerOperand() {
if swapOperandsOnOp() then result = this.getRightOperand() else result = this.getLeftOperand()
}
private predicate swapOperandsOnOp() {
// Swap the operands on a pointer add 'i + p', so that the pointer operand
// always comes first. Note that we still evaluate the operands
@@ -1444,9 +1440,19 @@ class TranslatedAssignOperation extends TranslatedAssignment {
}
private Opcode getOpcode() {
expr instanceof AssignAddExpr and result instanceof Opcode::Add
expr instanceof AssignAddExpr and
(
if expr.getRValue().getType() instanceof PointerType
then result instanceof Opcode::PointerAdd
else result instanceof Opcode::Add
)
or
expr instanceof AssignSubExpr and result instanceof Opcode::Sub
expr instanceof AssignSubExpr and
(
if expr.getRValue().getType() instanceof PointerType
then result instanceof Opcode::PointerSub
else result instanceof Opcode::Sub
)
or
expr instanceof AssignMulExpr and result instanceof Opcode::Mul
or
@@ -1462,10 +1468,7 @@ class TranslatedAssignOperation extends TranslatedAssignment {
or
expr instanceof AssignLShiftExpr and result instanceof Opcode::ShiftLeft
or
expr instanceof AssignRShiftExpr and result instanceof Opcode::ShiftRight // or
// TODO: THE CASES ABOVE DEAL WITH POINTERS
// expr instanceof AssignPointerAddExpr and result instanceof Opcode::PointerAdd or
// expr instanceof AssignPointerSubExpr and result instanceof Opcode::PointerSub
expr instanceof AssignRShiftExpr and result instanceof Opcode::ShiftRight
}
override predicate hasInstruction(
@@ -1500,11 +1503,13 @@ class TranslatedAssignOperation extends TranslatedAssignment {
override int getInstructionElementSize(InstructionTag tag) {
tag = AssignOperationOpTag() and
exists(Opcode opcode |
opcode = getOpcode() and
// TODO: ADD AND SUB FOR POITNER ARITH (WAS POINTERADD AND POINTERSUB)
(opcode instanceof Opcode::Add or opcode instanceof Opcode::Sub)
opcode = this.getOpcode() and
(
opcode instanceof Opcode::PointerAdd or
opcode instanceof Opcode::PointerSub
)
) and
result = 8 //max(getResultType().(PointerType).getReferentType().getSize()) TODO: DEAL WITH SIZE
result = Language::getTypeSize(getResultType().(PointerType).getReferentType())
}
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {

View File

@@ -249,6 +249,11 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
)
}
override int getInstructionElementSize(InstructionTag tag) {
tag = getElementAddressTag() and
result = Language::getTypeSize(getElementType())
}
override string getInstructionConstantValue(InstructionTag tag) {
tag = getElementIndexTag() and
result = getElementIndex().toString()

View File

@@ -8,15 +8,15 @@ array.cs:
# 4| r0_4(glval<Int32[]>) = VariableAddress[one_dim] :
# 4| mu0_5(Int32[]) = Uninitialized[one_dim] : &:r0_4
# 4| r0_6(Int32) = Constant[0] :
# 4| r0_7(glval<Int32>) = PointerAdd : r0_4, r0_6
# 4| r0_7(glval<Int32>) = PointerAdd[4] : r0_4, r0_6
# 4| r0_8(Int32) = Constant[100] :
# 4| mu0_9(Int32) = Store : &:r0_7, r0_8
# 4| r0_10(Int32) = Constant[1] :
# 4| r0_11(glval<Int32>) = PointerAdd : r0_4, r0_10
# 4| r0_11(glval<Int32>) = PointerAdd[4] : r0_4, r0_10
# 4| r0_12(Int32) = Constant[101] :
# 4| mu0_13(Int32) = Store : &:r0_11, r0_12
# 4| r0_14(Int32) = Constant[2] :
# 4| r0_15(glval<Int32>) = PointerAdd : r0_4, r0_14
# 4| r0_15(glval<Int32>) = PointerAdd[4] : r0_4, r0_14
# 4| r0_16(Int32) = Constant[102] :
# 4| mu0_17(Int32) = Store : &:r0_15, r0_16
# 5| r0_18(Int32) = Constant[1000] :
@@ -64,23 +64,23 @@ array.cs:
# 15| r0_4(glval<Int32[,]>) = VariableAddress[a] :
# 15| mu0_5(Int32[,]) = Uninitialized[a] : &:r0_4
# 15| r0_6(Int32) = Constant[0] :
# 15| r0_7(glval<null>) = PointerAdd : r0_4, r0_6
# 15| r0_7(glval<null>) = PointerAdd[8] : r0_4, r0_6
# 15| r0_8(Int32) = Constant[0] :
# 15| r0_9(glval<Int32>) = PointerAdd : r0_7, r0_8
# 15| r0_9(glval<Int32>) = PointerAdd[4] : r0_7, r0_8
# 15| r0_10(Int32) = Constant[100] :
# 15| mu0_11(Int32) = Store : &:r0_9, r0_10
# 15| r0_12(Int32) = Constant[1] :
# 15| r0_13(glval<Int32>) = PointerAdd : r0_7, r0_12
# 15| r0_13(glval<Int32>) = PointerAdd[4] : r0_7, r0_12
# 15| r0_14(Int32) = Constant[101] :
# 15| mu0_15(Int32) = Store : &:r0_13, r0_14
# 15| r0_16(Int32) = Constant[1] :
# 15| r0_17(glval<null>) = PointerAdd : r0_4, r0_16
# 15| r0_17(glval<null>) = PointerAdd[8] : r0_4, r0_16
# 15| r0_18(Int32) = Constant[0] :
# 15| r0_19(glval<Int32>) = PointerAdd : r0_17, r0_18
# 15| r0_19(glval<Int32>) = PointerAdd[4] : r0_17, r0_18
# 15| r0_20(Int32) = Constant[102] :
# 15| mu0_21(Int32) = Store : &:r0_19, r0_20
# 15| r0_22(Int32) = Constant[1] :
# 15| r0_23(glval<Int32>) = PointerAdd : r0_17, r0_22
# 15| r0_23(glval<Int32>) = PointerAdd[4] : r0_17, r0_22
# 15| r0_24(Int32) = Constant[103] :
# 15| mu0_25(Int32) = Store : &:r0_23, r0_24
# 16| r0_26(glval<Int32[,]>) = VariableAddress[b] :
@@ -88,45 +88,45 @@ array.cs:
# 17| r0_28(glval<Int32[,]>) = VariableAddress[c] :
# 17| mu0_29(Int32[,]) = Uninitialized[c] : &:r0_28
# 17| r0_30(Int32) = Constant[0] :
# 17| r0_31(glval<null>) = PointerAdd : r0_28, r0_30
# 17| r0_31(glval<null>) = PointerAdd[8] : r0_28, r0_30
# 17| r0_32(Int32) = Constant[0] :
# 17| r0_33(glval<Int32>) = PointerAdd : r0_31, r0_32
# 17| r0_33(glval<Int32>) = PointerAdd[4] : r0_31, r0_32
# 17| r0_34(Int32) = Constant[100] :
# 17| mu0_35(Int32) = Store : &:r0_33, r0_34
# 17| r0_36(Int32) = Constant[1] :
# 17| r0_37(glval<Int32>) = PointerAdd : r0_31, r0_36
# 17| r0_37(glval<Int32>) = PointerAdd[4] : r0_31, r0_36
# 17| r0_38(Int32) = Constant[101] :
# 17| mu0_39(Int32) = Store : &:r0_37, r0_38
# 17| r0_40(Int32) = Constant[1] :
# 17| r0_41(glval<null>) = PointerAdd : r0_28, r0_40
# 17| r0_41(glval<null>) = PointerAdd[8] : r0_28, r0_40
# 17| r0_42(Int32) = Constant[0] :
# 17| r0_43(glval<Int32>) = PointerAdd : r0_41, r0_42
# 17| r0_43(glval<Int32>) = PointerAdd[4] : r0_41, r0_42
# 17| r0_44(Int32) = Constant[102] :
# 17| mu0_45(Int32) = Store : &:r0_43, r0_44
# 17| r0_46(Int32) = Constant[1] :
# 17| r0_47(glval<Int32>) = PointerAdd : r0_41, r0_46
# 17| r0_47(glval<Int32>) = PointerAdd[4] : r0_41, r0_46
# 17| r0_48(Int32) = Constant[103] :
# 17| mu0_49(Int32) = Store : &:r0_47, r0_48
# 18| r0_50(glval<Int32[,]>) = VariableAddress[d] :
# 18| mu0_51(Int32[,]) = Uninitialized[d] : &:r0_50
# 18| r0_52(Int32) = Constant[0] :
# 18| r0_53(glval<null>) = PointerAdd : r0_50, r0_52
# 18| r0_53(glval<null>) = PointerAdd[8] : r0_50, r0_52
# 18| r0_54(Int32) = Constant[0] :
# 18| r0_55(glval<Int32>) = PointerAdd : r0_53, r0_54
# 18| r0_55(glval<Int32>) = PointerAdd[4] : r0_53, r0_54
# 18| r0_56(Int32) = Constant[100] :
# 18| mu0_57(Int32) = Store : &:r0_55, r0_56
# 18| r0_58(Int32) = Constant[1] :
# 18| r0_59(glval<Int32>) = PointerAdd : r0_53, r0_58
# 18| r0_59(glval<Int32>) = PointerAdd[4] : r0_53, r0_58
# 18| r0_60(Int32) = Constant[101] :
# 18| mu0_61(Int32) = Store : &:r0_59, r0_60
# 18| r0_62(Int32) = Constant[1] :
# 18| r0_63(glval<null>) = PointerAdd : r0_50, r0_62
# 18| r0_63(glval<null>) = PointerAdd[8] : r0_50, r0_62
# 18| r0_64(Int32) = Constant[0] :
# 18| r0_65(glval<Int32>) = PointerAdd : r0_63, r0_64
# 18| r0_65(glval<Int32>) = PointerAdd[4] : r0_63, r0_64
# 18| r0_66(Int32) = Constant[102] :
# 18| mu0_67(Int32) = Store : &:r0_65, r0_66
# 18| r0_68(Int32) = Constant[1] :
# 18| r0_69(glval<Int32>) = PointerAdd : r0_63, r0_68
# 18| r0_69(glval<Int32>) = PointerAdd[4] : r0_63, r0_68
# 18| r0_70(Int32) = Constant[103] :
# 18| mu0_71(Int32) = Store : &:r0_69, r0_70
# 19| r0_72(glval<Int32[,]>) = VariableAddress[e] :
@@ -489,31 +489,31 @@ foreach.cs:
# 5| r0_3(glval<Int32[]>) = VariableAddress[a_array] :
# 5| mu0_4(Int32[]) = Uninitialized[a_array] : &:r0_3
# 5| r0_5(Int32) = Constant[0] :
# 5| r0_6(glval<Int32>) = PointerAdd : r0_3, r0_5
# 5| r0_6(glval<Int32>) = PointerAdd[4] : r0_3, r0_5
# 5| r0_7(Int32) = Constant[1] :
# 5| mu0_8(Int32) = Store : &:r0_6, r0_7
# 5| r0_9(Int32) = Constant[1] :
# 5| r0_10(glval<Int32>) = PointerAdd : r0_3, r0_9
# 5| r0_10(glval<Int32>) = PointerAdd[4] : r0_3, r0_9
# 5| r0_11(Int32) = Constant[2] :
# 5| mu0_12(Int32) = Store : &:r0_10, r0_11
# 5| r0_13(Int32) = Constant[2] :
# 5| r0_14(glval<Int32>) = PointerAdd : r0_3, r0_13
# 5| r0_14(glval<Int32>) = PointerAdd[4] : r0_3, r0_13
# 5| r0_15(Int32) = Constant[3] :
# 5| mu0_16(Int32) = Store : &:r0_14, r0_15
# 5| r0_17(Int32) = Constant[3] :
# 5| r0_18(glval<Int32>) = PointerAdd : r0_3, r0_17
# 5| r0_18(glval<Int32>) = PointerAdd[4] : r0_3, r0_17
# 5| r0_19(Int32) = Constant[4] :
# 5| mu0_20(Int32) = Store : &:r0_18, r0_19
# 5| r0_21(Int32) = Constant[4] :
# 5| r0_22(glval<Int32>) = PointerAdd : r0_3, r0_21
# 5| r0_22(glval<Int32>) = PointerAdd[4] : r0_3, r0_21
# 5| r0_23(Int32) = Constant[5] :
# 5| mu0_24(Int32) = Store : &:r0_22, r0_23
# 5| r0_25(Int32) = Constant[5] :
# 5| r0_26(glval<Int32>) = PointerAdd : r0_3, r0_25
# 5| r0_26(glval<Int32>) = PointerAdd[4] : r0_3, r0_25
# 5| r0_27(Int32) = Constant[6] :
# 5| mu0_28(Int32) = Store : &:r0_26, r0_27
# 5| r0_29(Int32) = Constant[6] :
# 5| r0_30(glval<Int32>) = PointerAdd : r0_3, r0_29
# 5| r0_30(glval<Int32>) = PointerAdd[4] : r0_3, r0_29
# 5| r0_31(Int32) = Constant[7] :
# 5| mu0_32(Int32) = Store : &:r0_30, r0_31
# 7| r0_33(glval<IEnumerator>) = VariableAddress[#temp7:9] :
@@ -1169,20 +1169,19 @@ pointers.cs:
# 5| r0_8(glval<null>) = FunctionAddress[get_Length] :
# 5| r0_9(Int32) = Call : func:r0_8, this:r0_7
# 5| mu0_10(null) = ^CallSideEffect : ~mu0_2
# 5| r0_11(Int32) = Load : &:r0_9, ~mu0_2
# 5| mu0_12(Int32) = Store : &:r0_5, r0_11
# 6| r0_13(glval<Int32*>) = VariableAddress[b] :
# 6| r0_14(glval<Int32[]>) = VariableAddress[arr] :
# 6| r0_15(Int32[]) = Load : &:r0_14, ~mu0_2
# 6| r0_16(Int32*) = Convert : r0_15
# 6| mu0_17(Int32*) = Store : &:r0_13, r0_15
# 8| r0_18(glval<Int32*>) = VariableAddress[p] :
# 8| r0_19(glval<Int32*>) = VariableAddress[b] :
# 8| r0_20(Int32*) = Load : &:r0_19, ~mu0_2
# 8| mu0_21(Int32*) = Store : &:r0_18, r0_20
# 9| r0_22(glval<Int32>) = VariableAddress[i] :
# 9| r0_23(Int32) = Constant[0] :
# 9| mu0_24(Int32) = Store : &:r0_22, r0_23
# 5| mu0_11(Int32) = Store : &:r0_5, r0_9
# 6| r0_12(glval<Int32*>) = VariableAddress[b] :
# 6| r0_13(glval<Int32[]>) = VariableAddress[arr] :
# 6| r0_14(Int32[]) = Load : &:r0_13, ~mu0_2
# 6| r0_15(Int32*) = Convert : r0_14
# 6| mu0_16(Int32*) = Store : &:r0_12, r0_14
# 8| r0_17(glval<Int32*>) = VariableAddress[p] :
# 8| r0_18(glval<Int32*>) = VariableAddress[b] :
# 8| r0_19(Int32*) = Load : &:r0_18, ~mu0_2
# 8| mu0_20(Int32*) = Store : &:r0_17, r0_19
# 9| r0_21(glval<Int32>) = VariableAddress[i] :
# 9| r0_22(Int32) = Constant[0] :
# 9| mu0_23(Int32) = Store : &:r0_21, r0_22
#-----| Goto -> Block 2
# 3| Block 1
@@ -1265,15 +1264,15 @@ pointers.cs:
# 39| r0_43(glval<Int32[]>) = VariableAddress[arr] :
# 39| mu0_44(Int32[]) = Uninitialized[arr] : &:r0_43
# 39| r0_45(Int32) = Constant[0] :
# 39| r0_46(glval<Int32>) = PointerAdd : r0_43, r0_45
# 39| r0_46(glval<Int32>) = PointerAdd[4] : r0_43, r0_45
# 39| r0_47(Int32) = Constant[1] :
# 39| mu0_48(Int32) = Store : &:r0_46, r0_47
# 39| r0_49(Int32) = Constant[1] :
# 39| r0_50(glval<Int32>) = PointerAdd : r0_43, r0_49
# 39| r0_50(glval<Int32>) = PointerAdd[4] : r0_43, r0_49
# 39| r0_51(Int32) = Constant[2] :
# 39| mu0_52(Int32) = Store : &:r0_50, r0_51
# 39| r0_53(Int32) = Constant[2] :
# 39| r0_54(glval<Int32>) = PointerAdd : r0_43, r0_53
# 39| r0_54(glval<Int32>) = PointerAdd[4] : r0_43, r0_53
# 39| r0_55(Int32) = Constant[3] :
# 39| mu0_56(Int32) = Store : &:r0_54, r0_55
# 40| r0_57(glval<null>) = FunctionAddress[addone] :
@@ -1357,11 +1356,10 @@ prop.cs:
# 30| r0_18(glval<null>) = FunctionAddress[get_Prop] :
# 30| r0_19(Int32) = Call : func:r0_18, this:r0_17
# 30| mu0_20(null) = ^CallSideEffect : ~mu0_2
# 30| r0_21(Int32) = Load : &:r0_19, ~mu0_2
# 30| mu0_22(Int32) = Store : &:r0_15, r0_21
# 26| v0_23(Void) = ReturnVoid :
# 26| v0_24(Void) = UnmodeledUse : mu*
# 26| v0_25(Void) = ExitFunction :
# 30| mu0_21(Int32) = Store : &:r0_15, r0_19
# 26| v0_22(Void) = ReturnVoid :
# 26| v0_23(Void) = UnmodeledUse : mu*
# 26| v0_24(Void) = ExitFunction :
simple_call.cs:
# 5| System.Int32 test_simple_call.f()