Skip to content

Commit 2bc3506

Browse files
C++: Update SimpleSSA to use the new alias analysis API
1 parent d4ae9dd commit 2bc3506

File tree

3 files changed

+56
-44
lines changed

3 files changed

+56
-44
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
import semmle.code.cpp.ir.implementation.raw.IR as InputIR
2+
import AliasConfiguration as Configuration
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
private import semmle.code.cpp.ir.implementation.raw.IR
2+
3+
/**
4+
* A memory allocation that can be tracked by the SimpleSSA alias analysis.
5+
* All automatic variables are tracked.
6+
*/
7+
class Allocation extends IRAutomaticVariable {
8+
VariableAddressInstruction getABaseInstruction() {
9+
result.getVariable() = this
10+
}
11+
12+
final string getAllocationString() {
13+
result = toString()
14+
}
15+
16+
predicate alwaysEscapes() {
17+
// An automatic variable only escapes if its address is taken and escapes.
18+
none()
19+
}
20+
}
Lines changed: 35 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,61 @@
11
import AliasAnalysis
22
private import cpp
3+
private import AliasConfiguration
34
private import semmle.code.cpp.ir.implementation.raw.IR
4-
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints
5-
private import semmle.code.cpp.ir.implementation.internal.OperandTag
65
private import semmle.code.cpp.ir.internal.Overlap
7-
8-
private class IntValue = Ints::IntValue;
9-
10-
private predicate hasResultMemoryAccess(Instruction instr, IRVariable var, Type type, IntValue bitOffset) {
11-
resultPointsTo(instr.getResultAddressOperand().getAnyDef(), var, bitOffset) and
12-
type = instr.getResultType()
13-
}
14-
15-
private predicate hasOperandMemoryAccess(MemoryOperand operand, IRVariable var, Type type, IntValue bitOffset) {
16-
resultPointsTo(operand.getAddressOperand().getAnyDef(), var, bitOffset) and
17-
type = operand.getType()
18-
}
6+
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints
197

208
/**
21-
* Holds if the specified variable should be modeled in SSA form. For unaliased SSA, we only model a variable if its
22-
* address never escapes and all reads and writes of that variable access the entire variable using the original type
23-
* of the variable.
9+
* Holds if the specified variable should be modeled in SSA form. For unaliased SSA, we only model a
10+
* variable if its address never escapes and all reads and writes of that variable access the entire
11+
* variable using the original type of the variable.
2412
*/
25-
private predicate isVariableModeled(IRVariable var) {
26-
not variableAddressEscapes(var) and
27-
// There's no need to check for the right size. An `IRVariable` never has an `UnknownType`, so the test for
28-
// `type = var.getType()` is sufficient.
29-
forall(Instruction instr, Type type, IntValue bitOffset |
30-
hasResultMemoryAccess(instr, var, type, bitOffset) |
31-
bitOffset = 0 and
32-
type = var.getType()
33-
) and
34-
forall(MemoryOperand operand, Type type, IntValue bitOffset |
35-
hasOperandMemoryAccess(operand, var, type, bitOffset) |
36-
bitOffset = 0 and
37-
type = var.getType()
13+
private predicate isVariableModeled(Allocation var) {
14+
not allocationEscapes(var) and
15+
forall(AddressOperand addrOperand, Type type |
16+
(
17+
exists(Instruction instr |
18+
addrOperand = instr.getResultAddressOperand() and
19+
type = instr.getResultType()
20+
) or
21+
exists(MemoryOperand operand |
22+
addrOperand = operand.getAddressOperand() and
23+
type = operand.getType()
24+
)
25+
) and
26+
getAddressOperandAllocation(addrOperand) = var |
27+
exists(Instruction constantBase, int bitOffset |
28+
addressOperandBaseAndConstantOffset(addrOperand, constantBase, bitOffset) and
29+
bitOffset = 0 and
30+
constantBase = var.getABaseInstruction() and
31+
// There's no need to check for the right size. An `IRVariable` never has an `UnknownType`, so
32+
// the test for the right type is sufficient.
33+
type = var.getType()
34+
)
3835
)
3936
}
4037

4138
private newtype TMemoryLocation =
42-
MkMemoryLocation(IRVariable var) {
39+
MkMemoryLocation(Allocation var) {
4340
isVariableModeled(var)
4441
}
4542

46-
private MemoryLocation getMemoryLocation(IRVariable var) {
47-
result.getIRVariable() = var
43+
private MemoryLocation getMemoryLocation(Allocation var) {
44+
result.getAllocation() = var
4845
}
4946

5047
class MemoryLocation extends TMemoryLocation {
51-
IRVariable var;
48+
Allocation var;
5249

5350
MemoryLocation() {
5451
this = MkMemoryLocation(var)
5552
}
5653

5754
final string toString() {
58-
result = var.toString()
55+
result = var.getAllocationString()
5956
}
6057

61-
final IRVariable getIRVariable() {
58+
final Allocation getAllocation() {
6259
result = var
6360
}
6461

@@ -85,15 +82,9 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
8582
}
8683

8784
MemoryLocation getResultMemoryLocation(Instruction instr) {
88-
exists(IRVariable var |
89-
hasResultMemoryAccess(instr, var, _, _) and
90-
result = getMemoryLocation(var)
91-
)
85+
result = getMemoryLocation(getAddressOperandAllocation(instr.getResultAddressOperand()))
9286
}
9387

9488
MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
95-
exists(IRVariable var |
96-
hasOperandMemoryAccess(operand, var, _, _) and
97-
result = getMemoryLocation(var)
98-
)
89+
result = getMemoryLocation(getAddressOperandAllocation(operand.getAddressOperand()))
9990
}

0 commit comments

Comments
 (0)