@@ -34,7 +34,7 @@ private predicate operandIsConsumedWithoutEscaping(Operand operand) {
3434
3535private predicate operandEscapesDomain ( Operand operand ) {
3636 not operandIsConsumedWithoutEscaping ( operand ) and
37- not operandIsPropagated ( operand , _) and
37+ not operandIsPropagated ( operand , _, _ ) and
3838 not isArgumentForParameter ( _, operand , _) and
3939 not isOnlyEscapesViaReturnArgument ( operand ) and
4040 not operand .getUse ( ) instanceof ReturnValueInstruction and
@@ -69,67 +69,66 @@ IntValue getPointerBitOffset(PointerOffsetInstruction instr) {
6969}
7070
7171/**
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()`.
7675 */
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 )
12683 )
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
127124 )
128125}
129126
130127private 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+ )
133132 or
134133 // The operand is used in a function call which returns it, and the return value is then returned
135134 exists ( CallInstruction ci , Instruction init |
@@ -151,9 +150,11 @@ private predicate operandEscapesNonReturn(Operand operand) {
151150}
152151
153152private 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+ )
157158 or
158159 // The operand is used in a function call which returns it, and the return value is then returned
159160 exists ( CallInstruction ci , Instruction init |
@@ -173,9 +174,9 @@ private predicate operandMayReachReturn(Operand operand) {
173174
174175private predicate operandReturned ( Operand operand , IntValue bitOffset ) {
175176 // 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
179180 bitOffset = Ints:: add ( bitOffset1 , bitOffset2 )
180181 )
181182 or
@@ -270,12 +271,13 @@ predicate allocationEscapes(Configuration::Allocation allocation) {
270271/**
271272 * Equivalent to `operandIsPropagated()`, but includes interprocedural propagation.
272273 */
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 )
275276 or
276277 exists ( CallInstruction call , Instruction init |
277278 isArgumentForParameter ( call , operand , init ) and
278- resultReturned ( init , bitOffset )
279+ resultReturned ( init , bitOffset ) and
280+ instr = call
279281 )
280282}
281283
@@ -292,8 +294,7 @@ private predicate hasBaseAndOffset(AddressOperand addrOperand, Instruction base,
292294 // We already have an offset from `middle`.
293295 hasBaseAndOffset ( addrOperand , middle , previousBitOffset ) and
294296 // `middle` is propagated from `base`.
295- middleOperand = middle .getAnOperand ( ) and
296- operandIsPropagatedIncludingByCall ( middleOperand , additionalBitOffset ) and
297+ operandIsPropagatedIncludingByCall ( middleOperand , additionalBitOffset , middle ) and
297298 base = middleOperand .getDef ( ) and
298299 bitOffset = Ints:: add ( previousBitOffset , additionalBitOffset )
299300 )
0 commit comments