@@ -314,6 +314,164 @@ TEST_F(IR_ValidatorTest, StructMember_AlignNotDivisibleByTypeAlignment) {
314
314
)" )) << res.Failure ();
315
315
}
316
316
317
+ TEST_F (IR_ValidatorTest, StructureMember_SizeTooSmall) {
318
+ auto * str_ty =
319
+ ty.Struct (mod.symbols .New (" S" ),
320
+ Vector{
321
+ ty.Get <type::StructMember>(mod.symbols .New (" a" ), ty.array <u32 , 3 >(), 0u , 0u ,
322
+ 4u , 4u , IOAttributes{}),
323
+ });
324
+ mod.root_block ->Append (b.Var (" my_struct" , private_, str_ty));
325
+
326
+ auto * fn = b.Function (" F" , ty.void_ ());
327
+ b.Append (fn->Block (), [&] { b.Return (fn); });
328
+
329
+ auto res = ir::Validate (mod);
330
+ ASSERT_NE (res, Success);
331
+ EXPECT_THAT (
332
+ res.Failure ().reason ,
333
+ testing::HasSubstr (
334
+ " struct member 0 with size=4 must be at least as large as the type with size 12" ))
335
+ << res.Failure ();
336
+ }
337
+
338
+ TEST_F (IR_ValidatorTest, StructMember_RuntimeArrayNotLast) {
339
+ auto * s1 = ty.Struct (mod.symbols .New (" S1" ), {{mod.symbols .New (" a" ), ty.u32 ()}});
340
+ auto * rta = ty.runtime_array (s1);
341
+
342
+ auto * str_ty = ty.Struct (mod.symbols .New (" OuterS" ), {
343
+ {mod.symbols .New (" a1" ), rta},
344
+ {mod.symbols .New (" j" ), ty.u32 ()},
345
+ });
346
+
347
+ auto * v = b.Var (ty.ptr (storage, str_ty, read_write));
348
+ v->SetBindingPoint (0 , 0 );
349
+ mod.root_block ->Append (v);
350
+
351
+ auto res = ir::Validate (mod);
352
+ ASSERT_NE (res, Success);
353
+ EXPECT_THAT (
354
+ res.Failure ().reason ,
355
+ testing::HasSubstr (
356
+ R"( :11:3 error: var: runtime-sized arrays can only be the last member of a struct
357
+ %1:ptr<storage, OuterS, read_write> = var undef @binding_point(0, 0)
358
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^)" ))
359
+ << res.Failure ();
360
+ }
361
+
362
+ TEST_F (IR_ValidatorTest, StructMember_RuntimeArrayIsLast) {
363
+ auto * s1 = ty.Struct (mod.symbols .New (" S1" ), {{mod.symbols .New (" a" ), ty.u32 ()}});
364
+ auto * rta = ty.runtime_array (s1);
365
+
366
+ auto * str_ty = ty.Struct (mod.symbols .New (" OuterS" ), {
367
+ {mod.symbols .New (" j" ), ty.u32 ()},
368
+ {mod.symbols .New (" a1" ), rta},
369
+ });
370
+
371
+ auto * v = b.Var (ty.ptr (storage, str_ty, read_write));
372
+ v->SetBindingPoint (0 , 0 );
373
+ mod.root_block ->Append (v);
374
+
375
+ auto res = ir::Validate (mod);
376
+ ASSERT_EQ (res, Success) << res.Failure ();
377
+ }
378
+
379
+ TEST_F (IR_ValidatorTest, StructMember_MultipleRuntimeArrays) {
380
+ auto * s1 = ty.Struct (mod.symbols .New (" S1" ), {{mod.symbols .New (" a" ), ty.u32 ()}});
381
+ auto * rta = ty.runtime_array (s1);
382
+
383
+ auto * str_ty = ty.Struct (mod.symbols .New (" OuterS" ), {
384
+ {mod.symbols .New (" a1" ), rta},
385
+ {mod.symbols .New (" a2" ), rta},
386
+ });
387
+
388
+ auto * v = b.Var (ty.ptr (storage, str_ty, read_write));
389
+ v->SetBindingPoint (0 , 0 );
390
+ mod.root_block ->Append (v);
391
+
392
+ auto res = ir::Validate (mod);
393
+ ASSERT_NE (res, Success);
394
+ EXPECT_THAT (
395
+ res.Failure ().reason ,
396
+ testing::HasSubstr (
397
+ R"( :11:3 error: var: runtime-sized arrays can only be the last member of a struct
398
+ %1:ptr<storage, OuterS, read_write> = var undef @binding_point(0, 0)
399
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^)" ))
400
+ << res.Failure ();
401
+ }
402
+
403
+ TEST_F (IR_ValidatorTest, StructMember_RowMajor_WithoutCapability) {
404
+ auto * mat_ty = ty.mat2x2 <f32 >();
405
+ auto * member = ty.Get <core::type::StructMember>(
406
+ mod.symbols .New (" m" ), mat_ty, 0u , 0u , mat_ty->Align (), mat_ty->Size (), IOAttributes{});
407
+ member->SetRowMajor ();
408
+ auto * str_ty =
409
+ ty.Get <core::type::Struct>(mod.symbols .New (" MyStruct" ), Vector{member}, mat_ty->Size ());
410
+
411
+ auto * v = b.Var (ty.ptr (private_, str_ty));
412
+ mod.root_block ->Append (v);
413
+
414
+ auto res = ir::Validate (mod);
415
+ ASSERT_NE (res, Success);
416
+ EXPECT_THAT (
417
+ res.Failure ().reason ,
418
+ testing::HasSubstr (R"( :6:3 error: var: Row major annotation not allowed on structures
419
+ %1:ptr<private, MyStruct, read_write> = var undef
420
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
421
+ )" )) << res.Failure ();
422
+ }
423
+
424
+ TEST_F (IR_ValidatorTest, StructMember_RowMajor_WithCapability) {
425
+ auto * mat_ty = ty.mat2x2 <f32 >();
426
+ auto * member = ty.Get <core::type::StructMember>(
427
+ mod.symbols .New (" m" ), mat_ty, 0u , 0u , mat_ty->Align (), mat_ty->Size (), IOAttributes{});
428
+ member->SetRowMajor ();
429
+ auto * str_ty =
430
+ ty.Get <core::type::Struct>(mod.symbols .New (" MyStruct" ), Vector{member}, mat_ty->Size ());
431
+
432
+ auto * v = b.Var (ty.ptr (private_, str_ty));
433
+ mod.root_block ->Append (v);
434
+
435
+ auto res = ir::Validate (mod, Capabilities{Capability::kAllowStructMatrixDecorations });
436
+ ASSERT_EQ (res, Success) << res.Failure ();
437
+ }
438
+
439
+ TEST_F (IR_ValidatorTest, StructMember_MatrixStride_WithoutCapability) {
440
+ auto * mat_ty = ty.mat2x2 <f32 >();
441
+ auto * member = ty.Get <core::type::StructMember>(
442
+ mod.symbols .New (" m" ), mat_ty, 0u , 0u , mat_ty->Align (), mat_ty->Size (), IOAttributes{});
443
+ member->SetMatrixStride (32 );
444
+ auto * str_ty =
445
+ ty.Get <core::type::Struct>(mod.symbols .New (" MyStruct" ), Vector{member}, mat_ty->Size ());
446
+
447
+ auto * v = b.Var (ty.ptr (private_, str_ty));
448
+ mod.root_block ->Append (v);
449
+
450
+ auto res = ir::Validate (mod);
451
+ ASSERT_NE (res, Success);
452
+ EXPECT_THAT (
453
+ res.Failure ().reason ,
454
+ testing::HasSubstr (R"( :6:3 error: var: Matrix stride annotation not allowed on structures
455
+ %1:ptr<private, MyStruct, read_write> = var undef
456
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
457
+ )" )) << res.Failure ();
458
+ }
459
+
460
+ TEST_F (IR_ValidatorTest, StructMember_MatrixStride_WithCapability) {
461
+ auto * mat_ty = ty.mat2x2 <f32 >();
462
+ auto * member = ty.Get <core::type::StructMember>(
463
+ mod.symbols .New (" m" ), mat_ty, 0u , 0u , mat_ty->Align (), mat_ty->Size (), IOAttributes{});
464
+ member->SetMatrixStride (32 );
465
+ auto * str_ty =
466
+ ty.Get <core::type::Struct>(mod.symbols .New (" MyStruct" ), Vector{member}, mat_ty->Size ());
467
+
468
+ auto * v = b.Var (ty.ptr (private_, str_ty));
469
+ mod.root_block ->Append (v);
470
+
471
+ auto res = ir::Validate (mod, Capabilities{Capability::kAllowStructMatrixDecorations });
472
+ ASSERT_EQ (res, Success) << res.Failure ();
473
+ }
474
+
317
475
TEST_F (IR_ValidatorTest, FunctionParam_InvalidAddressSpaceForHandleType) {
318
476
auto * type = ty.ptr (AddressSpace::kFunction , ty.sampler ());
319
477
auto * fn = b.Function (" my_func" , ty.void_ ());
@@ -1342,27 +1500,6 @@ TEST_P(AddressSpace_AccessMode, Test) {
1342
1500
}
1343
1501
}
1344
1502
1345
- TEST_F (IR_ValidatorTest, StructureMemberSizeTooSmall) {
1346
- auto * str_ty =
1347
- ty.Struct (mod.symbols .New (" S" ),
1348
- Vector{
1349
- ty.Get <type::StructMember>(mod.symbols .New (" a" ), ty.array <u32 , 3 >(), 0u , 0u ,
1350
- 4u , 4u , IOAttributes{}),
1351
- });
1352
- mod.root_block ->Append (b.Var (" my_struct" , private_, str_ty));
1353
-
1354
- auto * fn = b.Function (" F" , ty.void_ ());
1355
- b.Append (fn->Block (), [&] { b.Return (fn); });
1356
-
1357
- auto res = ir::Validate (mod);
1358
- ASSERT_NE (res, Success);
1359
- EXPECT_THAT (
1360
- res.Failure ().reason ,
1361
- testing::HasSubstr (
1362
- " struct member 0 with size=4 must be at least as large as the type with size 12" ))
1363
- << res.Failure ();
1364
- }
1365
-
1366
1503
INSTANTIATE_TEST_SUITE_P (IR_ValidatorTest,
1367
1504
AddressSpace_AccessMode,
1368
1505
testing::Combine (testing::Values(AddressSpace::kFunction ,
0 commit comments