Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++: Add a new MemoryLocation to represent sets of Allocations #16907

Merged
merged 34 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4953e7e
C++: Add tests.
MathiasVP Jul 1, 2024
72679c8
C++: Add a new opcode and instruction.
MathiasVP Jul 1, 2024
ef85329
C++: Sync identical files.
MathiasVP Jul 1, 2024
ffa55b4
C++: Disable special casing of Phi operands in alias analysis. Instea…
MathiasVP Jul 1, 2024
1c8cf3c
C++: Sync identical files.
MathiasVP Jul 1, 2024
0b84329
C++: Expose the 'AddressOperand' from both 'hasResultMemoryAccess' an…
MathiasVP Jul 1, 2024
c5c4f08
C++: Rename from 'getAllocation' to 'getAnAllocation'.
MathiasVP Jul 2, 2024
5e1c67f
C++: Add a new 'MemoryLocation' that represents a set of allocations.
MathiasVP Jul 1, 2024
399d47d
C++: Cleanup
MathiasVP Jul 1, 2024
09c03d9
C++: The virtual variable of a variable that is contained in a groupe…
MathiasVP Jul 1, 2024
e7c43b3
C++: Return grouped memory locations from 'getOperandMemoryLocation' …
MathiasVP Jul 1, 2024
b185c67
C++: Handle overlap with grouped memory locations.
MathiasVP Jul 1, 2024
c54dc49
C++: Improve 'toString' on the 'InitializeGroup' instruction.
MathiasVP Jul 2, 2024
2c4bf13
C++: Sync identical files.
MathiasVP Jul 4, 2024
8db7ece
C++: Fill in trivial parts of SSA.
MathiasVP Jul 1, 2024
cf8b2d5
C++: Hide away the 'multiply by two' hack in a predicate.
MathiasVP Jul 1, 2024
c4d72e5
C++: No need to check if the offset is non-negative. It always is bec…
MathiasVP Jul 4, 2024
03ec184
C++: Add 'InitializeGroup' instructions to the successor relation.
MathiasVP Jul 4, 2024
db525f5
C++: Sync identical files.
MathiasVP Jul 1, 2024
92e814b
C++: Stub 'VariableGroup' and 'GroupedMemoryLocation' in unaliased SS…
MathiasVP Jul 1, 2024
d1e1037
C++: Accept test changes.
MathiasVP Jul 1, 2024
72b52cc
C++: Insert Chi instructions after InitializeGroup instructions whose…
MathiasVP Jul 4, 2024
89f0705
C++: Sync identical files.
MathiasVP Jul 4, 2024
6ef9dba
C++: Accept test changes.
MathiasVP Jul 4, 2024
b954845
C++: Ignore the new 'InitializeGroup' instruction in dataflow.
MathiasVP Jul 4, 2024
5d58cf6
C++: Accept query test changes.
MathiasVP Jul 4, 2024
4893785
C++: Accept test changes to GVN.
MathiasVP Jul 4, 2024
950d70f
C++: Replace 'InitializeGroup' with 'UninitializedGroup'.
MathiasVP Jul 16, 2024
8894fba
C++: Sync identical files.
MathiasVP Jul 16, 2024
9504e0f
C++: Accept test changes.
MathiasVP Jul 16, 2024
083b9b7
C++: Delete redundant conjuncts.
MathiasVP Jul 16, 2024
dbe0fce
C++: Sync identical files.
MathiasVP Jul 16, 2024
d5ccb2e
C++: Add a large QLDoc with example to 'getInstructionSuccessor'.
MathiasVP Jul 17, 2024
8a3a3fa
C++: Sync identical files.
MathiasVP Jul 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ predicate ignoreInstruction(Instruction instr) {
instr instanceof AliasedDefinitionInstruction or
instr instanceof AliasedUseInstruction or
instr instanceof InitializeNonLocalInstruction or
instr instanceof ReturnIndirectionInstruction
instr instanceof ReturnIndirectionInstruction or
instr instanceof UninitializedGroupInstruction
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ private newtype TMemoryAccessKind =
TPhiMemoryAccess() or
TUnmodeledMemoryAccess() or
TChiTotalMemoryAccess() or
TChiPartialMemoryAccess()
TChiPartialMemoryAccess() or
TGroupedMemoryAccess()

/**
* Describes the set of memory locations memory accessed by a memory operand or
Expand Down Expand Up @@ -99,3 +100,11 @@ class ChiTotalMemoryAccess extends MemoryAccessKind, TChiTotalMemoryAccess {
class ChiPartialMemoryAccess extends MemoryAccessKind, TChiPartialMemoryAccess {
override string toString() { result = "chi(partial)" }
}

/**
* The result of an `UninitializedGroup` instruction, which initializes a set of
* allocations that are each assigned the same virtual variable.
*/
class GroupedMemoryAccess extends MemoryAccessKind, TGroupedMemoryAccess {
override string toString() { result = "group" }
}
12 changes: 12 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ private newtype TOpcode =
TSizedBufferMayWriteSideEffect() or
TInitializeDynamicAllocation() or
TChi() or
TUninitializedGroup() or
TInlineAsm() or
TUnreached() or
TNewObj()
Expand Down Expand Up @@ -1237,6 +1238,17 @@ module Opcode {
}
}

/**
* The `Opcode` for a `UninitializedGroup`.
*
* See the `UninitializedGroupInstruction` documentation for more details.
*/
class UninitializedGroup extends Opcode, TUninitializedGroup {
final override string toString() { result = "UninitializedGroup" }

override GroupedMemoryAccess getWriteMemoryAccess() { any() }
}

/**
* The `Opcode` for an `InlineAsmInstruction`.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2142,6 +2142,47 @@ class ChiInstruction extends Instruction {
final predicate isPartialUpdate() { Construction::chiOnlyPartiallyUpdatesLocation(this) }
}

/**
* An instruction that initializes a set of allocations that are each assigned
* the same "virtual variable".
*
* As an example, consider the following snippet:
* ```
* int a;
* int b;
* int* p;
* if(b) {
* p = &a;
* } else {
* p = &b;
* }
* *p = 5;
* int x = a;
* ```
*
* Since both the address of `a` and `b` reach `p` at `*p = 5` the IR alias
* analysis will create a region that contains both `a` and `b`. The region
* containing both `a` and `b` are initialized by an `UninitializedGroup`
* instruction in the entry block of the enclosing function.
*/
class UninitializedGroupInstruction extends Instruction {
UninitializedGroupInstruction() { this.getOpcode() instanceof Opcode::UninitializedGroup }

/**
* Gets an `IRVariable` whose memory is initialized by this instruction, if any.
* Note: Allocations that are not represented as `IRVariable`s (such as
* dynamic allocations) are not returned by this predicate even if this
* instruction initializes such memory.
*/
final IRVariable getAnIRVariable() {
result = Construction::getAnUninitializedGroupVariable(this)
}

final override string getImmediateString() {
result = strictconcat(this.getAnIRVariable().toString(), ",")
}
}

/**
* An instruction representing unreachable code.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ private predicate operandEscapesDomain(Operand operand) {
not isArgumentForParameter(_, operand, _) and
not isOnlyEscapesViaReturnArgument(operand) and
not operand.getUse() instanceof ReturnValueInstruction and
not operand.getUse() instanceof ReturnIndirectionInstruction and
not operand instanceof PhiInputOperand
not operand.getUse() instanceof ReturnIndirectionInstruction
}

/**
Expand Down Expand Up @@ -191,6 +190,11 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset, Instr
// A copy propagates the source value.
operand = instr.(CopyInstruction).getSourceValueOperand() and bitOffset = 0
)
or
operand = instr.(PhiInstruction).getAnInputOperand() and
// Using `unknown` ensures termination since we cannot keep incrementing a bit offset
// through the back edge of a loop (or through recursion).
bitOffset = Ints::unknown()
}

private predicate operandEscapesNonReturn(Operand operand) {
Expand All @@ -212,9 +216,6 @@ private predicate operandEscapesNonReturn(Operand operand) {
or
isOnlyEscapesViaReturnArgument(operand) and resultEscapesNonReturn(operand.getUse())
or
operand instanceof PhiInputOperand and
resultEscapesNonReturn(operand.getUse())
or
operandEscapesDomain(operand)
}

Expand All @@ -236,9 +237,6 @@ private predicate operandMayReachReturn(Operand operand) {
operand.getUse() instanceof ReturnValueInstruction
or
isOnlyEscapesViaReturnArgument(operand) and resultMayReachReturn(operand.getUse())
or
operand instanceof PhiInputOperand and
resultMayReachReturn(operand.getUse())
}

private predicate operandReturned(Operand operand, IntValue bitOffset) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class IndirectParameterAllocation extends Allocation, TIndirectParameterAllocati
final override predicate isAlwaysAllocatedOnStack() { none() }

final override predicate alwaysEscapes() { none() }

final IRAutomaticVariable getIRVariable() { result = var }
}

class DynamicAllocation extends Allocation, TDynamicAllocation {
Expand Down
Loading
Loading