C++: Add a subclass of PostUpdateNodes and ensure that 'node.asExpr() instanceof ClassAggregateLiteral' holds for this new node subclass.

This commit is contained in:
Mathias Vorreiter Pedersen
2025-05-15 16:45:10 +01:00
parent 0f21075722
commit 783560cff6

View File

@@ -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.
*/