@@ -208,10 +208,40 @@ SymbolicValue ConstExprFunctionState::computeConstantValue(SILValue value) {
208208 if (!val.isConstant ()) {
209209 return val;
210210 }
211+ if (val.getKind () == SymbolicValue::Array) {
212+ // Extracting some internal members of Array.
213+ // This code pattern appears for Array literal initialization:
214+ // %buffer = struct_extract %array
215+ // %element0 = ref_tail_addr %buffer
216+ return val;
217+ }
211218 assert (val.getKind () == SymbolicValue::Aggregate);
212219 return val.getAggregateMembers ()[sei->getFieldIndex ()];
213220 }
214221
222+ if (auto *urc = dyn_cast<UncheckedRefCastInst>(value)) {
223+ auto val = getConstantValue (urc->getOperand ());
224+ if (val.getKind () == SymbolicValue::Array) {
225+ // Casting the array buffer for Array literal initialization:
226+ // %b1 = struct_extract %array
227+ // %buffer = unchecked_ref_cast %b1 to __ContiguousArrayStorageBase
228+ // %element0 = ref_tail_addr %buffer
229+ return val;
230+ }
231+ return getUnknown (evaluator, value, UnknownReason::UnsupportedInstruction);
232+ }
233+
234+ if (auto *rta = dyn_cast<RefTailAddrInst>(value)) {
235+ auto val = getConstantValue (rta->getOperand ());
236+ if (val.getKind () == SymbolicValue::Array) {
237+ // Projecting the elements base address from an Array buffer:
238+ // %buffer = struct_extract %array
239+ // %element0 = ref_tail_addr %buffer
240+ return val.getAddressOfArrayElement (evaluator.getAllocator (), 0 );
241+ }
242+ return getUnknown (evaluator, value, UnknownReason::UnsupportedInstruction);
243+ }
244+
215245 // If this is an unchecked_enum_data from a fragile type, then we can return
216246 // the enum case value.
217247 if (auto *uedi = dyn_cast<UncheckedEnumDataInst>(value)) {
0 commit comments