Skip to content

Commit 3c95205

Browse files
author
AndreiDiaconu1
committed
Minor fixes for array related translation
More accurate type sizes using language specific predicates from `IRCSharpLanguage.qll`. Added immediate operands for some `PointerX` (add, sub) instructions. Some other minor consistency fixes.
1 parent 7a57a3c commit 3c95205

File tree

4 files changed

+71
-60
lines changed

4 files changed

+71
-60
lines changed

csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,9 @@ predicate needsLoad(Expr expr) {
194194
* Holds if we should ignore the `Load` instruction for `expr` when generating IR.
195195
*/
196196
private predicate ignoreLoad(Expr expr) {
197-
// No load needed for the qualifier
198-
// in an array access
197+
// No load needed for the qualifier of an array access,
198+
// since we use the instruction `ElementsAddress`
199+
// to get the address of the first element in an array
199200
expr = any(ArrayAccess aa).getQualifier()
200201
or
201202
// No load is needed for the lvalue in an assignment such as:

csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/TranslatedExpr.qll

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
414414
this.getOpcode() instanceof Opcode::PointerAdd or
415415
this.getOpcode() instanceof Opcode::PointerSub
416416
) and
417-
result = 4 //max(getResultType().(PointerType).getSize())
417+
result = Language::getTypeSize(this.getResultType().(PointerType).getReferentType())
418418
}
419419

420420
final TranslatedExpr getOperand() { result = getTranslatedExpr(expr.getOperand()) }
@@ -578,7 +578,6 @@ class TranslatedArrayAccess extends TranslatedNonConstantExpr {
578578
(
579579
// The successor of a `PointerAdd` is an `ElementsAddress` if
580580
// that `PointerAdd` is not the last `PointerAdd` instruction.
581-
index < getRank() - 1 and
582581
tag = PointerAddTag(index) and
583582
result = this.getInstruction(ElementsAddressTag(index + 1))
584583
or
@@ -607,10 +606,7 @@ class TranslatedArrayAccess extends TranslatedNonConstantExpr {
607606
result = this.getInstruction(PointerAddTag(child.getAST().getIndex()))
608607
}
609608

610-
override Instruction getResult() {
611-
result = this.getInstruction(PointerAddTag(getRank() - 1)) //and
612-
//result.getResultType() = expr.getType()
613-
}
609+
override Instruction getResult() { result = this.getInstruction(PointerAddTag(getRank() - 1)) }
614610

615611
override predicate hasInstruction(
616612
Opcode opcode, InstructionTag tag, Type resultType, boolean isLValue
@@ -663,12 +659,14 @@ class TranslatedArrayAccess extends TranslatedNonConstantExpr {
663659
}
664660

665661
override int getInstructionElementSize(InstructionTag tag) {
666-
tag = PointerAddTag(_) and
667-
// TODO: Fix sizes once we have type sizes
668-
result = 4
662+
exists(int index |
663+
inBounds(index) and
664+
tag = PointerAddTag(index) and
665+
result = Language::getTypeSize(expr.getQualifier().getType().(ArrayType).getElementType())
666+
)
669667
}
670668

671-
private TranslatedExpr getBaseOperand() { result = getTranslatedExpr(expr.getChild(-1)) }
669+
private TranslatedExpr getBaseOperand() { result = getTranslatedExpr(expr.getQualifier()) }
672670

673671
private TranslatedExpr getOffsetOperand(int index) {
674672
this.inBounds(index) and
@@ -1248,16 +1246,14 @@ class TranslatedBinaryOperation extends TranslatedSingleInstructionExpr {
12481246
opcode instanceof Opcode::PointerSub or
12491247
opcode instanceof Opcode::PointerDiff
12501248
) and
1251-
result = 8 //max(getPointerOperand().getResultType().(PointerType).getReferentType().getSize()) TODO: SIZE AGAIN
1249+
result = Language::getTypeSize(this.getPointerOperand().getResultType())
12521250
)
12531251
}
12541252

1255-
// private TranslatedExpr getPointerOperand() {
1256-
// if swapOperandsOnOp() then
1257-
// result = this.getRightOperand()
1258-
// else
1259-
// result = this.getLeftOperand()
1260-
// }
1253+
private TranslatedExpr getPointerOperand() {
1254+
if swapOperandsOnOp() then result = this.getRightOperand() else result = this.getLeftOperand()
1255+
}
1256+
12611257
private predicate swapOperandsOnOp() {
12621258
// Swap the operands on a pointer add 'i + p', so that the pointer operand
12631259
// always comes first. Note that we still evaluate the operands
@@ -1444,9 +1440,19 @@ class TranslatedAssignOperation extends TranslatedAssignment {
14441440
}
14451441

14461442
private Opcode getOpcode() {
1447-
expr instanceof AssignAddExpr and result instanceof Opcode::Add
1443+
expr instanceof AssignAddExpr and
1444+
(
1445+
if expr.getRValue().getType() instanceof PointerType
1446+
then result instanceof Opcode::PointerAdd
1447+
else result instanceof Opcode::Add
1448+
)
14481449
or
1449-
expr instanceof AssignSubExpr and result instanceof Opcode::Sub
1450+
expr instanceof AssignSubExpr and
1451+
(
1452+
if expr.getRValue().getType() instanceof PointerType
1453+
then result instanceof Opcode::PointerSub
1454+
else result instanceof Opcode::Sub
1455+
)
14501456
or
14511457
expr instanceof AssignMulExpr and result instanceof Opcode::Mul
14521458
or
@@ -1462,10 +1468,7 @@ class TranslatedAssignOperation extends TranslatedAssignment {
14621468
or
14631469
expr instanceof AssignLShiftExpr and result instanceof Opcode::ShiftLeft
14641470
or
1465-
expr instanceof AssignRShiftExpr and result instanceof Opcode::ShiftRight // or
1466-
// TODO: THE CASES ABOVE DEAL WITH POINTERS
1467-
// expr instanceof AssignPointerAddExpr and result instanceof Opcode::PointerAdd or
1468-
// expr instanceof AssignPointerSubExpr and result instanceof Opcode::PointerSub
1471+
expr instanceof AssignRShiftExpr and result instanceof Opcode::ShiftRight
14691472
}
14701473

14711474
override predicate hasInstruction(
@@ -1500,11 +1503,13 @@ class TranslatedAssignOperation extends TranslatedAssignment {
15001503
override int getInstructionElementSize(InstructionTag tag) {
15011504
tag = AssignOperationOpTag() and
15021505
exists(Opcode opcode |
1503-
opcode = getOpcode() and
1504-
// TODO: ADD AND SUB FOR POITNER ARITH (WAS POINTERADD AND POINTERSUB)
1505-
(opcode instanceof Opcode::Add or opcode instanceof Opcode::Sub)
1506+
opcode = this.getOpcode() and
1507+
(
1508+
opcode instanceof Opcode::PointerAdd or
1509+
opcode instanceof Opcode::PointerSub
1510+
)
15061511
) and
1507-
result = 8 //max(getResultType().(PointerType).getReferentType().getSize()) TODO: DEAL WITH SIZE
1512+
result = Language::getTypeSize(getResultType().(PointerType).getReferentType())
15081513
}
15091514

15101515
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {

csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/TranslatedInitialization.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,11 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
249249
)
250250
}
251251

252+
override int getInstructionElementSize(InstructionTag tag) {
253+
tag = getElementAddressTag() and
254+
result = Language::getTypeSize(getElementType())
255+
}
256+
252257
override string getInstructionConstantValue(InstructionTag tag) {
253258
tag = getElementIndexTag() and
254259
result = getElementIndex().toString()

csharp/ql/test/library-tests/ir/ir/raw_ir.expected

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ array.cs:
88
# 4| r0_4(glval<Int32[]>) = VariableAddress[one_dim] :
99
# 4| mu0_5(Int32[]) = Uninitialized[one_dim] : &:r0_4
1010
# 4| r0_6(Int32) = Constant[0] :
11-
# 4| r0_7(glval<Int32>) = PointerAdd : r0_4, r0_6
11+
# 4| r0_7(glval<Int32>) = PointerAdd[4] : r0_4, r0_6
1212
# 4| r0_8(Int32) = Constant[100] :
1313
# 4| mu0_9(Int32) = Store : &:r0_7, r0_8
1414
# 4| r0_10(Int32) = Constant[1] :
15-
# 4| r0_11(glval<Int32>) = PointerAdd : r0_4, r0_10
15+
# 4| r0_11(glval<Int32>) = PointerAdd[4] : r0_4, r0_10
1616
# 4| r0_12(Int32) = Constant[101] :
1717
# 4| mu0_13(Int32) = Store : &:r0_11, r0_12
1818
# 4| r0_14(Int32) = Constant[2] :
19-
# 4| r0_15(glval<Int32>) = PointerAdd : r0_4, r0_14
19+
# 4| r0_15(glval<Int32>) = PointerAdd[4] : r0_4, r0_14
2020
# 4| r0_16(Int32) = Constant[102] :
2121
# 4| mu0_17(Int32) = Store : &:r0_15, r0_16
2222
# 5| r0_18(Int32) = Constant[1000] :
@@ -64,69 +64,69 @@ array.cs:
6464
# 15| r0_4(glval<Int32[,]>) = VariableAddress[a] :
6565
# 15| mu0_5(Int32[,]) = Uninitialized[a] : &:r0_4
6666
# 15| r0_6(Int32) = Constant[0] :
67-
# 15| r0_7(glval<null>) = PointerAdd : r0_4, r0_6
67+
# 15| r0_7(glval<null>) = PointerAdd[8] : r0_4, r0_6
6868
# 15| r0_8(Int32) = Constant[0] :
69-
# 15| r0_9(glval<Int32>) = PointerAdd : r0_7, r0_8
69+
# 15| r0_9(glval<Int32>) = PointerAdd[4] : r0_7, r0_8
7070
# 15| r0_10(Int32) = Constant[100] :
7171
# 15| mu0_11(Int32) = Store : &:r0_9, r0_10
7272
# 15| r0_12(Int32) = Constant[1] :
73-
# 15| r0_13(glval<Int32>) = PointerAdd : r0_7, r0_12
73+
# 15| r0_13(glval<Int32>) = PointerAdd[4] : r0_7, r0_12
7474
# 15| r0_14(Int32) = Constant[101] :
7575
# 15| mu0_15(Int32) = Store : &:r0_13, r0_14
7676
# 15| r0_16(Int32) = Constant[1] :
77-
# 15| r0_17(glval<null>) = PointerAdd : r0_4, r0_16
77+
# 15| r0_17(glval<null>) = PointerAdd[8] : r0_4, r0_16
7878
# 15| r0_18(Int32) = Constant[0] :
79-
# 15| r0_19(glval<Int32>) = PointerAdd : r0_17, r0_18
79+
# 15| r0_19(glval<Int32>) = PointerAdd[4] : r0_17, r0_18
8080
# 15| r0_20(Int32) = Constant[102] :
8181
# 15| mu0_21(Int32) = Store : &:r0_19, r0_20
8282
# 15| r0_22(Int32) = Constant[1] :
83-
# 15| r0_23(glval<Int32>) = PointerAdd : r0_17, r0_22
83+
# 15| r0_23(glval<Int32>) = PointerAdd[4] : r0_17, r0_22
8484
# 15| r0_24(Int32) = Constant[103] :
8585
# 15| mu0_25(Int32) = Store : &:r0_23, r0_24
8686
# 16| r0_26(glval<Int32[,]>) = VariableAddress[b] :
8787
# 16| mu0_27(Int32[,]) = Uninitialized[b] : &:r0_26
8888
# 17| r0_28(glval<Int32[,]>) = VariableAddress[c] :
8989
# 17| mu0_29(Int32[,]) = Uninitialized[c] : &:r0_28
9090
# 17| r0_30(Int32) = Constant[0] :
91-
# 17| r0_31(glval<null>) = PointerAdd : r0_28, r0_30
91+
# 17| r0_31(glval<null>) = PointerAdd[8] : r0_28, r0_30
9292
# 17| r0_32(Int32) = Constant[0] :
93-
# 17| r0_33(glval<Int32>) = PointerAdd : r0_31, r0_32
93+
# 17| r0_33(glval<Int32>) = PointerAdd[4] : r0_31, r0_32
9494
# 17| r0_34(Int32) = Constant[100] :
9595
# 17| mu0_35(Int32) = Store : &:r0_33, r0_34
9696
# 17| r0_36(Int32) = Constant[1] :
97-
# 17| r0_37(glval<Int32>) = PointerAdd : r0_31, r0_36
97+
# 17| r0_37(glval<Int32>) = PointerAdd[4] : r0_31, r0_36
9898
# 17| r0_38(Int32) = Constant[101] :
9999
# 17| mu0_39(Int32) = Store : &:r0_37, r0_38
100100
# 17| r0_40(Int32) = Constant[1] :
101-
# 17| r0_41(glval<null>) = PointerAdd : r0_28, r0_40
101+
# 17| r0_41(glval<null>) = PointerAdd[8] : r0_28, r0_40
102102
# 17| r0_42(Int32) = Constant[0] :
103-
# 17| r0_43(glval<Int32>) = PointerAdd : r0_41, r0_42
103+
# 17| r0_43(glval<Int32>) = PointerAdd[4] : r0_41, r0_42
104104
# 17| r0_44(Int32) = Constant[102] :
105105
# 17| mu0_45(Int32) = Store : &:r0_43, r0_44
106106
# 17| r0_46(Int32) = Constant[1] :
107-
# 17| r0_47(glval<Int32>) = PointerAdd : r0_41, r0_46
107+
# 17| r0_47(glval<Int32>) = PointerAdd[4] : r0_41, r0_46
108108
# 17| r0_48(Int32) = Constant[103] :
109109
# 17| mu0_49(Int32) = Store : &:r0_47, r0_48
110110
# 18| r0_50(glval<Int32[,]>) = VariableAddress[d] :
111111
# 18| mu0_51(Int32[,]) = Uninitialized[d] : &:r0_50
112112
# 18| r0_52(Int32) = Constant[0] :
113-
# 18| r0_53(glval<null>) = PointerAdd : r0_50, r0_52
113+
# 18| r0_53(glval<null>) = PointerAdd[8] : r0_50, r0_52
114114
# 18| r0_54(Int32) = Constant[0] :
115-
# 18| r0_55(glval<Int32>) = PointerAdd : r0_53, r0_54
115+
# 18| r0_55(glval<Int32>) = PointerAdd[4] : r0_53, r0_54
116116
# 18| r0_56(Int32) = Constant[100] :
117117
# 18| mu0_57(Int32) = Store : &:r0_55, r0_56
118118
# 18| r0_58(Int32) = Constant[1] :
119-
# 18| r0_59(glval<Int32>) = PointerAdd : r0_53, r0_58
119+
# 18| r0_59(glval<Int32>) = PointerAdd[4] : r0_53, r0_58
120120
# 18| r0_60(Int32) = Constant[101] :
121121
# 18| mu0_61(Int32) = Store : &:r0_59, r0_60
122122
# 18| r0_62(Int32) = Constant[1] :
123-
# 18| r0_63(glval<null>) = PointerAdd : r0_50, r0_62
123+
# 18| r0_63(glval<null>) = PointerAdd[8] : r0_50, r0_62
124124
# 18| r0_64(Int32) = Constant[0] :
125-
# 18| r0_65(glval<Int32>) = PointerAdd : r0_63, r0_64
125+
# 18| r0_65(glval<Int32>) = PointerAdd[4] : r0_63, r0_64
126126
# 18| r0_66(Int32) = Constant[102] :
127127
# 18| mu0_67(Int32) = Store : &:r0_65, r0_66
128128
# 18| r0_68(Int32) = Constant[1] :
129-
# 18| r0_69(glval<Int32>) = PointerAdd : r0_63, r0_68
129+
# 18| r0_69(glval<Int32>) = PointerAdd[4] : r0_63, r0_68
130130
# 18| r0_70(Int32) = Constant[103] :
131131
# 18| mu0_71(Int32) = Store : &:r0_69, r0_70
132132
# 19| r0_72(glval<Int32[,]>) = VariableAddress[e] :
@@ -489,31 +489,31 @@ foreach.cs:
489489
# 5| r0_3(glval<Int32[]>) = VariableAddress[a_array] :
490490
# 5| mu0_4(Int32[]) = Uninitialized[a_array] : &:r0_3
491491
# 5| r0_5(Int32) = Constant[0] :
492-
# 5| r0_6(glval<Int32>) = PointerAdd : r0_3, r0_5
492+
# 5| r0_6(glval<Int32>) = PointerAdd[4] : r0_3, r0_5
493493
# 5| r0_7(Int32) = Constant[1] :
494494
# 5| mu0_8(Int32) = Store : &:r0_6, r0_7
495495
# 5| r0_9(Int32) = Constant[1] :
496-
# 5| r0_10(glval<Int32>) = PointerAdd : r0_3, r0_9
496+
# 5| r0_10(glval<Int32>) = PointerAdd[4] : r0_3, r0_9
497497
# 5| r0_11(Int32) = Constant[2] :
498498
# 5| mu0_12(Int32) = Store : &:r0_10, r0_11
499499
# 5| r0_13(Int32) = Constant[2] :
500-
# 5| r0_14(glval<Int32>) = PointerAdd : r0_3, r0_13
500+
# 5| r0_14(glval<Int32>) = PointerAdd[4] : r0_3, r0_13
501501
# 5| r0_15(Int32) = Constant[3] :
502502
# 5| mu0_16(Int32) = Store : &:r0_14, r0_15
503503
# 5| r0_17(Int32) = Constant[3] :
504-
# 5| r0_18(glval<Int32>) = PointerAdd : r0_3, r0_17
504+
# 5| r0_18(glval<Int32>) = PointerAdd[4] : r0_3, r0_17
505505
# 5| r0_19(Int32) = Constant[4] :
506506
# 5| mu0_20(Int32) = Store : &:r0_18, r0_19
507507
# 5| r0_21(Int32) = Constant[4] :
508-
# 5| r0_22(glval<Int32>) = PointerAdd : r0_3, r0_21
508+
# 5| r0_22(glval<Int32>) = PointerAdd[4] : r0_3, r0_21
509509
# 5| r0_23(Int32) = Constant[5] :
510510
# 5| mu0_24(Int32) = Store : &:r0_22, r0_23
511511
# 5| r0_25(Int32) = Constant[5] :
512-
# 5| r0_26(glval<Int32>) = PointerAdd : r0_3, r0_25
512+
# 5| r0_26(glval<Int32>) = PointerAdd[4] : r0_3, r0_25
513513
# 5| r0_27(Int32) = Constant[6] :
514514
# 5| mu0_28(Int32) = Store : &:r0_26, r0_27
515515
# 5| r0_29(Int32) = Constant[6] :
516-
# 5| r0_30(glval<Int32>) = PointerAdd : r0_3, r0_29
516+
# 5| r0_30(glval<Int32>) = PointerAdd[4] : r0_3, r0_29
517517
# 5| r0_31(Int32) = Constant[7] :
518518
# 5| mu0_32(Int32) = Store : &:r0_30, r0_31
519519
# 7| r0_33(glval<IEnumerator>) = VariableAddress[#temp7:9] :
@@ -1265,15 +1265,15 @@ pointers.cs:
12651265
# 39| r0_43(glval<Int32[]>) = VariableAddress[arr] :
12661266
# 39| mu0_44(Int32[]) = Uninitialized[arr] : &:r0_43
12671267
# 39| r0_45(Int32) = Constant[0] :
1268-
# 39| r0_46(glval<Int32>) = PointerAdd : r0_43, r0_45
1268+
# 39| r0_46(glval<Int32>) = PointerAdd[4] : r0_43, r0_45
12691269
# 39| r0_47(Int32) = Constant[1] :
12701270
# 39| mu0_48(Int32) = Store : &:r0_46, r0_47
12711271
# 39| r0_49(Int32) = Constant[1] :
1272-
# 39| r0_50(glval<Int32>) = PointerAdd : r0_43, r0_49
1272+
# 39| r0_50(glval<Int32>) = PointerAdd[4] : r0_43, r0_49
12731273
# 39| r0_51(Int32) = Constant[2] :
12741274
# 39| mu0_52(Int32) = Store : &:r0_50, r0_51
12751275
# 39| r0_53(Int32) = Constant[2] :
1276-
# 39| r0_54(glval<Int32>) = PointerAdd : r0_43, r0_53
1276+
# 39| r0_54(glval<Int32>) = PointerAdd[4] : r0_43, r0_53
12771277
# 39| r0_55(Int32) = Constant[3] :
12781278
# 39| mu0_56(Int32) = Store : &:r0_54, r0_55
12791279
# 40| r0_57(glval<null>) = FunctionAddress[addone] :

0 commit comments

Comments
 (0)