Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4775051

Browse files
author
AndreiDiaconu1
committed
Address PR comment and fix bug
Fixes a bug where loads for array indexes would be ignored, even though the only ignored load in an array access should be the qualifier's.
1 parent fa74ed3 commit 4775051

4 files changed

Lines changed: 116 additions & 102 deletions

File tree

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ private predicate usedAsCondition(Expr expr) {
177177
/**
178178
* Holds if we should have a `Load` instruction for `expr` when generating the IR.
179179
*/
180-
predicate needsLoad(Expr expr) {
180+
predicate mayNeedLoad(Expr expr) {
181181
expr instanceof AssignableRead
182182
or
183183
// We need an extra load for the `PointerIndirectionExpr`
@@ -187,12 +187,18 @@ predicate needsLoad(Expr expr) {
187187
not exists(Assignment a | a.getLValue() = expr)
188188
}
189189

190+
predicate needsLoad(Expr expr) {
191+
mayNeedLoad(expr) and
192+
not ignoreLoad(expr)
193+
}
194+
190195
/**
191196
* Holds if we should ignore the `Load` instruction for `expr` when generating IR.
192197
*/
193198
predicate ignoreLoad(Expr expr) {
194-
// No load needed for an array access
195-
expr.getParent() instanceof ArrayAccess
199+
// No load needed for the qualifier
200+
// in an array access
201+
expr = any(ArrayAccess aa).getQualifier()
196202
or
197203
// No load is needed for the lvalue in an assignment such as:
198204
// Eg. `Object obj = oldObj`;
@@ -241,7 +247,6 @@ newtype TTranslatedElement =
241247
// expression.
242248
TTranslatedLoad(Expr expr) {
243249
not ignoreExpr(expr) and
244-
not ignoreLoad(expr) and
245250
needsLoad(expr)
246251
} or
247252
// An expression most naturally translated as control flow.

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,6 @@ abstract class TranslatedCoreExpr extends TranslatedExpr {
9494
final override predicate producesExprResult() {
9595
// If the expr needs a load, its translation does not produce the final value.
9696
not needsLoad(expr)
97-
or
98-
// If we're supposed to ignore the load on this expression, then this
99-
// expression produces the final value.
100-
ignoreLoad(expr)
10197
}
10298

10399
/**

csharp/ql/test/library-tests/ir/ir/array.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ public void one_dim_init_acc()
55
one_dim[0] = 1000;
66
one_dim[1] = one_dim[0];
77
one_dim[1] = 1003;
8+
9+
int i = 0;
10+
one_dim[i] = 0;
811
}
912

1013
public void twod_and_init_acc()

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

Lines changed: 104 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -41,100 +41,110 @@ array.cs:
4141
# 7| r0_37(Int32) = Constant[1] :
4242
# 7| r0_38(Int32[]) = PointerAdd[4] : r0_36, r0_37
4343
# 7| mu0_39(Int32) = Store : &:r0_38, r0_34
44-
# 2| v0_40(Void) = ReturnVoid :
45-
# 2| v0_41(Void) = UnmodeledUse : mu*
46-
# 2| v0_42(Void) = ExitFunction :
47-
48-
# 10| System.Void ArrayTest.twod_and_init_acc()
49-
# 10| Block 0
50-
# 10| v0_0(Void) = EnterFunction :
51-
# 10| mu0_1(null) = AliasedDefinition :
52-
# 10| mu0_2(null) = UnmodeledDefinition :
53-
# 10| r0_3(glval<ArrayTest>) = InitializeThis :
54-
# 12| r0_4(glval<Int32[,]>) = VariableAddress[a] :
55-
# 12| mu0_5(Int32[,]) = Uninitialized[a] : &:r0_4
56-
# 12| r0_6(Int32) = Constant[0] :
57-
# 12| r0_7(glval<null>) = PointerAdd : r0_4, r0_6
58-
# 12| r0_8(Int32) = Constant[0] :
59-
# 12| r0_9(glval<Int32>) = PointerAdd : r0_7, r0_8
60-
# 12| r0_10(Int32) = Constant[100] :
61-
# 12| mu0_11(Int32) = Store : &:r0_9, r0_10
62-
# 12| r0_12(Int32) = Constant[1] :
63-
# 12| r0_13(glval<Int32>) = PointerAdd : r0_7, r0_12
64-
# 12| r0_14(Int32) = Constant[101] :
65-
# 12| mu0_15(Int32) = Store : &:r0_13, r0_14
66-
# 12| r0_16(Int32) = Constant[1] :
67-
# 12| r0_17(glval<null>) = PointerAdd : r0_4, r0_16
68-
# 12| r0_18(Int32) = Constant[0] :
69-
# 12| r0_19(glval<Int32>) = PointerAdd : r0_17, r0_18
70-
# 12| r0_20(Int32) = Constant[102] :
71-
# 12| mu0_21(Int32) = Store : &:r0_19, r0_20
72-
# 12| r0_22(Int32) = Constant[1] :
73-
# 12| r0_23(glval<Int32>) = PointerAdd : r0_17, r0_22
74-
# 12| r0_24(Int32) = Constant[103] :
75-
# 12| mu0_25(Int32) = Store : &:r0_23, r0_24
76-
# 13| r0_26(glval<Int32[,]>) = VariableAddress[b] :
77-
# 13| mu0_27(Int32[,]) = Uninitialized[b] : &:r0_26
78-
# 14| r0_28(glval<Int32[,]>) = VariableAddress[c] :
79-
# 14| mu0_29(Int32[,]) = Uninitialized[c] : &:r0_28
80-
# 14| r0_30(Int32) = Constant[0] :
81-
# 14| r0_31(glval<null>) = PointerAdd : r0_28, r0_30
82-
# 14| r0_32(Int32) = Constant[0] :
83-
# 14| r0_33(glval<Int32>) = PointerAdd : r0_31, r0_32
84-
# 14| r0_34(Int32) = Constant[100] :
85-
# 14| mu0_35(Int32) = Store : &:r0_33, r0_34
86-
# 14| r0_36(Int32) = Constant[1] :
87-
# 14| r0_37(glval<Int32>) = PointerAdd : r0_31, r0_36
88-
# 14| r0_38(Int32) = Constant[101] :
89-
# 14| mu0_39(Int32) = Store : &:r0_37, r0_38
90-
# 14| r0_40(Int32) = Constant[1] :
91-
# 14| r0_41(glval<null>) = PointerAdd : r0_28, r0_40
92-
# 14| r0_42(Int32) = Constant[0] :
93-
# 14| r0_43(glval<Int32>) = PointerAdd : r0_41, r0_42
94-
# 14| r0_44(Int32) = Constant[102] :
95-
# 14| mu0_45(Int32) = Store : &:r0_43, r0_44
96-
# 14| r0_46(Int32) = Constant[1] :
97-
# 14| r0_47(glval<Int32>) = PointerAdd : r0_41, r0_46
98-
# 14| r0_48(Int32) = Constant[103] :
99-
# 14| mu0_49(Int32) = Store : &:r0_47, r0_48
100-
# 15| r0_50(glval<Int32[,]>) = VariableAddress[d] :
101-
# 15| mu0_51(Int32[,]) = Uninitialized[d] : &:r0_50
102-
# 15| r0_52(Int32) = Constant[0] :
103-
# 15| r0_53(glval<null>) = PointerAdd : r0_50, r0_52
104-
# 15| r0_54(Int32) = Constant[0] :
105-
# 15| r0_55(glval<Int32>) = PointerAdd : r0_53, r0_54
106-
# 15| r0_56(Int32) = Constant[100] :
107-
# 15| mu0_57(Int32) = Store : &:r0_55, r0_56
108-
# 15| r0_58(Int32) = Constant[1] :
109-
# 15| r0_59(glval<Int32>) = PointerAdd : r0_53, r0_58
110-
# 15| r0_60(Int32) = Constant[101] :
111-
# 15| mu0_61(Int32) = Store : &:r0_59, r0_60
112-
# 15| r0_62(Int32) = Constant[1] :
113-
# 15| r0_63(glval<null>) = PointerAdd : r0_50, r0_62
114-
# 15| r0_64(Int32) = Constant[0] :
115-
# 15| r0_65(glval<Int32>) = PointerAdd : r0_63, r0_64
116-
# 15| r0_66(Int32) = Constant[102] :
117-
# 15| mu0_67(Int32) = Store : &:r0_65, r0_66
118-
# 15| r0_68(Int32) = Constant[1] :
119-
# 15| r0_69(glval<Int32>) = PointerAdd : r0_63, r0_68
120-
# 15| r0_70(Int32) = Constant[103] :
121-
# 15| mu0_71(Int32) = Store : &:r0_69, r0_70
122-
# 16| r0_72(glval<Int32[,]>) = VariableAddress[e] :
123-
# 16| r0_73(glval<Int32[,]>) = VariableAddress[a] :
124-
# 16| r0_74(Int32[,]) = Load : &:r0_73, ~mu0_2
125-
# 16| mu0_75(Int32[,]) = Store : &:r0_72, r0_74
126-
# 17| r0_76(Int32) = Constant[-1] :
127-
# 17| r0_77(glval<Int32[,]>) = VariableAddress[e] :
128-
# 17| r0_78(Int32[,]) = ElementsAddress : r0_77
129-
# 17| r0_79(Int32) = Constant[1] :
130-
# 17| r0_80(Int32[,]) = PointerAdd[4] : r0_78, r0_79
131-
# 17| r0_81(Int32[]) = ElementsAddress : r0_80
132-
# 17| r0_82(Int32) = Constant[1] :
133-
# 17| r0_83(Int32[]) = PointerAdd[4] : r0_81, r0_82
134-
# 17| mu0_84(Int32) = Store : &:r0_83, r0_76
135-
# 10| v0_85(Void) = ReturnVoid :
136-
# 10| v0_86(Void) = UnmodeledUse : mu*
137-
# 10| v0_87(Void) = ExitFunction :
44+
# 9| r0_40(glval<Int32>) = VariableAddress[i] :
45+
# 9| r0_41(Int32) = Constant[0] :
46+
# 9| mu0_42(Int32) = Store : &:r0_40, r0_41
47+
# 10| r0_43(Int32) = Constant[0] :
48+
# 10| r0_44(glval<Int32[]>) = VariableAddress[one_dim] :
49+
# 10| r0_45(Int32[]) = ElementsAddress : r0_44
50+
# 10| r0_46(glval<Int32>) = VariableAddress[i] :
51+
# 10| r0_47(Int32) = Load : &:r0_46, ~mu0_2
52+
# 10| r0_48(Int32[]) = PointerAdd[4] : r0_45, r0_47
53+
# 10| mu0_49(Int32) = Store : &:r0_48, r0_43
54+
# 2| v0_50(Void) = ReturnVoid :
55+
# 2| v0_51(Void) = UnmodeledUse : mu*
56+
# 2| v0_52(Void) = ExitFunction :
57+
58+
# 13| System.Void ArrayTest.twod_and_init_acc()
59+
# 13| Block 0
60+
# 13| v0_0(Void) = EnterFunction :
61+
# 13| mu0_1(null) = AliasedDefinition :
62+
# 13| mu0_2(null) = UnmodeledDefinition :
63+
# 13| r0_3(glval<ArrayTest>) = InitializeThis :
64+
# 15| r0_4(glval<Int32[,]>) = VariableAddress[a] :
65+
# 15| mu0_5(Int32[,]) = Uninitialized[a] : &:r0_4
66+
# 15| r0_6(Int32) = Constant[0] :
67+
# 15| r0_7(glval<null>) = PointerAdd : r0_4, r0_6
68+
# 15| r0_8(Int32) = Constant[0] :
69+
# 15| r0_9(glval<Int32>) = PointerAdd : r0_7, r0_8
70+
# 15| r0_10(Int32) = Constant[100] :
71+
# 15| mu0_11(Int32) = Store : &:r0_9, r0_10
72+
# 15| r0_12(Int32) = Constant[1] :
73+
# 15| r0_13(glval<Int32>) = PointerAdd : r0_7, r0_12
74+
# 15| r0_14(Int32) = Constant[101] :
75+
# 15| mu0_15(Int32) = Store : &:r0_13, r0_14
76+
# 15| r0_16(Int32) = Constant[1] :
77+
# 15| r0_17(glval<null>) = PointerAdd : r0_4, r0_16
78+
# 15| r0_18(Int32) = Constant[0] :
79+
# 15| r0_19(glval<Int32>) = PointerAdd : r0_17, r0_18
80+
# 15| r0_20(Int32) = Constant[102] :
81+
# 15| mu0_21(Int32) = Store : &:r0_19, r0_20
82+
# 15| r0_22(Int32) = Constant[1] :
83+
# 15| r0_23(glval<Int32>) = PointerAdd : r0_17, r0_22
84+
# 15| r0_24(Int32) = Constant[103] :
85+
# 15| mu0_25(Int32) = Store : &:r0_23, r0_24
86+
# 16| r0_26(glval<Int32[,]>) = VariableAddress[b] :
87+
# 16| mu0_27(Int32[,]) = Uninitialized[b] : &:r0_26
88+
# 17| r0_28(glval<Int32[,]>) = VariableAddress[c] :
89+
# 17| mu0_29(Int32[,]) = Uninitialized[c] : &:r0_28
90+
# 17| r0_30(Int32) = Constant[0] :
91+
# 17| r0_31(glval<null>) = PointerAdd : r0_28, r0_30
92+
# 17| r0_32(Int32) = Constant[0] :
93+
# 17| r0_33(glval<Int32>) = PointerAdd : r0_31, r0_32
94+
# 17| r0_34(Int32) = Constant[100] :
95+
# 17| mu0_35(Int32) = Store : &:r0_33, r0_34
96+
# 17| r0_36(Int32) = Constant[1] :
97+
# 17| r0_37(glval<Int32>) = PointerAdd : r0_31, r0_36
98+
# 17| r0_38(Int32) = Constant[101] :
99+
# 17| mu0_39(Int32) = Store : &:r0_37, r0_38
100+
# 17| r0_40(Int32) = Constant[1] :
101+
# 17| r0_41(glval<null>) = PointerAdd : r0_28, r0_40
102+
# 17| r0_42(Int32) = Constant[0] :
103+
# 17| r0_43(glval<Int32>) = PointerAdd : r0_41, r0_42
104+
# 17| r0_44(Int32) = Constant[102] :
105+
# 17| mu0_45(Int32) = Store : &:r0_43, r0_44
106+
# 17| r0_46(Int32) = Constant[1] :
107+
# 17| r0_47(glval<Int32>) = PointerAdd : r0_41, r0_46
108+
# 17| r0_48(Int32) = Constant[103] :
109+
# 17| mu0_49(Int32) = Store : &:r0_47, r0_48
110+
# 18| r0_50(glval<Int32[,]>) = VariableAddress[d] :
111+
# 18| mu0_51(Int32[,]) = Uninitialized[d] : &:r0_50
112+
# 18| r0_52(Int32) = Constant[0] :
113+
# 18| r0_53(glval<null>) = PointerAdd : r0_50, r0_52
114+
# 18| r0_54(Int32) = Constant[0] :
115+
# 18| r0_55(glval<Int32>) = PointerAdd : r0_53, r0_54
116+
# 18| r0_56(Int32) = Constant[100] :
117+
# 18| mu0_57(Int32) = Store : &:r0_55, r0_56
118+
# 18| r0_58(Int32) = Constant[1] :
119+
# 18| r0_59(glval<Int32>) = PointerAdd : r0_53, r0_58
120+
# 18| r0_60(Int32) = Constant[101] :
121+
# 18| mu0_61(Int32) = Store : &:r0_59, r0_60
122+
# 18| r0_62(Int32) = Constant[1] :
123+
# 18| r0_63(glval<null>) = PointerAdd : r0_50, r0_62
124+
# 18| r0_64(Int32) = Constant[0] :
125+
# 18| r0_65(glval<Int32>) = PointerAdd : r0_63, r0_64
126+
# 18| r0_66(Int32) = Constant[102] :
127+
# 18| mu0_67(Int32) = Store : &:r0_65, r0_66
128+
# 18| r0_68(Int32) = Constant[1] :
129+
# 18| r0_69(glval<Int32>) = PointerAdd : r0_63, r0_68
130+
# 18| r0_70(Int32) = Constant[103] :
131+
# 18| mu0_71(Int32) = Store : &:r0_69, r0_70
132+
# 19| r0_72(glval<Int32[,]>) = VariableAddress[e] :
133+
# 19| r0_73(glval<Int32[,]>) = VariableAddress[a] :
134+
# 19| r0_74(Int32[,]) = Load : &:r0_73, ~mu0_2
135+
# 19| mu0_75(Int32[,]) = Store : &:r0_72, r0_74
136+
# 20| r0_76(Int32) = Constant[-1] :
137+
# 20| r0_77(glval<Int32[,]>) = VariableAddress[e] :
138+
# 20| r0_78(Int32[,]) = ElementsAddress : r0_77
139+
# 20| r0_79(Int32) = Constant[1] :
140+
# 20| r0_80(Int32[,]) = PointerAdd[4] : r0_78, r0_79
141+
# 20| r0_81(Int32[]) = ElementsAddress : r0_80
142+
# 20| r0_82(Int32) = Constant[1] :
143+
# 20| r0_83(Int32[]) = PointerAdd[4] : r0_81, r0_82
144+
# 20| mu0_84(Int32) = Store : &:r0_83, r0_76
145+
# 13| v0_85(Void) = ReturnVoid :
146+
# 13| v0_86(Void) = UnmodeledUse : mu*
147+
# 13| v0_87(Void) = ExitFunction :
138148

139149
assignop.cs:
140150
# 4| System.Void AssignOp.Main()

0 commit comments

Comments
 (0)