@@ -264,6 +264,41 @@ private module Cached {
264
264
e = getConvertedResultExpression ( node .asInstruction ( ) , n )
265
265
}
266
266
267
+ /**
268
+ * The IR doesn't have an instruction `i` for which this holds:
269
+ * ```
270
+ * i.getUnconvertedResultExpression() instanceof ClassAggregateLiteral
271
+ * ```
272
+ * and thus we don't automaticallt get a dataflow node for which:
273
+ * ```
274
+ * node.asExpr() instanceof ClassAggregateLiteral
275
+ * ```
276
+ * This is because the IR represents a `ClassAggregateLiteral` as a sequence
277
+ * of field writes. To work around this we map `asExpr` on the
278
+ * `PostUpdateNode` for the last field write to the class aggregate literal.
279
+ */
280
+ private class ClassAggregateInitializerPostUpdateNode extends PostFieldUpdateNode {
281
+ ClassAggregateLiteral aggr ;
282
+
283
+ ClassAggregateInitializerPostUpdateNode ( ) {
284
+ exists ( Node node1 , FieldContent fc , int position , StoreInstruction store |
285
+ store .getSourceValue ( ) .getUnconvertedResultExpression ( ) =
286
+ aggr .getFieldExpr ( fc .getField ( ) , position ) and
287
+ node1 .asInstruction ( ) = store and
288
+ // This is the last field write from the aggregate initialization.
289
+ not exists ( aggr .getFieldExpr ( _, position + 1 ) ) and
290
+ storeStep ( node1 , fc , this )
291
+ )
292
+ }
293
+
294
+ ClassAggregateLiteral getClassAggregateLiteral ( ) { result = aggr }
295
+ }
296
+
297
+ private predicate exprNodeShouldBePostUpdateNode ( Node node , Expr e , int n ) {
298
+ node .( ClassAggregateInitializerPostUpdateNode ) .getClassAggregateLiteral ( ) = e and
299
+ n = 0
300
+ }
301
+
267
302
/** Holds if `node` should be an `IndirectInstruction` that maps `node.asIndirectExpr()` to `e`. */
268
303
private predicate indirectExprNodeShouldBeIndirectInstruction (
269
304
IndirectInstruction node , Expr e , int n , int indirectionIndex
@@ -294,7 +329,8 @@ private module Cached {
294
329
exprNodeShouldBeInstruction ( _, e , n ) or
295
330
exprNodeShouldBeOperand ( _, e , n ) or
296
331
exprNodeShouldBeIndirectOutNode ( _, e , n ) or
297
- exprNodeShouldBeIndirectOperand ( _, e , n )
332
+ exprNodeShouldBeIndirectOperand ( _, e , n ) or
333
+ exprNodeShouldBePostUpdateNode ( _, e , n )
298
334
}
299
335
300
336
private class InstructionExprNode extends ExprNodeBase , InstructionNode {
@@ -442,6 +478,12 @@ private module Cached {
442
478
final override Expr getConvertedExpr ( int n ) { exprNodeShouldBeIndirectOperand ( this , result , n ) }
443
479
}
444
480
481
+ private class PostUpdateExprNode extends ExprNodeBase instanceof PostUpdateNode {
482
+ PostUpdateExprNode ( ) { exprNodeShouldBePostUpdateNode ( this , _, _) }
483
+
484
+ final override Expr getConvertedExpr ( int n ) { exprNodeShouldBePostUpdateNode ( this , result , n ) }
485
+ }
486
+
445
487
/**
446
488
* An expression, viewed as a node in a data flow graph.
447
489
*/
0 commit comments