@@ -45,6 +45,28 @@ private module Cached {
45
45
)
46
46
}
47
47
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
+
48
70
private Expr getConvertedResultExpressionImpl0 ( Instruction instr ) {
49
71
// IR construction inserts an additional cast to a `size_t` on the extent
50
72
// of a `new[]` expression. The resulting `ConvertInstruction` doesn't have
@@ -95,6 +117,16 @@ private module Cached {
95
117
tco .producesExprResult ( ) and
96
118
result = asDefinitionImpl0 ( instr )
97
119
)
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 ( )
98
130
}
99
131
100
132
private Expr getConvertedResultExpressionImpl ( Instruction instr ) {
0 commit comments