Skip to content

Commit 7f2c6dd

Browse files
author
Dave Bartolomeo
committed
C++/C#: Remove UnmodeledUseOperand
1 parent 3c233c7 commit 7f2c6dd

30 files changed

+128
-328
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,9 +590,7 @@ module Opcode {
590590
class UnmodeledUse extends Opcode, TUnmodeledUse {
591591
final override string toString() { result = "UnmodeledUse" }
592592

593-
final override predicate hasOperandInternal(OperandTag tag) {
594-
tag instanceof UnmodeledUseOperandTag
595-
}
593+
final override predicate hasOperandInternal(OperandTag tag) { none() }
596594
}
597595

598596
class AliasedDefinition extends Opcode, TAliasedDefinition {

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ module InstructionConsistency {
5555
operand.getOperandTag() = tag
5656
) and
5757
operandCount > 1 and
58-
not tag instanceof UnmodeledUseOperandTag and
5958
message =
6059
"Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
6160
" in function '$@'." and
@@ -158,7 +157,6 @@ module InstructionConsistency {
158157
) {
159158
exists(MemoryOperand operand, Instruction def |
160159
operand = instr.getAnOperand() and
161-
not operand instanceof UnmodeledUseOperand and
162160
def = operand.getAnyDef() and
163161
not def.isResultModeled() and
164162
not def instanceof UnmodeledDefinitionInstruction and

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

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@ private newtype TOperand =
1919
) {
2020
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
2121
not Construction::isInCycle(useInstr) and
22-
(
23-
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
24-
or
25-
tag instanceof UnmodeledUseOperandTag
26-
)
22+
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
2723
} or
2824
TPhiOperand(
2925
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -327,16 +323,6 @@ class ConditionOperand extends RegisterOperand {
327323
override string toString() { result = "Condition" }
328324
}
329325

330-
/**
331-
* An operand of the special `UnmodeledUse` instruction, representing a value
332-
* whose set of uses is unknown.
333-
*/
334-
class UnmodeledUseOperand extends NonPhiMemoryOperand {
335-
override UnmodeledUseOperandTag tag;
336-
337-
override string toString() { result = "UnmodeledUse" }
338-
}
339-
340326
/**
341327
* The operand representing the target function of an `Call` instruction.
342328
*/

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,10 @@ private predicate resultMayReachReturn(Instruction instr) { operandMayReachRetur
247247
private predicate resultEscapesNonReturn(Instruction instr) {
248248
// The result escapes if it has at least one use that escapes.
249249
operandEscapesNonReturn(instr.getAUse())
250+
or
251+
// The result also escapes if it is not modeled in SSA, because we do not know where it might be
252+
// used.
253+
not instr.isResultModeled()
250254
}
251255

252256
/**

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

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -128,23 +128,10 @@ private module Cached {
128128
oldOperand = oldInstruction.getAnOperand() and
129129
tag = oldOperand.getOperandTag() and
130130
(
131-
(
132-
if exists(Alias::getOperandMemoryLocation(oldOperand))
133-
then hasMemoryOperandDefinition(oldInstruction, oldOperand, overlap, result)
134-
else (
135-
result = instruction.getEnclosingIRFunction().getUnmodeledDefinitionInstruction() and
136-
overlap instanceof MustTotallyOverlap
137-
)
138-
)
139-
or
140-
// Connect any definitions that are not being modeled in SSA to the
141-
// `UnmodeledUse` instruction.
142-
exists(OldInstruction oldDefinition |
143-
instruction instanceof UnmodeledUseInstruction and
144-
tag instanceof UnmodeledUseOperandTag and
145-
oldDefinition = oldOperand.getAnyDef() and
146-
not exists(Alias::getResultMemoryLocation(oldDefinition)) and
147-
result = getNewInstruction(oldDefinition) and
131+
if exists(Alias::getOperandMemoryLocation(oldOperand))
132+
then hasMemoryOperandDefinition(oldInstruction, oldOperand, overlap, result)
133+
else (
134+
result = instruction.getEnclosingIRFunction().getUnmodeledDefinitionInstruction() and
148135
overlap instanceof MustTotallyOverlap
149136
)
150137
)
@@ -154,13 +141,6 @@ private module Cached {
154141
tag instanceof ChiPartialOperandTag and
155142
overlap instanceof MustExactlyOverlap
156143
or
157-
exists(IRFunction f |
158-
tag instanceof UnmodeledUseOperandTag and
159-
result = f.getUnmodeledDefinitionInstruction() and
160-
instruction = f.getUnmodeledUseInstruction() and
161-
overlap instanceof MustTotallyOverlap
162-
)
163-
or
164144
tag instanceof ChiTotalOperandTag and
165145
result = getChiInstructionTotalOperand(instruction) and
166146
overlap instanceof MustExactlyOverlap

cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ private newtype TOperandTag =
1515
TLeftOperand() or
1616
TRightOperand() or
1717
TConditionOperand() or
18-
TUnmodeledUseOperand() or
1918
TCallTargetOperand() or
2019
TThisArgumentOperand() or
2120
TPositionalArgumentOperand(int argIndex) { Language::hasPositionalArgIndex(argIndex) } or
@@ -165,18 +164,6 @@ class ConditionOperandTag extends RegisterOperandTag, TConditionOperand {
165164

166165
ConditionOperandTag conditionOperand() { result = TConditionOperand() }
167166

168-
/**
169-
* An operand of the special `UnmodeledUse` instruction, representing a value
170-
* whose set of uses is unknown.
171-
*/
172-
class UnmodeledUseOperandTag extends MemoryOperandTag, TUnmodeledUseOperand {
173-
final override string toString() { result = "UnmodeledUse" }
174-
175-
final override int getSortOrder() { result = 9 }
176-
}
177-
178-
UnmodeledUseOperandTag unmodeledUseOperand() { result = TUnmodeledUseOperand() }
179-
180167
/**
181168
* The operand representing the target function of an `Call` instruction.
182169
*/

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ module InstructionConsistency {
5555
operand.getOperandTag() = tag
5656
) and
5757
operandCount > 1 and
58-
not tag instanceof UnmodeledUseOperandTag and
5958
message =
6059
"Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" +
6160
" in function '$@'." and
@@ -158,7 +157,6 @@ module InstructionConsistency {
158157
) {
159158
exists(MemoryOperand operand, Instruction def |
160159
operand = instr.getAnOperand() and
161-
not operand instanceof UnmodeledUseOperand and
162160
def = operand.getAnyDef() and
163161
not def.isResultModeled() and
164162
not def instanceof UnmodeledDefinitionInstruction and

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

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@ private newtype TOperand =
1919
) {
2020
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
2121
not Construction::isInCycle(useInstr) and
22-
(
23-
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
24-
or
25-
tag instanceof UnmodeledUseOperandTag
26-
)
22+
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
2723
} or
2824
TPhiOperand(
2925
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -327,16 +323,6 @@ class ConditionOperand extends RegisterOperand {
327323
override string toString() { result = "Condition" }
328324
}
329325

330-
/**
331-
* An operand of the special `UnmodeledUse` instruction, representing a value
332-
* whose set of uses is unknown.
333-
*/
334-
class UnmodeledUseOperand extends NonPhiMemoryOperand {
335-
override UnmodeledUseOperandTag tag;
336-
337-
override string toString() { result = "UnmodeledUse" }
338-
}
339-
340326
/**
341327
* The operand representing the target function of an `Call` instruction.
342328
*/

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,25 @@ private module Cached {
9191
Instruction getRegisterOperandDefinition(Instruction instruction, RegisterOperandTag tag) {
9292
result =
9393
getInstructionTranslatedElement(instruction)
94-
.getInstructionOperand(getInstructionTag(instruction), tag)
94+
.getInstructionRegisterOperand(getInstructionTag(instruction), tag)
9595
}
9696

9797
cached
9898
Instruction getMemoryOperandDefinition(
9999
Instruction instruction, MemoryOperandTag tag, Overlap overlap
100100
) {
101-
result =
102-
getInstructionTranslatedElement(instruction)
103-
.getInstructionOperand(getInstructionTag(instruction), tag) and
104-
overlap instanceof MustTotallyOverlap
101+
exists(TranslatedElement translatedElement, TranslatedFunction translatedFunc |
102+
translatedElement = getInstructionTranslatedElement(instruction) and
103+
exists(getInstructionOperandType(instruction, tag)) and
104+
translatedFunc = getTranslatedFunction(instruction.getEnclosingFunction()) and
105+
result = translatedFunc.getUnmodeledDefinitionInstruction() and
106+
overlap instanceof MustTotallyOverlap
107+
)
108+
or
109+
// Without the code below, the optimizer will realize that raw IR never contains Chi operands,
110+
// and report an error that `ChiTotalOperand` and `ChiPartialOperand` are infeasible.
111+
(tag instanceof ChiTotalOperandTag or tag instanceof ChiPartialOperandTag) and
112+
none()
105113
}
106114

107115
/** Gets a non-phi instruction that defines an operand of `instr`. */
@@ -144,12 +152,13 @@ private module Cached {
144152
CppType getInstructionOperandType(Instruction instruction, TypedOperandTag tag) {
145153
// For all `LoadInstruction`s, the operand type of the `LoadOperand` is the same as
146154
// the result type of the load.
155+
tag instanceof LoadOperandTag and
147156
result = instruction.(LoadInstruction).getResultLanguageType()
148157
or
149158
not instruction instanceof LoadInstruction and
150159
result =
151160
getInstructionTranslatedElement(instruction)
152-
.getInstructionOperandType(getInstructionTag(instruction), tag)
161+
.getInstructionMemoryOperandType(getInstructionTag(instruction), tag)
153162
}
154163

155164
cached

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

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ abstract class TranslatedCall extends TranslatedExpr {
9494
)
9595
}
9696

97-
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
97+
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
9898
tag = CallTag() and
9999
(
100100
operandTag instanceof CallTargetOperandTag and
@@ -115,7 +115,9 @@ abstract class TranslatedCall extends TranslatedExpr {
115115
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
116116
}
117117

118-
final override CppType getInstructionOperandType(InstructionTag tag, TypedOperandTag operandTag) {
118+
final override CppType getInstructionMemoryOperandType(
119+
InstructionTag tag, TypedOperandTag operandTag
120+
) {
119121
tag = CallSideEffectTag() and
120122
hasSideEffect() and
121123
operandTag instanceof SideEffectOperandTag and
@@ -381,7 +383,7 @@ class TranslatedAllocationSideEffects extends TranslatedSideEffects,
381383
else result = getParent().getChildSuccessor(this)
382384
}
383385

384-
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
386+
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
385387
tag = OnlyInstructionTag() and
386388
operandTag = addressOperand() and
387389
result = getPrimaryInstructionForSideEffect(OnlyInstructionTag())
@@ -437,7 +439,7 @@ class TranslatedStructorCallSideEffects extends TranslatedCallSideEffects {
437439

438440
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
439441

440-
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
442+
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
441443
tag instanceof OnlyInstructionTag and
442444
operandTag instanceof AddressOperandTag and
443445
result = getParent().(TranslatedStructorCall).getQualifierResult()
@@ -513,25 +515,21 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
513515
kind instanceof GotoEdge
514516
}
515517

516-
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
518+
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
517519
tag instanceof OnlyInstructionTag and
518520
operandTag instanceof AddressOperandTag and
519521
result = getTranslatedExpr(arg).getResult()
520522
or
521523
tag instanceof OnlyInstructionTag and
522-
operandTag instanceof SideEffectOperandTag and
523-
not isWrite() and
524-
result = getEnclosingFunction().getUnmodeledDefinitionInstruction()
525-
or
526-
tag instanceof OnlyInstructionTag and
527524
operandTag instanceof BufferSizeOperandTag and
528525
result =
529526
getTranslatedExpr(call
530527
.getArgument(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index))
531528
.getFullyConverted()).getResult()
532529
}
533530

534-
override CppType getInstructionOperandType(InstructionTag tag, TypedOperandTag operandTag) {
531+
override CppType getInstructionMemoryOperandType(InstructionTag tag, TypedOperandTag operandTag) {
532+
not isWrite() and
535533
if hasSpecificReadSideEffect(any(BufferAccessOpcode op))
536534
then
537535
result = getUnknownType() and

0 commit comments

Comments
 (0)