mirror of
https://github.com/github/codeql.git
synced 2026-04-24 08:15:14 +02:00
C++: Fix joins in 'controlsBlock'.
This commit is contained in:
@@ -203,30 +203,42 @@ private class GuardConditionFromIR extends GuardCondition {
|
||||
* `&&` and `||`. See the detailed explanation on predicate `controls`.
|
||||
*/
|
||||
private predicate controlsBlock(BasicBlock controlled, boolean testIsTrue) {
|
||||
exists(IRBlock irb, Instruction instr |
|
||||
exists(IRBlock irb |
|
||||
ir.controls(irb, testIsTrue) and
|
||||
instr = irb.getAnInstruction() and
|
||||
instr.getAst().(ControlFlowNode).getBasicBlock() = controlled and
|
||||
not isUnreachedBlock(irb) and
|
||||
not this.excludeAsControlledInstruction(instr)
|
||||
nonExcludedIRAndBasicBlock(irb, controlled) and
|
||||
not isUnreachedBlock(irb)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate excludeAsControlledInstruction(Instruction instr) {
|
||||
// Exclude the temporaries generated by a ternary expression.
|
||||
exists(TranslatedConditionalExpr tce |
|
||||
instr = tce.getInstruction(ConditionValueFalseStoreTag())
|
||||
or
|
||||
instr = tce.getInstruction(ConditionValueTrueStoreTag())
|
||||
or
|
||||
instr = tce.getInstruction(ConditionValueTrueTempAddressTag())
|
||||
or
|
||||
instr = tce.getInstruction(ConditionValueFalseTempAddressTag())
|
||||
)
|
||||
private predicate excludeAsControlledInstruction(Instruction instr) {
|
||||
// Exclude the temporaries generated by a ternary expression.
|
||||
exists(TranslatedConditionalExpr tce |
|
||||
instr = tce.getInstruction(ConditionValueFalseStoreTag())
|
||||
or
|
||||
// Exclude unreached instructions, as their AST is the whole function and not a block.
|
||||
instr instanceof UnreachedInstruction
|
||||
}
|
||||
instr = tce.getInstruction(ConditionValueTrueStoreTag())
|
||||
or
|
||||
instr = tce.getInstruction(ConditionValueTrueTempAddressTag())
|
||||
or
|
||||
instr = tce.getInstruction(ConditionValueFalseTempAddressTag())
|
||||
)
|
||||
or
|
||||
// Exclude unreached instructions, as their AST is the whole function and not a block.
|
||||
instr instanceof UnreachedInstruction
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `irb` is the `IRBlock` corresponding to the AST basic block
|
||||
* `controlled`, and `irb` does not contain any instruction(s) that should make
|
||||
* the `irb` be ignored.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate nonExcludedIRAndBasicBlock(IRBlock irb, BasicBlock controlled) {
|
||||
exists(Instruction instr |
|
||||
instr = irb.getAnInstruction() and
|
||||
instr.getAst().(ControlFlowNode).getBasicBlock() = controlled and
|
||||
not excludeAsControlledInstruction(instr)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user