@@ -45,6 +45,28 @@ private module Cached {
4545 )
4646 }
4747
48+ private Expr getRankedElementExpr ( ArrayAggregateLiteral aggr , int rnk ) {
49+ result =
50+ rank [ rnk + 1 ] ( Expr e , int elementIndex , int position |
51+ e = aggr .getElementExpr ( elementIndex , position )
52+ |
53+ e order by elementIndex , position
54+ )
55+ }
56+
57+ private class LastArrayAggregateStore extends StoreInstruction {
58+ ArrayAggregateLiteral aggr ;
59+
60+ LastArrayAggregateStore ( ) {
61+ exists ( int rnk |
62+ this .getSourceValue ( ) .getUnconvertedResultExpression ( ) = getRankedElementExpr ( aggr , rnk ) and
63+ not exists ( getRankedElementExpr ( aggr , rnk + 1 ) )
64+ )
65+ }
66+
67+ ArrayAggregateLiteral getArrayAggregateLiteral ( ) { result = aggr }
68+ }
69+
4870 private Expr getConvertedResultExpressionImpl0 ( Instruction instr ) {
4971 // IR construction inserts an additional cast to a `size_t` on the extent
5072 // of a `new[]` expression. The resulting `ConvertInstruction` doesn't have
@@ -95,6 +117,16 @@ private module Cached {
95117 tco .producesExprResult ( ) and
96118 result = asDefinitionImpl0 ( instr )
97119 )
120+ or
121+ // IR construction breaks an array aggregate literal `{1, 2, 3}` into a
122+ // sequence of `StoreInstruction`s. So there's no instruction `i` for which
123+ // `i.getUnconvertedResultExpression() instanceof ArrayAggregateLiteral`.
124+ // So we map the instruction node corresponding to the last `Store`
125+ // instruction of the sequence to the result of the array aggregate
126+ // literal. This makes sense since this store will immediately flow into
127+ // the indirect node representing the array. So this node does represent
128+ // the array after it has been fully initialized.
129+ result = instr .( LastArrayAggregateStore ) .getArrayAggregateLiteral ( )
98130 }
99131
100132 private Expr getConvertedResultExpressionImpl ( Instruction instr ) {
0 commit comments