Skip to content

Commit 650539d

Browse files
C++: IR sanity query unnecessaryPhiInstruction
Have `Instruction.getResultSize()` return zero for `void`.
1 parent f4a0600 commit 650539d

File tree

6 files changed

+65
-41
lines changed

6 files changed

+65
-41
lines changed

cpp/ql/src/semmle/code/cpp/ir/internal/Instruction.qll

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,14 @@ module InstructionSanity {
6868
}
6969

7070
/**
71-
* Holds if `Phi` instruction `instr` has fewer than two operands.
71+
* Holds if `Phi` instruction `instr` is missing an operand corresponding to
72+
* the predecessor block `pred`.
7273
*/
73-
query predicate missingPhiOperands(PhiInstruction instr, int predIndex, Location predLoc) {
74-
exists(IRBlock pred |
75-
pred = instr.getBlock().getAPredecessor() and
76-
predLoc = pred.getLocation() and
77-
predIndex = pred.getDisplayIndex() and
78-
not exists(PhiOperand operand |
79-
exists(instr.getOperand(operand)) and
80-
operand.getPredecessorBlock() = pred
81-
)
74+
query predicate missingPhiOperand(PhiInstruction instr, IRBlock pred) {
75+
pred = instr.getBlock().getAPredecessor() and
76+
not exists(PhiOperand operand |
77+
exists(instr.getOperand(operand)) and
78+
operand.getPredecessorBlock() = pred
8279
)
8380
}
8481

@@ -92,6 +89,18 @@ module InstructionSanity {
9289
not instr instanceof PhiInstruction
9390
}
9491

92+
/**
93+
* Holds if a `Phi` instruction is present in a block with fewer than two
94+
* predecessors.
95+
*/
96+
query predicate unnecessaryPhiInstruction(PhiInstruction instr) {
97+
count(instr.getBlock().getAPredecessor()) < 2
98+
}
99+
100+
/**
101+
* Holds if instruction `op` consumes an operand `operand` that was defined in
102+
* a different function.
103+
*/
95104
query predicate operandAcrossFunctions(
96105
Instruction op, Instruction operand, OperandTag tag
97106
) {
@@ -321,8 +330,7 @@ class Instruction extends Construction::TInstruction {
321330

322331
/**
323332
* Gets the size of the result produced by this instruction, in bytes. If the
324-
* instruction does not produce a result, or if the result does not have a
325-
* known constant size, this predicate does not hold.
333+
* result does not have a known constant size, this predicate does not hold.
326334
*
327335
* If `this.isGLValue()` holds for this instruction, the value of
328336
* `getResultSize()` will always be the size of a pointer.
@@ -337,7 +345,6 @@ class Instruction extends Construction::TInstruction {
337345
else if resultType instanceof UnknownType then
338346
result = Construction::getInstructionResultSize(this)
339347
else (
340-
not resultType instanceof VoidType and
341348
result = resultType.getSize()
342349
)
343350
}

cpp/ql/src/semmle/code/cpp/ssa/internal/aliased_ssa/Instruction.qll

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,14 @@ module InstructionSanity {
6868
}
6969

7070
/**
71-
* Holds if `Phi` instruction `instr` has fewer than two operands.
71+
* Holds if `Phi` instruction `instr` is missing an operand corresponding to
72+
* the predecessor block `pred`.
7273
*/
73-
query predicate missingPhiOperand(PhiInstruction instr, int predIndex, Location predLoc) {
74-
exists(IRBlock pred |
75-
pred = instr.getBlock().getAPredecessor() and
76-
predLoc = pred.getLocation() and
77-
predIndex = pred.getDisplayIndex() and
78-
not exists(PhiOperand operand |
79-
exists(instr.getOperand(operand)) and
80-
operand.getPredecessorBlock() = pred
81-
)
74+
query predicate missingPhiOperand(PhiInstruction instr, IRBlock pred) {
75+
pred = instr.getBlock().getAPredecessor() and
76+
not exists(PhiOperand operand |
77+
exists(instr.getOperand(operand)) and
78+
operand.getPredecessorBlock() = pred
8279
)
8380
}
8481

@@ -92,6 +89,18 @@ module InstructionSanity {
9289
not instr instanceof PhiInstruction
9390
}
9491

92+
/**
93+
* Holds if a `Phi` instruction is present in a block with fewer than two
94+
* predecessors.
95+
*/
96+
query predicate unnecessaryPhiInstruction(PhiInstruction instr) {
97+
count(instr.getBlock().getAPredecessor()) < 2
98+
}
99+
100+
/**
101+
* Holds if instruction `op` consumes an operand `operand` that was defined in
102+
* a different function.
103+
*/
95104
query predicate operandAcrossFunctions(
96105
Instruction op, Instruction operand, OperandTag tag
97106
) {
@@ -321,8 +330,7 @@ class Instruction extends Construction::TInstruction {
321330

322331
/**
323332
* Gets the size of the result produced by this instruction, in bytes. If the
324-
* instruction does not produce a result, or if the result does not have a
325-
* known constant size, this predicate does not hold.
333+
* result does not have a known constant size, this predicate does not hold.
326334
*
327335
* If `this.isGLValue()` holds for this instruction, the value of
328336
* `getResultSize()` will always be the size of a pointer.
@@ -337,7 +345,6 @@ class Instruction extends Construction::TInstruction {
337345
else if resultType instanceof UnknownType then
338346
result = Construction::getInstructionResultSize(this)
339347
else (
340-
not resultType instanceof VoidType and
341348
result = resultType.getSize()
342349
)
343350
}

cpp/ql/src/semmle/code/cpp/ssa/internal/ssa/Instruction.qll

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,14 @@ module InstructionSanity {
6868
}
6969

7070
/**
71-
* Holds if `Phi` instruction `instr` has fewer than two operands.
71+
* Holds if `Phi` instruction `instr` is missing an operand corresponding to
72+
* the predecessor block `pred`.
7273
*/
73-
query predicate missingPhiOperands(PhiInstruction instr, int predIndex, Location predLoc) {
74-
exists(IRBlock pred |
75-
pred = instr.getBlock().getAPredecessor() and
76-
predLoc = pred.getLocation() and
77-
predIndex = pred.getDisplayIndex() and
78-
not exists(PhiOperand operand |
79-
exists(instr.getOperand(operand)) and
80-
operand.getPredecessorBlock() = pred
81-
)
74+
query predicate missingPhiOperand(PhiInstruction instr, IRBlock pred) {
75+
pred = instr.getBlock().getAPredecessor() and
76+
not exists(PhiOperand operand |
77+
exists(instr.getOperand(operand)) and
78+
operand.getPredecessorBlock() = pred
8279
)
8380
}
8481

@@ -92,6 +89,18 @@ module InstructionSanity {
9289
not instr instanceof PhiInstruction
9390
}
9491

92+
/**
93+
* Holds if a `Phi` instruction is present in a block with fewer than two
94+
* predecessors.
95+
*/
96+
query predicate unnecessaryPhiInstruction(PhiInstruction instr) {
97+
count(instr.getBlock().getAPredecessor()) < 2
98+
}
99+
100+
/**
101+
* Holds if instruction `op` consumes an operand `operand` that was defined in
102+
* a different function.
103+
*/
95104
query predicate operandAcrossFunctions(
96105
Instruction op, Instruction operand, OperandTag tag
97106
) {
@@ -321,8 +330,7 @@ class Instruction extends Construction::TInstruction {
321330

322331
/**
323332
* Gets the size of the result produced by this instruction, in bytes. If the
324-
* instruction does not produce a result, or if the result does not have a
325-
* known constant size, this predicate does not hold.
333+
* result does not have a known constant size, this predicate does not hold.
326334
*
327335
* If `this.isGLValue()` holds for this instruction, the value of
328336
* `getResultSize()` will always be the size of a pointer.
@@ -337,7 +345,6 @@ class Instruction extends Construction::TInstruction {
337345
else if resultType instanceof UnknownType then
338346
result = Construction::getInstructionResultSize(this)
339347
else (
340-
not resultType instanceof VoidType and
341348
result = resultType.getSize()
342349
)
343350
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ unexpectedOperand
33
duplicateOperand
44
missingPhiOperand
55
instructionWithoutSuccessor
6+
unnecessaryPhiInstruction
67
operandAcrossFunctions
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
missingOperand
22
unexpectedOperand
33
duplicateOperand
4-
missingPhiOperands
4+
missingPhiOperand
55
instructionWithoutSuccessor
6+
unnecessaryPhiInstruction
67
operandAcrossFunctions
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
missingOperand
22
unexpectedOperand
33
duplicateOperand
4-
missingPhiOperands
4+
missingPhiOperand
55
instructionWithoutSuccessor
6+
unnecessaryPhiInstruction
67
operandAcrossFunctions

0 commit comments

Comments
 (0)