1// RUN: tco %s | FileCheck %s 2// RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s 3 4// UNSUPPORTED: system-windows 5 6// CHECK-LABEL: define ptr @alloca_scalar_nonchar() 7// CHECK: alloca i32, i64 1 8func.func @alloca_scalar_nonchar() -> !fir.ref<i32> { 9 %1 = fir.alloca i32 10 return %1 : !fir.ref<i32> 11} 12 13// CHECK-LABEL: define ptr @alloca_scalars_nonchar() 14// CHECK: alloca i32, i64 100 15func.func @alloca_scalars_nonchar() -> !fir.ref<i32> { 16 %0 = arith.constant 100 : index 17 %1 = fir.alloca i32, %0 18 return %1 : !fir.ref<i32> 19} 20 21// CHECK-LABEL: define ptr @allocmem_scalar_nonchar( 22// CHECK: call ptr @malloc(i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64)) 23func.func @allocmem_scalar_nonchar() -> !fir.heap<i32> { 24 %1 = fir.allocmem i32 25 return %1 : !fir.heap<i32> 26} 27 28// CHECK-LABEL: define ptr @allocmem_scalars_nonchar( 29// CHECK: call ptr @malloc(i64 mul (i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i64 100)) 30func.func @allocmem_scalars_nonchar() -> !fir.heap<i32> { 31 %0 = arith.constant 100 : index 32 %1 = fir.allocmem i32, %0 33 return %1 : !fir.heap<i32> 34} 35 36// CHECK-LABEL: define ptr @alloca_scalar_char( 37// CHECK: alloca [10 x i8], i64 1 38func.func @alloca_scalar_char() -> !fir.ref<!fir.char<1,10>> { 39 %1 = fir.alloca !fir.char<1,10> 40 return %1 : !fir.ref<!fir.char<1,10>> 41} 42 43// CHECK-LABEL: define ptr @alloca_scalar_char_kind( 44// CHECK: alloca [10 x i16], i64 1 45func.func @alloca_scalar_char_kind() -> !fir.ref<!fir.char<2,10>> { 46 %1 = fir.alloca !fir.char<2,10> 47 return %1 : !fir.ref<!fir.char<2,10>> 48} 49 50// CHECK-LABEL: define ptr @allocmem_scalar_char( 51// CHECK: call ptr @malloc(i64 ptrtoint (ptr getelementptr ([10 x i8], ptr null, i32 1) to i64)) 52func.func @allocmem_scalar_char() -> !fir.heap<!fir.char<1,10>> { 53 %1 = fir.allocmem !fir.char<1,10> 54 return %1 : !fir.heap<!fir.char<1,10>> 55} 56 57// CHECK-LABEL: define ptr @allocmem_scalar_char_kind( 58// CHECK: call ptr @malloc(i64 ptrtoint (ptr getelementptr ([10 x i16], ptr null, i32 1) to i64)) 59func.func @allocmem_scalar_char_kind() -> !fir.heap<!fir.char<2,10>> { 60 %1 = fir.allocmem !fir.char<2,10> 61 return %1 : !fir.heap<!fir.char<2,10>> 62} 63 64// CHECK-LABEL: define ptr @alloca_scalar_dynchar( 65// CHECK-SAME: i32 %[[len:.*]]) 66// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64 67// CHECK: alloca i8, i64 %[[mul1]] 68func.func @alloca_scalar_dynchar(%l : i32) -> !fir.ref<!fir.char<1,?>> { 69 %1 = fir.alloca !fir.char<1,?>(%l : i32) 70 return %1 : !fir.ref<!fir.char<1,?>> 71} 72 73// CHECK-LABEL: define ptr @alloca_scalar_dynchar_kind( 74// CHECK-SAME: i32 %[[len:.*]]) 75// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64 76// CHECK: alloca i16, i64 %[[mul1]] 77func.func @alloca_scalar_dynchar_kind(%l : i32) -> !fir.ref<!fir.char<2,?>> { 78 %1 = fir.alloca !fir.char<2,?>(%l : i32) 79 return %1 : !fir.ref<!fir.char<2,?>> 80} 81 82// CHECK-LABEL: define ptr @allocmem_scalar_dynchar( 83// CHECK-SAME: i32 %[[len:.*]]) 84// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64 85// CHECK: %[[mul2:.*]] = mul i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), %[[mul1]] 86// CHECK: call ptr @malloc(i64 %[[mul2]]) 87func.func @allocmem_scalar_dynchar(%l : i32) -> !fir.heap<!fir.char<1,?>> { 88 %1 = fir.allocmem !fir.char<1,?>(%l : i32) 89 return %1 : !fir.heap<!fir.char<1,?>> 90} 91 92// CHECK-LABEL: define ptr @allocmem_scalar_dynchar_kind( 93// CHECK-SAME: i32 %[[len:.*]]) 94// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64 95// CHECK: %[[mul2:.*]] = mul i64 ptrtoint (ptr getelementptr (i16, ptr null, i32 1) to i64), %[[mul1]] 96// CHECK: call ptr @malloc(i64 %[[mul2]]) 97func.func @allocmem_scalar_dynchar_kind(%l : i32) -> !fir.heap<!fir.char<2,?>>{ 98 %1 = fir.allocmem !fir.char<2,?>(%l : i32) 99 return %1 : !fir.heap<!fir.char<2,?>> 100} 101 102// CHECK-LABEL: define ptr @alloca_ptr_to_dynarray_nonchar( 103// CHECK: %1 = alloca ptr, i64 1 104func.func @alloca_ptr_to_dynarray_nonchar() -> !fir.ref<!fir.ptr<!fir.array<?xi32>>> { 105 %1 = fir.alloca !fir.ptr<!fir.array<?xi32>> 106 return %1 : !fir.ref<!fir.ptr<!fir.array<?xi32>>> 107} 108 109// CHECK-LABEL: define ptr @alloca_array_of_nonchar( 110// CHECK: alloca [3 x [3 x i32]], i64 1 111func.func @alloca_array_of_nonchar() -> !fir.ref<!fir.array<3x3xi32>> { 112 %1 = fir.alloca !fir.array<3x3xi32> 113 return %1 : !fir.ref<!fir.array<3x3xi32>> 114} 115 116// CHECK-LABEL: define ptr @alloca_array_of_char( 117// CHECK: alloca [3 x [3 x [10 x i8]]], i64 1 118func.func @alloca_array_of_char() -> !fir.ref<!fir.array<3x3x!fir.char<1,10>>> { 119 %1 = fir.alloca !fir.array<3x3x!fir.char<1,10>> 120 return %1 : !fir.ref<!fir.array<3x3x!fir.char<1,10>>> 121} 122 123// CHECK-LABEL: define ptr @alloca_array_of_dynchar( 124// CHECK-SAME: i32 %[[len:.*]]) 125// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64 126// CHECK: %[[mul2:.*]] = mul i64 %[[mul1]], 9 127// CHECK: alloca i8, i64 %[[mul2]] 128func.func @alloca_array_of_dynchar(%l: i32) -> !fir.ref<!fir.array<3x3x!fir.char<1,?>>> { 129 %1 = fir.alloca !fir.array<3x3x!fir.char<1,?>>(%l : i32) 130 return %1 : !fir.ref<!fir.array<3x3x!fir.char<1,?>>> 131} 132 133// CHECK-LABEL: define ptr @allocmem_array_of_nonchar( 134// CHECK: call ptr @malloc(i64 ptrtoint (ptr getelementptr ([3 x [3 x i32]], ptr null, i32 1) to i64)) 135func.func @allocmem_array_of_nonchar() -> !fir.heap<!fir.array<3x3xi32>> { 136 %1 = fir.allocmem !fir.array<3x3xi32> 137 return %1 : !fir.heap<!fir.array<3x3xi32>> 138} 139 140// CHECK-LABEL: define ptr @allocmem_array_of_char( 141// CHECK: call ptr @malloc(i64 ptrtoint (ptr getelementptr ([3 x [3 x [10 x i8]]], ptr null, i32 1) to i64)) 142func.func @allocmem_array_of_char() -> !fir.heap<!fir.array<3x3x!fir.char<1,10>>> { 143 %1 = fir.allocmem !fir.array<3x3x!fir.char<1,10>> 144 return %1 : !fir.heap<!fir.array<3x3x!fir.char<1,10>>> 145} 146 147// CHECK-LABEL: define ptr @allocmem_array_of_dynchar( 148// CHECK-SAME: i32 %[[len:.*]]) 149// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64 150// CHECK: %[[mul2:.*]] = mul i64 mul (i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), i64 9), %[[mul1]] 151// CHECK: call ptr @malloc(i64 %[[mul2]]) 152func.func @allocmem_array_of_dynchar(%l: i32) -> !fir.heap<!fir.array<3x3x!fir.char<1,?>>> { 153 %1 = fir.allocmem !fir.array<3x3x!fir.char<1,?>>(%l : i32) 154 return %1 : !fir.heap<!fir.array<3x3x!fir.char<1,?>>> 155} 156 157// CHECK-LABEL: define ptr @alloca_dynarray_of_nonchar( 158// CHECK-SAME: i64 %[[extent:.*]]) 159// CHECK: %[[prod1:.*]] = mul i64 %[[extent]], 1 160// CHECK: alloca [3 x i32], i64 %[[prod1]] 161func.func @alloca_dynarray_of_nonchar(%e: index) -> !fir.ref<!fir.array<3x?xi32>> { 162 %1 = fir.alloca !fir.array<3x?xi32>, %e 163 return %1 : !fir.ref<!fir.array<3x?xi32>> 164} 165 166// CHECK-LABEL: define ptr @alloca_dynarray_of_nonchar2( 167// CHECK-SAME: i64 %[[extent:.*]]) 168// CHECK: %[[prod1:.*]] = mul i64 %[[extent]], 1 169// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]] 170// CHECK: alloca i32, i64 %[[prod2]] 171func.func @alloca_dynarray_of_nonchar2(%e: index) -> !fir.ref<!fir.array<?x?xi32>> { 172 %1 = fir.alloca !fir.array<?x?xi32>, %e, %e 173 return %1 : !fir.ref<!fir.array<?x?xi32>> 174} 175 176// CHECK-LABEL: define ptr @allocmem_dynarray_of_nonchar( 177// CHECK-SAME: i64 %[[extent:.*]]) 178// CHECK: %[[prod1:.*]] = mul i64 ptrtoint (ptr getelementptr ([3 x i32], ptr null, i32 1) to i64), %[[extent]] 179// CHECK: call ptr @malloc(i64 %[[prod1]]) 180func.func @allocmem_dynarray_of_nonchar(%e: index) -> !fir.heap<!fir.array<3x?xi32>> { 181 %1 = fir.allocmem !fir.array<3x?xi32>, %e 182 return %1 : !fir.heap<!fir.array<3x?xi32>> 183} 184 185// CHECK-LABEL: define ptr @allocmem_dynarray_of_nonchar2( 186// CHECK-SAME: i64 %[[extent:.*]]) 187// CHECK: %[[prod1:.*]] = mul i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), %[[extent]] 188// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]] 189// CHECK: call ptr @malloc(i64 %[[prod2]]) 190func.func @allocmem_dynarray_of_nonchar2(%e: index) -> !fir.heap<!fir.array<?x?xi32>> { 191 %1 = fir.allocmem !fir.array<?x?xi32>, %e, %e 192 return %1 : !fir.heap<!fir.array<?x?xi32>> 193} 194 195// CHECK-LABEL: define ptr @alloca_dynarray_of_char( 196// CHECK-SAME: i64 %[[extent:.*]]) 197// CHECK: %[[prod1:.*]] = mul i64 %[[extent]], 1 198// CHECK: alloca [3 x [10 x i16]], i64 %[[prod1]] 199func.func @alloca_dynarray_of_char(%e : index) -> !fir.ref<!fir.array<3x?x!fir.char<2,10>>> { 200 %1 = fir.alloca !fir.array<3x?x!fir.char<2,10>>, %e 201 return %1 : !fir.ref<!fir.array<3x?x!fir.char<2,10>>> 202} 203 204// CHECK-LABEL: define ptr @alloca_dynarray_of_char2( 205// CHECK-SAME: i64 %[[extent:.*]]) 206// CHECK: %[[prod1:.*]] = mul i64 %[[extent]], 1 207// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]] 208// CHECK: alloca [10 x i16], i64 %[[prod2]] 209func.func @alloca_dynarray_of_char2(%e : index) -> !fir.ref<!fir.array<?x?x!fir.char<2,10>>> { 210 %1 = fir.alloca !fir.array<?x?x!fir.char<2,10>>, %e, %e 211 return %1 : !fir.ref<!fir.array<?x?x!fir.char<2,10>>> 212} 213 214// CHECK-LABEL: define ptr @allocmem_dynarray_of_char( 215// CHECK-SAME: i64 %[[extent:.*]]) 216// CHECK: %[[prod1:.*]] = mul i64 ptrtoint (ptr getelementptr ([3 x [10 x i16]], ptr null, i32 1) to i64), %[[extent]] 217// CHECK: call ptr @malloc(i64 %[[prod1]]) 218func.func @allocmem_dynarray_of_char(%e : index) -> !fir.heap<!fir.array<3x?x!fir.char<2,10>>> { 219 %1 = fir.allocmem !fir.array<3x?x!fir.char<2,10>>, %e 220 return %1 : !fir.heap<!fir.array<3x?x!fir.char<2,10>>> 221} 222 223// CHECK-LABEL: define ptr @allocmem_dynarray_of_char2( 224// CHECK-SAME: i64 %[[extent:.*]]) 225// CHECK: %[[prod1:.*]] = mul i64 ptrtoint (ptr getelementptr ([10 x i16], ptr null, i32 1) to i64), %[[extent]] 226// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]] 227// CHECK: call ptr @malloc(i64 %[[prod2]]) 228func.func @allocmem_dynarray_of_char2(%e : index) -> !fir.heap<!fir.array<?x?x!fir.char<2,10>>> { 229 %1 = fir.allocmem !fir.array<?x?x!fir.char<2,10>>, %e, %e 230 return %1 : !fir.heap<!fir.array<?x?x!fir.char<2,10>>> 231} 232 233// CHECK-LABEL: define ptr @alloca_dynarray_of_dynchar( 234// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]]) 235// CHECK: %[[prod1:.*]] = sext i32 %[[len]] to i64 236// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], 3 237// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]] 238// CHECK: alloca i16, i64 %[[prod3]] 239func.func @alloca_dynarray_of_dynchar(%l: i32, %e : index) -> !fir.ref<!fir.array<3x?x!fir.char<2,?>>> { 240 %1 = fir.alloca !fir.array<3x?x!fir.char<2,?>>(%l : i32), %e 241 return %1 : !fir.ref<!fir.array<3x?x!fir.char<2,?>>> 242} 243 244// CHECK-LABEL: define ptr @alloca_dynarray_of_dynchar2( 245// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]]) 246// CHECK: %[[prod1:.*]] = sext i32 %[[len]] to i64 247// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]] 248// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]] 249// CHECK: alloca i16, i64 %[[prod3]] 250func.func @alloca_dynarray_of_dynchar2(%l: i32, %e : index) -> !fir.ref<!fir.array<?x?x!fir.char<2,?>>> { 251 %1 = fir.alloca !fir.array<?x?x!fir.char<2,?>>(%l : i32), %e, %e 252 return %1 : !fir.ref<!fir.array<?x?x!fir.char<2,?>>> 253} 254 255// CHECK-LABEL: define ptr @allocmem_dynarray_of_dynchar( 256// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]]) 257// CHECK: %[[prod1:.*]] = sext i32 %[[len]] to i64 258// CHECK: %[[prod2:.*]] = mul i64 mul (i64 ptrtoint (ptr getelementptr (i16, ptr null, i32 1) to i64), i64 3), %[[prod1]] 259// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]] 260// CHECK: call ptr @malloc(i64 %[[prod3]]) 261func.func @allocmem_dynarray_of_dynchar(%l: i32, %e : index) -> !fir.heap<!fir.array<3x?x!fir.char<2,?>>> { 262 %1 = fir.allocmem !fir.array<3x?x!fir.char<2,?>>(%l : i32), %e 263 return %1 : !fir.heap<!fir.array<3x?x!fir.char<2,?>>> 264} 265 266// CHECK-LABEL: define ptr @allocmem_dynarray_of_dynchar2( 267// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]]) 268// CHECK: %[[a:.*]] = sext i32 %[[len]] to i64 269// CHECK: %[[prod1:.*]] = mul i64 ptrtoint (ptr getelementptr (i16, ptr null, i32 1) to i64), %[[a]] 270// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]] 271// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]] 272// CHECK: call ptr @malloc(i64 %[[prod3]]) 273func.func @allocmem_dynarray_of_dynchar2(%l: i32, %e : index) -> !fir.heap<!fir.array<?x?x!fir.char<2,?>>> { 274 %1 = fir.allocmem !fir.array<?x?x!fir.char<2,?>>(%l : i32), %e, %e 275 return %1 : !fir.heap<!fir.array<?x?x!fir.char<2,?>>> 276} 277 278// CHECK-LABEL: define ptr @alloca_array_with_holes_nonchar( 279// CHECK-SAME: i64 %[[a:.*]], i64 %[[b:.*]]) 280// CHECK: %[[prod1:.*]] = mul i64 15, %[[a]] 281// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[b]] 282// CHECK: alloca [4 x i32], i64 %[[prod2]] 283func.func @alloca_array_with_holes_nonchar(%0 : index, %1 : index) -> !fir.ref<!fir.array<4x?x3x?x5xi32>> { 284 %a = fir.alloca !fir.array<4x?x3x?x5xi32>, %0, %1 285 return %a : !fir.ref<!fir.array<4x?x3x?x5xi32>> 286} 287 288// CHECK-LABEL: define ptr @alloca_array_with_holes_char( 289// CHECK-SAME: i64 %[[e:.*]]) 290// CHECK: %[[mul:.*]] = mul i64 4, %[[e]] 291// CHECK: alloca [3 x [10 x i16]], i64 %[[mul]] 292func.func @alloca_array_with_holes_char(%e: index) -> !fir.ref<!fir.array<3x?x4x!fir.char<2,10>>> { 293 %1 = fir.alloca !fir.array<3x?x4x!fir.char<2,10>>, %e 294 return %1 : !fir.ref<!fir.array<3x?x4x!fir.char<2,10>>> 295} 296 297// CHECK-LABEL: define ptr @alloca_array_with_holes_dynchar( 298// CHECK-SAME: i64 %[[len:.*]], i64 %[[extent:.*]]) 299// CHECK: %[[a:.*]] = mul i64 %[[len]], 12 300// CHECK: %[[b:.*]] = mul i64 %[[a]], %[[extent]] 301// CHECK: alloca i16, i64 %[[b]] 302func.func @alloca_array_with_holes_dynchar(%arg0: index, %arg1: index) -> !fir.ref<!fir.array<3x?x4x!fir.char<2,?>>> { 303 %1 = fir.alloca !fir.array<3x?x4x!fir.char<2,?>>(%arg0 : index), %arg1 304 return %1 : !fir.ref<!fir.array<3x?x4x!fir.char<2,?>>> 305} 306 307// CHECK-LABEL: define ptr @allocmem_array_with_holes_nonchar( 308// CHECK-SAME: i64 %[[e1:.*]], i64 %[[e2:.*]]) 309// CHECK: %[[a:.*]] = mul i64 mul (i64 ptrtoint{{.*}} 15), %[[e1]] 310// CHECK: %[[b:.*]] = mul i64 %3, %[[e2]] 311// CHECK: call ptr @malloc(i64 %[[b]]) 312func.func @allocmem_array_with_holes_nonchar(%0 : index, %1 : index) -> !fir.heap<!fir.array<4x?x3x?x5xi32>> { 313 %a = fir.allocmem !fir.array<4x?x3x?x5xi32>, %0, %1 314 return %a : !fir.heap<!fir.array<4x?x3x?x5xi32>> 315} 316 317// CHECK-LABEL: define ptr @allocmem_array_with_holes_char( 318// CHECK-SAME: i64 %[[e:.*]]) 319// CHECK: %[[mul:.*]] = mul i64 mul (i64 ptrtoint (ptr getelementptr ([3 x [10 x i16]], ptr null, i32 1) to i64), i64 4), %[[e]] 320// CHECK: call ptr @malloc(i64 %[[mul]]) 321func.func @allocmem_array_with_holes_char(%e: index) -> !fir.heap<!fir.array<3x?x4x!fir.char<2,10>>> { 322 %1 = fir.allocmem !fir.array<3x?x4x!fir.char<2,10>>, %e 323 return %1 : !fir.heap<!fir.array<3x?x4x!fir.char<2,10>>> 324} 325 326// CHECK-LABEL: define ptr @allocmem_array_with_holes_dynchar( 327// CHECK-SAME: i64 %[[len:.*]], i64 %[[extent:.*]]) 328// CHECK: %[[a:.*]] = mul i64 mul (i64 ptrtoint (ptr getelementptr (i16, ptr null, i32 1) to i64), i64 12), %[[len]] 329// CHECK: %[[b:.*]] = mul i64 %[[a]], %[[extent]] 330// CHECK: call ptr @malloc(i64 %[[b]]) 331func.func @allocmem_array_with_holes_dynchar(%arg0: index, %arg1: index) -> !fir.heap<!fir.array<3x?x4x!fir.char<2,?>>> { 332 %1 = fir.allocmem !fir.array<3x?x4x!fir.char<2,?>>(%arg0 : index), %arg1 333 return %1 : !fir.heap<!fir.array<3x?x4x!fir.char<2,?>>> 334} 335 336// CHECK-LABEL: define void @alloca_unlimited_polymorphic_box 337// CHECK: %[[VAL_1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, i64 1 338// CHECK: %[[VAL_0:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, i64 1 339// CHECK: %[[VAL_3:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, i64 1 340// CHECK: %[[VAL_2:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, i64 1 341 342func.func @alloca_unlimited_polymorphic_box() { 343 %0 = fir.alloca !fir.class<none> 344 %1 = fir.alloca !fir.class<!fir.array<?xnone>> 345 %2 = fir.alloca !fir.box<none> 346 %3 = fir.alloca !fir.box<!fir.array<?xnone>> 347 return 348} 349// Note: allocmem of fir.box are not possible (fir::HeapType::verify does not 350// accept box types), so there is no equivalent of 351// alloca_unlimited_polymorphic_box for allocmem. 352