mirror of
https://github.com/github/codeql.git
synced 2026-05-01 11:45:14 +02:00
C++: Add a subclass of PostUpdateNodes and ensure that 'node.asExpr() instanceof ClassAggregateLiteral' holds for this new node subclass.
This commit is contained in:
@@ -264,6 +264,41 @@ private module Cached {
|
||||
e = getConvertedResultExpression(node.asInstruction(), n)
|
||||
}
|
||||
|
||||
/**
|
||||
* The IR doesn't have an instruction `i` for which this holds:
|
||||
* ```
|
||||
* i.getUnconvertedResultExpression() instanceof ClassAggregateLiteral
|
||||
* ```
|
||||
* and thus we don't automaticallt get a dataflow node for which:
|
||||
* ```
|
||||
* node.asExpr() instanceof ClassAggregateLiteral
|
||||
* ```
|
||||
* This is because the IR represents a `ClassAggregateLiteral` as a sequence
|
||||
* of field writes. To work around this we map `asExpr` on the
|
||||
* `PostUpdateNode` for the last field write to the class aggregate literal.
|
||||
*/
|
||||
private class ClassAggregateInitializerPostUpdateNode extends PostFieldUpdateNode {
|
||||
ClassAggregateLiteral aggr;
|
||||
|
||||
ClassAggregateInitializerPostUpdateNode() {
|
||||
exists(Node node1, FieldContent fc, int position, StoreInstruction store |
|
||||
store.getSourceValue().getUnconvertedResultExpression() =
|
||||
aggr.getFieldExpr(fc.getField(), position) and
|
||||
node1.asInstruction() = store and
|
||||
// This is the last field write from the aggregate initialization.
|
||||
not exists(aggr.getFieldExpr(_, position + 1)) and
|
||||
storeStep(node1, fc, this)
|
||||
)
|
||||
}
|
||||
|
||||
ClassAggregateLiteral getClassAggregateLiteral() { result = aggr }
|
||||
}
|
||||
|
||||
private predicate exprNodeShouldBePostUpdateNode(Node node, Expr e, int n) {
|
||||
node.(ClassAggregateInitializerPostUpdateNode).getClassAggregateLiteral() = e and
|
||||
n = 0
|
||||
}
|
||||
|
||||
/** Holds if `node` should be an `IndirectInstruction` that maps `node.asIndirectExpr()` to `e`. */
|
||||
private predicate indirectExprNodeShouldBeIndirectInstruction(
|
||||
IndirectInstruction node, Expr e, int n, int indirectionIndex
|
||||
@@ -294,7 +329,8 @@ private module Cached {
|
||||
exprNodeShouldBeInstruction(_, e, n) or
|
||||
exprNodeShouldBeOperand(_, e, n) or
|
||||
exprNodeShouldBeIndirectOutNode(_, e, n) or
|
||||
exprNodeShouldBeIndirectOperand(_, e, n)
|
||||
exprNodeShouldBeIndirectOperand(_, e, n) or
|
||||
exprNodeShouldBePostUpdateNode(_, e, n)
|
||||
}
|
||||
|
||||
private class InstructionExprNode extends ExprNodeBase, InstructionNode {
|
||||
@@ -442,6 +478,12 @@ private module Cached {
|
||||
final override Expr getConvertedExpr(int n) { exprNodeShouldBeIndirectOperand(this, result, n) }
|
||||
}
|
||||
|
||||
private class PostUpdateExprNode extends ExprNodeBase instanceof PostUpdateNode {
|
||||
PostUpdateExprNode() { exprNodeShouldBePostUpdateNode(this, _, _) }
|
||||
|
||||
final override Expr getConvertedExpr(int n) { exprNodeShouldBePostUpdateNode(this, result, n) }
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression, viewed as a node in a data flow graph.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user