@@ -34,7 +34,7 @@ private predicate operandIsConsumedWithoutEscaping(Operand operand) {
34
34
35
35
private predicate operandEscapesDomain ( Operand operand ) {
36
36
not operandIsConsumedWithoutEscaping ( operand ) and
37
- not operandIsPropagated ( operand , _) and
37
+ not operandIsPropagated ( operand , _, _ ) and
38
38
not isArgumentForParameter ( _, operand , _) and
39
39
not isOnlyEscapesViaReturnArgument ( operand ) and
40
40
not operand .getUse ( ) instanceof ReturnValueInstruction and
@@ -69,67 +69,66 @@ IntValue getPointerBitOffset(PointerOffsetInstruction instr) {
69
69
}
70
70
71
71
/**
72
- * Holds if any address held in operand `tag` of instruction `instr` is
73
- * propagated to the result of `instr`, offset by the number of bits in
74
- * `bitOffset`. If the address is propagated, but the offset is not known to be
75
- * a constant, then `bitOffset` is unknown.
72
+ * Holds if any address held in operand `operand` is propagated to the result of `instr`, offset by
73
+ * the number of bits in `bitOffset`. If the address is propagated, but the offset is not known to
74
+ * be a constant, then `bitOffset` is `unknown()`.
76
75
*/
77
- private predicate operandIsPropagated ( Operand operand , IntValue bitOffset ) {
78
- exists ( Instruction instr |
79
- instr = operand .getUse ( ) and
80
- (
81
- // Converting to a non-virtual base class adds the offset of the base class.
82
- exists ( ConvertToNonVirtualBaseInstruction convert |
83
- convert = instr and
84
- bitOffset = Ints:: mul ( convert .getDerivation ( ) .getByteOffset ( ) , 8 )
85
- )
86
- or
87
- // Conversion using dynamic_cast results in an unknown offset
88
- instr instanceof CheckedConvertOrNullInstruction and
89
- bitOffset = Ints:: unknown ( )
90
- or
91
- // Converting to a derived class subtracts the offset of the base class.
92
- exists ( ConvertToDerivedInstruction convert |
93
- convert = instr and
94
- bitOffset = Ints:: neg ( Ints:: mul ( convert .getDerivation ( ) .getByteOffset ( ) , 8 ) )
95
- )
96
- or
97
- // Converting to a virtual base class adds an unknown offset.
98
- instr instanceof ConvertToVirtualBaseInstruction and
99
- bitOffset = Ints:: unknown ( )
100
- or
101
- // Conversion to another pointer type propagates the source address.
102
- exists ( ConvertInstruction convert , IRType resultType |
103
- convert = instr and
104
- resultType = convert .getResultIRType ( ) and
105
- resultType instanceof IRAddressType and
106
- bitOffset = 0
107
- )
108
- or
109
- // Adding an integer to or subtracting an integer from a pointer propagates
110
- // the address with an offset.
111
- exists ( PointerOffsetInstruction ptrOffset |
112
- ptrOffset = instr and
113
- operand = ptrOffset .getLeftOperand ( ) and
114
- bitOffset = getPointerBitOffset ( ptrOffset )
115
- )
116
- or
117
- // Computing a field address from a pointer propagates the address plus the
118
- // offset of the field.
119
- bitOffset = Language:: getFieldBitOffset ( instr .( FieldAddressInstruction ) .getField ( ) )
120
- or
121
- // A copy propagates the source value.
122
- operand = instr .( CopyInstruction ) .getSourceValueOperand ( ) and bitOffset = 0
123
- or
124
- // Some functions are known to propagate an argument
125
- isAlwaysReturnedArgument ( operand ) and bitOffset = 0
76
+ private predicate operandIsPropagated ( Operand operand , IntValue bitOffset , Instruction instr ) {
77
+ instr = operand .getUse ( ) and
78
+ (
79
+ // Converting to a non-virtual base class adds the offset of the base class.
80
+ exists ( ConvertToNonVirtualBaseInstruction convert |
81
+ convert = instr and
82
+ bitOffset = Ints:: mul ( convert .getDerivation ( ) .getByteOffset ( ) , 8 )
126
83
)
84
+ or
85
+ // Conversion using dynamic_cast results in an unknown offset
86
+ instr instanceof CheckedConvertOrNullInstruction and
87
+ bitOffset = Ints:: unknown ( )
88
+ or
89
+ // Converting to a derived class subtracts the offset of the base class.
90
+ exists ( ConvertToDerivedInstruction convert |
91
+ convert = instr and
92
+ bitOffset = Ints:: neg ( Ints:: mul ( convert .getDerivation ( ) .getByteOffset ( ) , 8 ) )
93
+ )
94
+ or
95
+ // Converting to a virtual base class adds an unknown offset.
96
+ instr instanceof ConvertToVirtualBaseInstruction and
97
+ bitOffset = Ints:: unknown ( )
98
+ or
99
+ // Conversion to another pointer type propagates the source address.
100
+ exists ( ConvertInstruction convert , IRType resultType |
101
+ convert = instr and
102
+ resultType = convert .getResultIRType ( ) and
103
+ resultType instanceof IRAddressType and
104
+ bitOffset = 0
105
+ )
106
+ or
107
+ // Adding an integer to or subtracting an integer from a pointer propagates
108
+ // the address with an offset.
109
+ exists ( PointerOffsetInstruction ptrOffset |
110
+ ptrOffset = instr and
111
+ operand = ptrOffset .getLeftOperand ( ) and
112
+ bitOffset = getPointerBitOffset ( ptrOffset )
113
+ )
114
+ or
115
+ // Computing a field address from a pointer propagates the address plus the
116
+ // offset of the field.
117
+ bitOffset = Language:: getFieldBitOffset ( instr .( FieldAddressInstruction ) .getField ( ) )
118
+ or
119
+ // A copy propagates the source value.
120
+ operand = instr .( CopyInstruction ) .getSourceValueOperand ( ) and bitOffset = 0
121
+ or
122
+ // Some functions are known to propagate an argument
123
+ isAlwaysReturnedArgument ( operand ) and bitOffset = 0
127
124
)
128
125
}
129
126
130
127
private predicate operandEscapesNonReturn ( Operand operand ) {
131
- // The address is propagated to the result of the instruction, and that result itself is returned
132
- operandIsPropagated ( operand , _) and resultEscapesNonReturn ( operand .getUse ( ) )
128
+ exists ( Instruction instr |
129
+ // The address is propagated to the result of the instruction, and that result itself is returned
130
+ operandIsPropagated ( operand , _, instr ) and resultEscapesNonReturn ( instr )
131
+ )
133
132
or
134
133
// The operand is used in a function call which returns it, and the return value is then returned
135
134
exists ( CallInstruction ci , Instruction init |
@@ -151,9 +150,11 @@ private predicate operandEscapesNonReturn(Operand operand) {
151
150
}
152
151
153
152
private predicate operandMayReachReturn ( Operand operand ) {
154
- // The address is propagated to the result of the instruction, and that result itself is returned
155
- operandIsPropagated ( operand , _) and
156
- resultMayReachReturn ( operand .getUse ( ) )
153
+ exists ( Instruction instr |
154
+ // The address is propagated to the result of the instruction, and that result itself is returned
155
+ operandIsPropagated ( operand , _, instr ) and
156
+ resultMayReachReturn ( instr )
157
+ )
157
158
or
158
159
// The operand is used in a function call which returns it, and the return value is then returned
159
160
exists ( CallInstruction ci , Instruction init |
@@ -173,9 +174,9 @@ private predicate operandMayReachReturn(Operand operand) {
173
174
174
175
private predicate operandReturned ( Operand operand , IntValue bitOffset ) {
175
176
// The address is propagated to the result of the instruction, and that result itself is returned
176
- exists ( IntValue bitOffset1 , IntValue bitOffset2 |
177
- operandIsPropagated ( operand , bitOffset1 ) and
178
- resultReturned ( operand . getUse ( ) , bitOffset2 ) and
177
+ exists ( Instruction instr , IntValue bitOffset1 , IntValue bitOffset2 |
178
+ operandIsPropagated ( operand , bitOffset1 , instr ) and
179
+ resultReturned ( instr , bitOffset2 ) and
179
180
bitOffset = Ints:: add ( bitOffset1 , bitOffset2 )
180
181
)
181
182
or
@@ -270,12 +271,13 @@ predicate allocationEscapes(Configuration::Allocation allocation) {
270
271
/**
271
272
* Equivalent to `operandIsPropagated()`, but includes interprocedural propagation.
272
273
*/
273
- private predicate operandIsPropagatedIncludingByCall ( Operand operand , IntValue bitOffset ) {
274
- operandIsPropagated ( operand , bitOffset )
274
+ private predicate operandIsPropagatedIncludingByCall ( Operand operand , IntValue bitOffset , Instruction instr ) {
275
+ operandIsPropagated ( operand , bitOffset , instr )
275
276
or
276
277
exists ( CallInstruction call , Instruction init |
277
278
isArgumentForParameter ( call , operand , init ) and
278
- resultReturned ( init , bitOffset )
279
+ resultReturned ( init , bitOffset ) and
280
+ instr = call
279
281
)
280
282
}
281
283
@@ -292,8 +294,7 @@ private predicate hasBaseAndOffset(AddressOperand addrOperand, Instruction base,
292
294
// We already have an offset from `middle`.
293
295
hasBaseAndOffset ( addrOperand , middle , previousBitOffset ) and
294
296
// `middle` is propagated from `base`.
295
- middleOperand = middle .getAnOperand ( ) and
296
- operandIsPropagatedIncludingByCall ( middleOperand , additionalBitOffset ) and
297
+ operandIsPropagatedIncludingByCall ( middleOperand , additionalBitOffset , middle ) and
297
298
base = middleOperand .getDef ( ) and
298
299
bitOffset = Ints:: add ( previousBitOffset , additionalBitOffset )
299
300
)
0 commit comments