mirror of
https://github.com/github/codeql.git
synced 2025-12-22 19:56:32 +01:00
C++: Reduce code duplication by moving shared code into a module.
This commit is contained in:
@@ -1273,6 +1273,33 @@ abstract private class IndirectExprNodeBase extends Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A signature for converting an indirect node to an expression. */
|
||||||
|
private signature module IndirectNodeToIndirectExprSig {
|
||||||
|
/** The indirect node class to be converted to an expression */
|
||||||
|
class IndirectNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the indirect expression at indirection index `indirectionIndex`
|
||||||
|
* of `node` is `e`. The integer `n` specifies how many conversions has been
|
||||||
|
* applied to `node`.
|
||||||
|
*/
|
||||||
|
predicate indirectNodeHasIndirectExpr(IndirectNode node, Expr e, int n, int indirectionIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A module that implements the logic for deciding whether an indirect node
|
||||||
|
* should be an `IndirectExprNode`.
|
||||||
|
*/
|
||||||
|
private module IndirectNodeToIndirectExpr<IndirectNodeToIndirectExprSig Sig> {
|
||||||
|
import Sig
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This predicate shifts the indirection index by one when `conv` is a
|
||||||
|
* `ReferenceDereferenceExpr`.
|
||||||
|
*
|
||||||
|
* This is necessary because `ReferenceDereferenceExpr` is a conversion
|
||||||
|
* in the AST, but appears as a `LoadInstruction` in the IR.
|
||||||
|
*/
|
||||||
bindingset[e, indirectionIndex]
|
bindingset[e, indirectionIndex]
|
||||||
private predicate adjustForReference(
|
private predicate adjustForReference(
|
||||||
Expr e, int indirectionIndex, Expr conv, int adjustedIndirectionIndex
|
Expr e, int indirectionIndex, Expr conv, int adjustedIndirectionIndex
|
||||||
@@ -1285,37 +1312,51 @@ private predicate adjustForReference(
|
|||||||
adjustedIndirectionIndex = indirectionIndex
|
adjustedIndirectionIndex = indirectionIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase instanceof IndirectOperand
|
/** Holds if `node` should be an `IndirectExprNode`. */
|
||||||
{
|
predicate charpred(IndirectNode node) {
|
||||||
IndirectOperandIndirectExprNode() {
|
|
||||||
exists(Expr e, int n, int indirectionIndex |
|
exists(Expr e, int n, int indirectionIndex |
|
||||||
indirectExprNodeShouldBeIndirectOperand(this, e, n, indirectionIndex) and
|
indirectNodeHasIndirectExpr(node, e, n, indirectionIndex) and
|
||||||
not exists(Expr conv, int adjustedIndirectionIndex |
|
not exists(Expr conv, int adjustedIndirectionIndex |
|
||||||
adjustForReference(e, indirectionIndex, conv, adjustedIndirectionIndex) and
|
adjustForReference(e, indirectionIndex, conv, adjustedIndirectionIndex) and
|
||||||
indirectExprNodeShouldBeIndirectOperand(_, conv, n + 1, adjustedIndirectionIndex)
|
indirectNodeHasIndirectExpr(_, conv, n + 1, adjustedIndirectionIndex)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private module IndirectOperandIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
|
||||||
|
class IndirectNode = IndirectOperand;
|
||||||
|
|
||||||
|
predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectOperand/4;
|
||||||
|
}
|
||||||
|
|
||||||
|
module IndirectOperandToIndirectExpr =
|
||||||
|
IndirectNodeToIndirectExpr<IndirectOperandIndirectExprNodeImpl>;
|
||||||
|
|
||||||
|
private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase instanceof IndirectOperand
|
||||||
|
{
|
||||||
|
IndirectOperandIndirectExprNode() { IndirectOperandToIndirectExpr::charpred(this) }
|
||||||
|
|
||||||
final override Expr getConvertedExpr(int n, int index) {
|
final override Expr getConvertedExpr(int n, int index) {
|
||||||
indirectExprNodeShouldBeIndirectOperand(this, result, n, index)
|
IndirectOperandToIndirectExpr::indirectNodeHasIndirectExpr(this, result, n, index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private module IndirectInstructionIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
|
||||||
|
class IndirectNode = IndirectInstruction;
|
||||||
|
|
||||||
|
predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectInstruction/4;
|
||||||
|
}
|
||||||
|
|
||||||
|
module IndirectInstructionToIndirectExpr =
|
||||||
|
IndirectNodeToIndirectExpr<IndirectInstructionIndirectExprNodeImpl>;
|
||||||
|
|
||||||
private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase instanceof IndirectInstruction
|
private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase instanceof IndirectInstruction
|
||||||
{
|
{
|
||||||
IndirectInstructionIndirectExprNode() {
|
IndirectInstructionIndirectExprNode() { IndirectInstructionToIndirectExpr::charpred(this) }
|
||||||
exists(Expr e, int n, int indirectionIndex |
|
|
||||||
indirectExprNodeShouldBeIndirectInstruction(this, e, n, indirectionIndex) and
|
|
||||||
not exists(Expr conv, int adjustedIndirectionIndex |
|
|
||||||
adjustForReference(e, indirectionIndex, conv, adjustedIndirectionIndex) and
|
|
||||||
not indirectExprNodeShouldBeIndirectInstruction(_, conv, n + 1, adjustedIndirectionIndex)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
final override Expr getConvertedExpr(int n, int index) {
|
final override Expr getConvertedExpr(int n, int index) {
|
||||||
indirectExprNodeShouldBeIndirectInstruction(this, result, n, index)
|
IndirectInstructionToIndirectExpr::indirectNodeHasIndirectExpr(this, result, n, index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user