C++: points-to for argument-returning calls

This commit is contained in:
Robert Marsh
2019-03-04 17:14:13 -08:00
parent 878502f82e
commit 97c11a5222
3 changed files with 45 additions and 33 deletions

View File

@@ -161,7 +161,7 @@ private predicate operandEscapesNonReturn(Operand operand) {
exists(CallInstruction ci, Instruction init |
isArgumentForParameter(ci, operand, init) and
(
resultReturned(init) and
resultReturned(init, _) and
resultEscapesNonReturn(ci)
or
resultEscapesNonReturn(init)
@@ -173,21 +173,29 @@ private predicate operandEscapesNonReturn(Operand operand) {
operandEscapesDomain(operand)
}
private predicate operandReturned(Operand operand) {
private predicate operandReturned(Operand operand, IntValue bitOffset) {
// The address is propagated to the result of the instruction, and that result itself is returned
operandIsPropagated(operand, _) and resultReturned(operand.getUseInstruction())
exists(IntValue bitOffset1, IntValue bitOffset2 |
operandIsPropagated(operand, bitOffset1) and
resultReturned(operand.getUseInstruction(), bitOffset2) and
bitOffset = bitOffset1 + bitOffset2
)
or
// The operand is used in a function call which returns it, and the return value is then returned
exists(CallInstruction ci, Instruction init |
exists(CallInstruction ci, Instruction init, IntValue bitOffset1, IntValue bitOffset2 |
isArgumentForParameter(ci, operand, init) and
resultReturned(init) and
resultReturned(ci)
resultReturned(init, bitOffset1) and
resultReturned(ci, bitOffset2) and
bitOffset = bitOffset1 + bitOffset2
)
or
// The address is returned
operand.getUseInstruction() instanceof ReturnValueInstruction
operand.getUseInstruction() instanceof ReturnValueInstruction and
bitOffset = 0
or
isOnlyEscapesViaReturnArgument(operand) and resultReturned(operand.getUseInstruction())
isOnlyEscapesViaReturnArgument(operand) and resultReturned(operand.getUseInstruction(), _) and
bitOffset = Ints::unknown()
}
private predicate isArgumentForParameter(CallInstruction ci, Operand operand, Instruction init) {
@@ -227,8 +235,8 @@ private predicate isNeverEscapesArgument(Operand operand) {
)
}
private predicate resultReturned(Instruction instr) {
operandReturned(instr.getAUse())
private predicate resultReturned(Instruction instr, IntValue bitOffset) {
operandReturned(instr.getAUse(), bitOffset)
}
/**
@@ -284,8 +292,7 @@ predicate resultPointsTo(Instruction instr, IRVariable var, IntValue bitOffset)
or
exists(CallInstruction ci, Instruction init |
isArgumentForParameter(ci, operand, init) and
resultReturned(init) and
propagatedBitOffset = Ints::unknown()
resultReturned(init, propagatedBitOffset)
)
) and
bitOffset = Ints::add(originalBitOffset, propagatedBitOffset)

View File

@@ -161,7 +161,7 @@ private predicate operandEscapesNonReturn(Operand operand) {
exists(CallInstruction ci, Instruction init |
isArgumentForParameter(ci, operand, init) and
(
resultReturned(init) and
resultReturned(init, _) and
resultEscapesNonReturn(ci)
or
resultEscapesNonReturn(init)
@@ -173,21 +173,29 @@ private predicate operandEscapesNonReturn(Operand operand) {
operandEscapesDomain(operand)
}
private predicate operandReturned(Operand operand) {
private predicate operandReturned(Operand operand, IntValue bitOffset) {
// The address is propagated to the result of the instruction, and that result itself is returned
operandIsPropagated(operand, _) and resultReturned(operand.getUseInstruction())
exists(IntValue bitOffset1, IntValue bitOffset2 |
operandIsPropagated(operand, bitOffset1) and
resultReturned(operand.getUseInstruction(), bitOffset2) and
bitOffset = bitOffset1 + bitOffset2
)
or
// The operand is used in a function call which returns it, and the return value is then returned
exists(CallInstruction ci, Instruction init |
exists(CallInstruction ci, Instruction init, IntValue bitOffset1, IntValue bitOffset2 |
isArgumentForParameter(ci, operand, init) and
resultReturned(init) and
resultReturned(ci)
resultReturned(init, bitOffset1) and
resultReturned(ci, bitOffset2) and
bitOffset = bitOffset1 + bitOffset2
)
or
// The address is returned
operand.getUseInstruction() instanceof ReturnValueInstruction
operand.getUseInstruction() instanceof ReturnValueInstruction and
bitOffset = 0
or
isOnlyEscapesViaReturnArgument(operand) and resultReturned(operand.getUseInstruction())
isOnlyEscapesViaReturnArgument(operand) and resultReturned(operand.getUseInstruction(), _) and
bitOffset = Ints::unknown()
}
private predicate isArgumentForParameter(CallInstruction ci, Operand operand, Instruction init) {
@@ -227,8 +235,8 @@ private predicate isNeverEscapesArgument(Operand operand) {
)
}
private predicate resultReturned(Instruction instr) {
operandReturned(instr.getAUse())
private predicate resultReturned(Instruction instr, IntValue bitOffset) {
operandReturned(instr.getAUse(), bitOffset)
}
/**
@@ -284,8 +292,7 @@ predicate resultPointsTo(Instruction instr, IRVariable var, IntValue bitOffset)
or
exists(CallInstruction ci, Instruction init |
isArgumentForParameter(ci, operand, init) and
resultReturned(init) and
propagatedBitOffset = Ints::unknown()
resultReturned(init, propagatedBitOffset)
)
) and
bitOffset = Ints::add(originalBitOffset, propagatedBitOffset)

View File

@@ -140,10 +140,10 @@
| escape.cpp:187:9:187:18 | VariableAddress[passByRef2] | passByRef2+0:0 | passByRef2+0:0 |
| escape.cpp:188:32:188:41 | VariableAddress[passByRef2] | passByRef2+0:0 | passByRef2+0:0 |
| escape.cpp:190:9:190:18 | VariableAddress[passByPtr3] | passByPtr3+0:0 | passByPtr3+0:0 |
| escape.cpp:191:30:191:42 | Call | none | passByPtr3+? |
| escape.cpp:191:30:191:42 | Call | none | passByPtr3+0:0 |
| escape.cpp:191:45:191:54 | VariableAddress[passByPtr3] | passByPtr3+0:0 | passByPtr3+0:0 |
| escape.cpp:193:9:193:18 | VariableAddress[passByRef3] | passByRef3+0:0 | passByRef3+0:0 |
| escape.cpp:194:32:194:46 | Call | none | passByRef3+? |
| escape.cpp:194:32:194:46 | Call | none | passByRef3+0:0 |
| escape.cpp:194:48:194:57 | VariableAddress[passByRef3] | passByRef3+0:0 | passByRef3+0:0 |
| escape.cpp:196:9:196:18 | VariableAddress[passByPtr4] | passByPtr4+0:0 | passByPtr4+0:0 |
| escape.cpp:197:9:197:18 | VariableAddress[passByPtr5] | passByPtr5+0:0 | passByPtr5+0:0 |
@@ -152,32 +152,30 @@
| escape.cpp:199:31:199:40 | VariableAddress[passByPtr5] | passByPtr5+0:0 | passByPtr5+0:0 |
| escape.cpp:199:43:199:47 | VariableAddress[no_b2] | no_b2+0:0 | no_b2+0:0 |
| escape.cpp:201:9:201:18 | VariableAddress[passByRef6] | passByRef6+0:0 | passByRef6+0:0 |
| escape.cpp:202:5:202:19 | Call | none | passByRef6+? |
| escape.cpp:202:5:202:19 | Call | none | passByRef6+0:0 |
| escape.cpp:202:21:202:30 | VariableAddress[passByRef6] | passByRef6+0:0 | passByRef6+0:0 |
| escape.cpp:204:9:204:25 | VariableAddress[no_ssa_passByRef7] | no_ssa_passByRef7+0:0 | no_ssa_passByRef7+0:0 |
| escape.cpp:205:5:205:19 | Call | none | no_ssa_passByRef7+? |
| escape.cpp:205:5:205:19 | Call | none | no_ssa_passByRef7+0:0 |
| escape.cpp:205:21:205:37 | VariableAddress[no_ssa_passByRef7] | no_ssa_passByRef7+0:0 | no_ssa_passByRef7+0:0 |
| escape.cpp:207:7:207:14 | VariableAddress[no_ssa_c] | no_ssa_c+0:0 | no_ssa_c+0:0 |
| escape.cpp:209:5:209:12 | VariableAddress[no_ssa_c] | no_ssa_c+0:0 | no_ssa_c+0:0 |
| escape.cpp:209:14:209:25 | Call | none | no_ssa_c+? |
| escape.cpp:209:14:209:25 | Call | none | no_ssa_c+0:0 |
| escape.cpp:211:7:211:7 | VariableAddress[c] | c+0:0 | c+0:0 |
| escape.cpp:213:5:213:5 | VariableAddress[c] | c+0:0 | c+0:0 |
| escape.cpp:215:7:215:8 | VariableAddress[c2] | c2+0:0 | c2+0:0 |
| escape.cpp:217:15:217:16 | VariableAddress[c2] | c2+0:0 | c2+0:0 |
| escape.cpp:219:7:219:8 | VariableAddress[c3] | c3+0:0 | c3+0:0 |
| escape.cpp:221:5:221:6 | VariableAddress[c3] | c3+0:0 | c3+0:0 |
| escape.cpp:221:8:221:19 | Call | none | c3+? |
| escape.cpp:221:8:221:19 | Call | none | c3+0:0 |
| escape.cpp:223:7:223:8 | VariableAddress[c4] | c4+0:0 | c4+0:0 |
| escape.cpp:225:14:225:15 | VariableAddress[c4] | c4+0:0 | c4+0:0 |
| escape.cpp:225:17:225:28 | Call | none | c4+? |
| escape.cpp:225:17:225:28 | Call | none | c4+0:0 |
| escape.cpp:227:7:227:8 | VariableAddress[c5] | c5+0:0 | c5+0:0 |
| escape.cpp:229:5:229:6 | VariableAddress[c5] | c5+0:0 | c5+0:0 |
| escape.cpp:231:21:231:23 | VariableAddress[or1] | or1+0:0 | or1+0:0 |
| escape.cpp:232:5:232:7 | VariableAddress[or1] | or1+0:0 | or1+0:0 |
| escape.cpp:232:9:232:18 | Call | none | or1+? |
| escape.cpp:234:21:234:23 | VariableAddress[or2] | or2+0:0 | or2+0:0 |
| escape.cpp:235:14:235:16 | VariableAddress[or2] | or2+0:0 | or2+0:0 |
| escape.cpp:235:18:235:27 | Call | none | or2+? |
| escape.cpp:237:18:237:20 | VariableAddress[on1] | on1+0:0 | on1+0:0 |
| escape.cpp:238:5:238:7 | VariableAddress[on1] | on1+0:0 | on1+0:0 |
| escape.cpp:240:18:240:20 | VariableAddress[on2] | on2+0:0 | on2+0:0 |