Skip to content

Commit 1bde117

Browse files
author
Dave Bartolomeo
committed
C++: Connect InitializeIndirection to UnmodeledDefinition
The IR generation for `InitializeIndirection` currently connects its load operand to the result of the corresponding `InitializeParameter` instruction. This isn't exactly wrong, but it doesn't fit the IR invariant of "All unmodeled uses consume `UnmodeledDefinition`". Our current code doesn't care, because we just throw away all of the existing def-use information, modeled or otherwise, when we build unaliased SSA. However, some upcoming SSA changes don't work correctly if this invariant is broken. I've added the trivial IR generation change, along with a new sanity query.
1 parent 7c5c9ea commit 1bde117

File tree

16 files changed

+144
-35
lines changed

16 files changed

+144
-35
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRSanity.qll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,26 @@ module InstructionSanity {
149149
count(instr.getBlock().getAPredecessor()) < 2
150150
}
151151

152+
/**
153+
* Holds if a memory operand is connected to a definition with an unmodeled result, other than
154+
* `UnmodeledDefinition` itself.
155+
*/
156+
query predicate memoryOperandDefinitionIsUnmodeled(
157+
Instruction instr, string message, IRFunction func, string funcText
158+
) {
159+
exists(MemoryOperand operand, Instruction def |
160+
operand = instr.getAnOperand() and
161+
not operand instanceof UnmodeledUseOperand and
162+
def = operand.getAnyDef() and
163+
not def.isResultModeled() and
164+
not def instanceof UnmodeledDefinitionInstruction and
165+
message =
166+
"Memory operand definition has unmodeled result, but is not the `UnmodeledDefinition` instruction in function '$@'" and
167+
func = instr.getEnclosingIRFunction() and
168+
funcText = Language::getIdentityString(func.getFunction())
169+
)
170+
}
171+
152172
/**
153173
* Holds if operand `operand` consumes a value that was defined in
154174
* a different function.

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRSanity.qll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,26 @@ module InstructionSanity {
149149
count(instr.getBlock().getAPredecessor()) < 2
150150
}
151151

152+
/**
153+
* Holds if a memory operand is connected to a definition with an unmodeled result, other than
154+
* `UnmodeledDefinition` itself.
155+
*/
156+
query predicate memoryOperandDefinitionIsUnmodeled(
157+
Instruction instr, string message, IRFunction func, string funcText
158+
) {
159+
exists(MemoryOperand operand, Instruction def |
160+
operand = instr.getAnOperand() and
161+
not operand instanceof UnmodeledUseOperand and
162+
def = operand.getAnyDef() and
163+
not def.isResultModeled() and
164+
not def instanceof UnmodeledDefinitionInstruction and
165+
message =
166+
"Memory operand definition has unmodeled result, but is not the `UnmodeledDefinition` instruction in function '$@'" and
167+
func = instr.getEnclosingIRFunction() and
168+
funcText = Language::getIdentityString(func.getFunction())
169+
)
170+
}
171+
152172
/**
153173
* Holds if operand `operand` consumes a value that was defined in
154174
* a different function.

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ abstract class TranslatedParameter extends TranslatedElement {
454454
result = getInstruction(InitializerVariableAddressTag())
455455
or
456456
operandTag instanceof LoadOperandTag and
457-
result = getInstruction(InitializerStoreTag())
457+
result = getTranslatedFunction(getFunction()).getUnmodeledDefinitionInstruction()
458458
)
459459
or
460460
tag = InitializerIndirectStoreTag() and

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRSanity.qll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,26 @@ module InstructionSanity {
149149
count(instr.getBlock().getAPredecessor()) < 2
150150
}
151151

152+
/**
153+
* Holds if a memory operand is connected to a definition with an unmodeled result, other than
154+
* `UnmodeledDefinition` itself.
155+
*/
156+
query predicate memoryOperandDefinitionIsUnmodeled(
157+
Instruction instr, string message, IRFunction func, string funcText
158+
) {
159+
exists(MemoryOperand operand, Instruction def |
160+
operand = instr.getAnOperand() and
161+
not operand instanceof UnmodeledUseOperand and
162+
def = operand.getAnyDef() and
163+
not def.isResultModeled() and
164+
not def instanceof UnmodeledDefinitionInstruction and
165+
message =
166+
"Memory operand definition has unmodeled result, but is not the `UnmodeledDefinition` instruction in function '$@'" and
167+
func = instr.getEnclosingIRFunction() and
168+
funcText = Language::getIdentityString(func.getFunction())
169+
)
170+
}
171+
152172
/**
153173
* Holds if operand `operand` consumes a value that was defined in
154174
* a different function.

cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ instructionWithoutSuccessor
1313
ambiguousSuccessors
1414
unexplainedLoop
1515
unnecessaryPhiInstruction
16+
memoryOperandDefinitionIsUnmodeled
1617
operandAcrossFunctions
1718
instructionWithoutUniqueBlock
1819
containsLoopOfForwardEdges

cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity_unsound.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ instructionWithoutSuccessor
1313
ambiguousSuccessors
1414
unexplainedLoop
1515
unnecessaryPhiInstruction
16+
memoryOperandDefinitionIsUnmodeled
1617
operandAcrossFunctions
1718
instructionWithoutUniqueBlock
1819
containsLoopOfForwardEdges

cpp/ql/test/library-tests/ir/ir/raw_ir.expected

Lines changed: 34 additions & 34 deletions
Large diffs are not rendered by default.

cpp/ql/test/library-tests/ir/ir/raw_sanity.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ instructionWithoutSuccessor
1313
ambiguousSuccessors
1414
unexplainedLoop
1515
unnecessaryPhiInstruction
16+
memoryOperandDefinitionIsUnmodeled
1617
operandAcrossFunctions
1718
instructionWithoutUniqueBlock
1819
containsLoopOfForwardEdges

cpp/ql/test/library-tests/ir/ir/unaliased_ssa_sanity.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ instructionWithoutSuccessor
1313
ambiguousSuccessors
1414
unexplainedLoop
1515
unnecessaryPhiInstruction
16+
memoryOperandDefinitionIsUnmodeled
1617
operandAcrossFunctions
1718
instructionWithoutUniqueBlock
1819
containsLoopOfForwardEdges

cpp/ql/test/library-tests/ir/ir/unaliased_ssa_sanity_unsound.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ instructionWithoutSuccessor
1313
ambiguousSuccessors
1414
unexplainedLoop
1515
unnecessaryPhiInstruction
16+
memoryOperandDefinitionIsUnmodeled
1617
operandAcrossFunctions
1718
instructionWithoutUniqueBlock
1819
containsLoopOfForwardEdges

0 commit comments

Comments
 (0)