Skip to content

Commit 195b811

Browse files
committed
C++: handle phi operands from unreachable blocks
1 parent 6600436 commit 195b811

File tree

6 files changed

+30
-17
lines changed

6 files changed

+30
-17
lines changed

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,22 @@ private module Cached {
6868
instr instanceof TUnreachedInstruction
6969
}
7070

71-
private IRBlock getNewBlock(OldBlock oldBlock) {
72-
result.getFirstInstruction() = getNewInstruction(oldBlock.getFirstInstruction())
71+
cached IRBlock getNewBlock(OldBlock oldBlock) {
72+
exists(Instruction newEnd, OldIR::Instruction oldEnd |
73+
(
74+
result.getLastInstruction() = newEnd and
75+
not newEnd instanceof ChiInstruction
76+
or
77+
newEnd = result.getLastInstruction().(ChiInstruction).getAPredecessor() // does this work?
78+
) and
79+
(
80+
oldBlock.getLastInstruction() = oldEnd and
81+
not oldEnd instanceof OldIR::ChiInstruction
82+
or
83+
oldEnd = oldBlock.getLastInstruction().(OldIR::ChiInstruction).getAPredecessor() // does this work?
84+
) and
85+
oldEnd = getNewInstruction(newEnd)
86+
)
7387
}
7488

7589
/**
@@ -164,7 +178,7 @@ private module Cached {
164178
(
165179
result = getNewInstruction(oldOperand.getAnyDef()) and
166180
overlap = originalOverlap
167-
or
181+
or
168182
exists(OldIR::PhiInputOperand phiOperand, Overlap phiOperandOverlap |
169183
phiOperand = getDegeneratePhiOperand(oldOperand.getAnyDef()) and
170184
result = getNewDefinitionFromOldSSA(phiOperand, phiOperandOverlap) and

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

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,9 @@ private module Internal {
3636
useInstr.getOpcode().hasOperand(tag)
3737
} or
3838
TUnaliasedPhiOperand(
39-
Unaliased::PhiInstruction useInstr, Unaliased::Instruction defInstr,
40-
Unaliased::IRBlock predecessorBlock, Overlap overlap
39+
Unaliased::PhiInstruction useInstr, Unaliased::IRBlock predecessorBlock, Overlap overlap
4140
) {
42-
defInstr = UnaliasedConstruction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
41+
exists(UnaliasedConstruction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap))
4342
} or
4443
//// ALIASED
4544
////
@@ -50,10 +49,9 @@ private module Internal {
5049
// important that we use the same definition of "is variable aliased" across
5150
// the phases.
5251
TAliasedPhiOperand(
53-
TAliasedSSAPhiInstruction useInstr, Aliased::Instruction defInstr,
54-
Aliased::IRBlock predecessorBlock, Overlap overlap
52+
TAliasedSSAPhiInstruction useInstr, Aliased::IRBlock predecessorBlock, Overlap overlap
5553
) {
56-
defInstr = AliasedConstruction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
54+
exists(AliasedConstruction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap))
5755
} or
5856
TAliasedChiOperand(TAliasedSSAChiInstruction useInstr, ChiOperandTag tag) { any() }
5957
}
@@ -144,7 +142,8 @@ module UnaliasedSSAOperands {
144142
Unaliased::PhiInstruction useInstr, Unaliased::Instruction defInstr,
145143
Unaliased::IRBlock predecessorBlock, Overlap overlap
146144
) {
147-
result = Internal::TUnaliasedPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
145+
defInstr = UnaliasedConstruction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap) and
146+
result = Internal::TUnaliasedPhiOperand(useInstr, predecessorBlock, overlap)
148147
}
149148

150149
TPhiOperand reusedPhiOperand(
@@ -182,7 +181,8 @@ module AliasedSSAOperands {
182181
Aliased::PhiInstruction useInstr, Aliased::Instruction defInstr,
183182
Aliased::IRBlock predecessorBlock, Overlap overlap
184183
) {
185-
result = Internal::TAliasedPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
184+
defInstr = AliasedConstruction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap) and
185+
result = Internal::TAliasedPhiOperand(useInstr, predecessorBlock, overlap)
186186
}
187187

188188
/**
@@ -193,8 +193,9 @@ module AliasedSSAOperands {
193193
Aliased::IRBlock predecessorBlock, Overlap overlap
194194
) {
195195
exists(Unaliased::IRBlock oldBlock |
196-
predecessorBlock.getFirstInstruction() = oldBlock.getFirstInstruction() and
197-
result = Internal::TUnaliasedPhiOperand(useInstr, defInstr, oldBlock, overlap)
196+
predecessorBlock = AliasedConstruction::getNewBlock(oldBlock) and
197+
result = Internal::TUnaliasedPhiOperand(useInstr, oldBlock, _) and
198+
defInstr = AliasedConstruction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
198199
)
199200
}
200201

cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ missingOperand
22
unexpectedOperand
33
duplicateOperand
44
missingPhiOperand
5-
| ssa.cpp:398:3:398:13 | Phi: return ... | Instruction 'Phi: return ...' is missing an operand for predecessor block 'VariableAddress: y' in function '$@'. | ssa.cpp:383:5:383:24 | int FusedBlockPhiOperand(int, int, int, bool) | int FusedBlockPhiOperand(int, int, int, bool) |
65
missingOperandType
76
duplicateChiOperand
87
sideEffectWithoutPrimary

cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency_unsound.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ missingOperand
22
unexpectedOperand
33
duplicateOperand
44
missingPhiOperand
5-
| ssa.cpp:398:3:398:13 | Phi: return ... | Instruction 'Phi: return ...' is missing an operand for predecessor block 'VariableAddress: y' in function '$@'. | ssa.cpp:383:5:383:24 | int FusedBlockPhiOperand(int, int, int, bool) | int FusedBlockPhiOperand(int, int, int, bool) |
65
missingOperandType
76
duplicateChiOperand
87
sideEffectWithoutPrimary

cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1802,7 +1802,7 @@ ssa.cpp:
18021802
#-----| Goto -> Block 4
18031803

18041804
# 398| Block 4
1805-
# 398| m398_1(int) = Phi : from 1:m388_4
1805+
# 398| m398_1(int) = Phi : from 1:m388_4, from 3:m391_4
18061806
# 398| r398_2(glval<int>) = VariableAddress[#return] :
18071807
# 398| r398_3(glval<int>) = VariableAddress[ret] :
18081808
# 398| r398_4(int) = Load[ret] : &:r398_3, m398_1

cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1792,7 +1792,7 @@ ssa.cpp:
17921792
#-----| Goto -> Block 4
17931793

17941794
# 398| Block 4
1795-
# 398| m398_1(int) = Phi : from 1:m388_4
1795+
# 398| m398_1(int) = Phi : from 1:m388_4, from 3:m391_4
17961796
# 398| r398_2(glval<int>) = VariableAddress[#return] :
17971797
# 398| r398_3(glval<int>) = VariableAddress[ret] :
17981798
# 398| r398_4(int) = Load[ret] : &:r398_3, m398_1

0 commit comments

Comments
 (0)