Skip to content

Commit 0cde86d

Browse files
C++: Fix PR feedback
1 parent 9869fd3 commit 0cde86d

File tree

4 files changed

+47
-21
lines changed

4 files changed

+47
-21
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/SSA.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,15 @@ other `MemoryLocation`.
121121
#### Aliased SSA
122122
The current memory model used to construct Aliased SSA models every memory access. There are two
123123
kinds of `MemoryLocation`:
124-
- `VariableMemoryAccess` represents an access to a known `IRVariable` with a specific type, at a bit
125-
offset that may or may not be a known constant. `VariableMemoryAccess` represents any access to a
124+
- `VariableMemoryLocation` represents an access to a known `IRVariable` with a specific type, at a bit
125+
offset that may or may not be a known constant. `VariableMemoryLocation` represents any access to a
126126
known `IRVariable` even if that variable's address escapes.
127127
- `UnknownMemoryLocation` represents an access where the memory being accessed is not known to be part
128128
of a single specific `IRVariable`.
129129

130130
In addition, there are two different kinds of `VirtualVariable`:
131131
- `VariableVirtualVariable` represents an `IRVariable` whose address does not escape. The
132-
`VariableVirtualVariable` is just the `VariableMemoryAccess` that represents an access to the entire
132+
`VariableVirtualVariable` is just the `VariableMemoryLocation` that represents an access to the entire
133133
`IRVariable` with its declared type.
134134
- `UnknownVirtualVariable` represents all memory that is not covered by a `VariableVirtualVariable`.
135135
This includes the `UnknownMemoryLocation`, as well as any `VariableMemoryLocation` whose

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ private newtype TMemoryLocation =
3838
TUnknownMemoryLocation(FunctionIR funcIR) or
3939
TUnknownVirtualVariable(FunctionIR funcIR)
4040

41+
/**
42+
* Represents the memory location accessed by a memory operand or memory result. In this implementation, the location is
43+
* one of the following:
44+
* - `VariableMemoryLocation` - A location within a known `IRVariable`, at an offset that is either a constant or is
45+
* unknown.
46+
* - `UnknownMemoryLocation` - A location not known to be within a specific `IRVariable`.
47+
*/
4148
abstract class MemoryLocation extends TMemoryLocation {
4249
abstract string toString();
4350

@@ -53,7 +60,7 @@ abstract class VirtualVariable extends MemoryLocation {
5360

5461
/**
5562
* An access to memory within a single known `IRVariable`. The variable may be either an unescaped variable
56-
* (with its own `VirtualIRVariable`) or an escaped variable (assiged to `UnknownVirtualVariable`).
63+
* (with its own `VirtualIRVariable`) or an escaped variable (assigned to `UnknownVirtualVariable`).
5764
*/
5865
class VariableMemoryLocation extends TVariableMemoryLocation, MemoryLocation {
5966
IRVariable var;
@@ -102,10 +109,15 @@ class VariableMemoryLocation extends TVariableMemoryLocation, MemoryLocation {
102109
*/
103110
final predicate coversEntireVariable() {
104111
startBitOffset = 0 and
105-
Ints::isEQ(endBitOffset, Ints::mul(var.getType().getSize(), 8))
112+
endBitOffset = var.getType().getSize() * 8
106113
}
107114
}
108115

116+
/**
117+
* Represents the `MemoryLocation` for an `IRVariable` that acts as its own `VirtualVariable`. Includes any
118+
* `VariableMemoryLocation` that exactly overlaps its entire `IRVariable`, and only if that `IRVariable` does not
119+
* escape.
120+
*/
109121
class VariableVirtualVariable extends VariableMemoryLocation, VirtualVariable {
110122
VariableVirtualVariable() {
111123
not variableAddressEscapes(var) and

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,17 @@ private import PhiInsertion
388388
* location and there is a use of that location reachable from that block without an intervening definition of the
389389
* location.
390390
* Within the approach outlined above, we treat a location slightly differently depending on whether or not it is a
391-
* virtual variable. For a virtual variable,
392-
* location into the beginning of a block
391+
* virtual variable. For a virtual variable, we will insert a `Phi` instruction on the dominance frontier if there is
392+
* a use of any member location of that virtual variable that is reachable from the `Phi` instruction. For a location
393+
* that is not a virtual variable, we insert a `Phi` instruction only if there is an exactly-overlapping use of the
394+
* location reachable from the `Phi` instruction. This ensures that we insert a `Phi` instruction for a non-virtual
395+
* variable only if doing so would allow dataflow analysis to get a more precise result than if we just used a `Phi`
396+
* instruction for the virtual variable as a whole.
393397
*/
394398
private module PhiInsertion {
399+
/**
400+
* Holds if a `Phi` instruction needs to be inserted for location `defLocation` at the beginning of block `phiBlock`.
401+
*/
395402
predicate definitionHasPhiNode(Alias::MemoryLocation defLocation, OldBlock phiBlock) {
396403
exists(OldBlock defBlock |
397404
phiBlock = Dominance::getDominanceFrontier(defBlock) and
@@ -402,8 +409,8 @@ private module PhiInsertion {
402409
}
403410

404411
/**
405-
* Holds if the virtual variable `vvar` has a definition in block `block`, either because of an existing instruction
406-
* or because of a Phi node.
412+
* Holds if the memory location `defLocation` has a definition in block `block`, either because of an existing
413+
* instruction, a `Phi` node, or a `Chi` node.
407414
*/
408415
private predicate definitionHasDefinitionInBlock(Alias::MemoryLocation defLocation, OldBlock block) {
409416
definitionHasPhiNode(defLocation, block) or
@@ -501,10 +508,10 @@ private module PhiInsertion {
501508
private import DefUse
502509

503510
/**
504-
* Module containing the predicates that connect uses to their reaching definition. The reaching definitios are computed
505-
* separately for each unique use `MemoryLocation`. An instruction is treated as a definition of a use location if the
506-
* defined location overlaps the use location in any way. Thus, a single instruction may serve as a definition for
507-
* multiple use locations, since a single definition location may overlap many use locations.
511+
* Module containing the predicates that connect uses to their reaching definition. The reaching definitions are
512+
* computed separately for each unique use `MemoryLocation`. An instruction is treated as a definition of a use location
513+
* if the defined location overlaps the use location in any way. Thus, a single instruction may serve as a definition
514+
* for multiple use locations, since a single definition location may overlap many use locations.
508515
*
509516
* Definitions and uses are identified by a block and an integer "offset". An offset of -1 indicates the definition
510517
* from a `Phi` instruction at the beginning of the block. An offset of 2*i indicates a definition or use on the

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,17 @@ private import PhiInsertion
388388
* location and there is a use of that location reachable from that block without an intervening definition of the
389389
* location.
390390
* Within the approach outlined above, we treat a location slightly differently depending on whether or not it is a
391-
* virtual variable. For a virtual variable,
392-
* location into the beginning of a block
391+
* virtual variable. For a virtual variable, we will insert a `Phi` instruction on the dominance frontier if there is
392+
* a use of any member location of that virtual variable that is reachable from the `Phi` instruction. For a location
393+
* that is not a virtual variable, we insert a `Phi` instruction only if there is an exactly-overlapping use of the
394+
* location reachable from the `Phi` instruction. This ensures that we insert a `Phi` instruction for a non-virtual
395+
* variable only if doing so would allow dataflow analysis to get a more precise result than if we just used a `Phi`
396+
* instruction for the virtual variable as a whole.
393397
*/
394398
private module PhiInsertion {
399+
/**
400+
* Holds if a `Phi` instruction needs to be inserted for location `defLocation` at the beginning of block `phiBlock`.
401+
*/
395402
predicate definitionHasPhiNode(Alias::MemoryLocation defLocation, OldBlock phiBlock) {
396403
exists(OldBlock defBlock |
397404
phiBlock = Dominance::getDominanceFrontier(defBlock) and
@@ -402,8 +409,8 @@ private module PhiInsertion {
402409
}
403410

404411
/**
405-
* Holds if the virtual variable `vvar` has a definition in block `block`, either because of an existing instruction
406-
* or because of a Phi node.
412+
* Holds if the memory location `defLocation` has a definition in block `block`, either because of an existing
413+
* instruction, a `Phi` node, or a `Chi` node.
407414
*/
408415
private predicate definitionHasDefinitionInBlock(Alias::MemoryLocation defLocation, OldBlock block) {
409416
definitionHasPhiNode(defLocation, block) or
@@ -501,10 +508,10 @@ private module PhiInsertion {
501508
private import DefUse
502509

503510
/**
504-
* Module containing the predicates that connect uses to their reaching definition. The reaching definitios are computed
505-
* separately for each unique use `MemoryLocation`. An instruction is treated as a definition of a use location if the
506-
* defined location overlaps the use location in any way. Thus, a single instruction may serve as a definition for
507-
* multiple use locations, since a single definition location may overlap many use locations.
511+
* Module containing the predicates that connect uses to their reaching definition. The reaching definitions are
512+
* computed separately for each unique use `MemoryLocation`. An instruction is treated as a definition of a use location
513+
* if the defined location overlaps the use location in any way. Thus, a single instruction may serve as a definition
514+
* for multiple use locations, since a single definition location may overlap many use locations.
508515
*
509516
* Definitions and uses are identified by a block and an integer "offset". An offset of -1 indicates the definition
510517
* from a `Phi` instruction at the beginning of the block. An offset of 2*i indicates a definition or use on the

0 commit comments

Comments
 (0)