From 61076ac6de10357195e32481613c3b80dd900550 Mon Sep 17 00:00:00 2001 From: Sander Mertens Date: Thu, 3 Aug 2023 16:49:33 -0700 Subject: [PATCH] #1016 allow meta computed alignment to be smaller than actual alignment --- flecs.c | 13 +++++++--- src/addons/meta/meta.c | 13 +++++++--- test/meta/project.json | 3 ++- test/meta/src/StructTypes.c | 51 +++++++++++++++++++++++++++++++++++++ test/meta/src/main.c | 7 ++++- 5 files changed, 77 insertions(+), 10 deletions(-) diff --git a/flecs.c b/flecs.c index ffc4a4b5a3..cd1f6e96c1 100644 --- a/flecs.c +++ b/flecs.c @@ -25274,10 +25274,15 @@ int flecs_init_type( return -1; } if (comp->size == size && comp->alignment != alignment) { - ecs_err("computed size for '%s' matches with actual type but " - "alignment is different (%d vs. %d)", ecs_get_name(world, type), - alignment, comp->alignment); - return -1; + if (comp->alignment < alignment) { + ecs_err("computed size for '%s' matches with actual type but " + "alignment is different (%d vs. %d)", ecs_get_name(world, type), + alignment, comp->alignment); + } else { + /* If this is an existing type, the alignment can be larger but + * not smaller than the computed alignment. */ + alignment = comp->alignment; + } } meta_type->partial = comp->size != size; diff --git a/src/addons/meta/meta.c b/src/addons/meta/meta.c index b6e4cc0a88..580c502768 100644 --- a/src/addons/meta/meta.c +++ b/src/addons/meta/meta.c @@ -295,10 +295,15 @@ int flecs_init_type( return -1; } if (comp->size == size && comp->alignment != alignment) { - ecs_err("computed size for '%s' matches with actual type but " - "alignment is different (%d vs. %d)", ecs_get_name(world, type), - alignment, comp->alignment); - return -1; + if (comp->alignment < alignment) { + ecs_err("computed size for '%s' matches with actual type but " + "alignment is different (%d vs. %d)", ecs_get_name(world, type), + alignment, comp->alignment); + } else { + /* If this is an existing type, the alignment can be larger but + * not smaller than the computed alignment. */ + alignment = comp->alignment; + } } meta_type->partial = comp->size != size; diff --git a/test/meta/project.json b/test/meta/project.json index b392ede1f1..0340a1a173 100644 --- a/test/meta/project.json +++ b/test/meta/project.json @@ -120,7 +120,8 @@ "invalid_warning_range", "overlapping_error_warning_range", "overlapping_value_error_range", - "overlapping_value_warning_range" + "overlapping_value_warning_range", + "struct_w_16_alignment" ] }, { "id": "NestedStructTypes", diff --git a/test/meta/src/StructTypes.c b/test/meta/src/StructTypes.c index d735dae0e3..ef2353cb62 100644 --- a/test/meta/src/StructTypes.c +++ b/test/meta/src/StructTypes.c @@ -771,3 +771,54 @@ void StructTypes_overlapping_value_warning_range() { ecs_fini(world); } + +void StructTypes_struct_w_16_alignment() { +#ifndef _MSC_VER + typedef __attribute((aligned(16))) +#else + typedef __declspec(align(16)) +#endif + struct T { + float x; + float y; + float z; + float w; + } T; + + ecs_world_t *world = ecs_init(); + + ECS_COMPONENT(world, T); + + ecs_entity_t t = ecs_struct(world, { + .entity = ecs_id(T), + .members = { + {"x", ecs_id(ecs_f32_t)}, + {"y", ecs_id(ecs_f32_t)}, + {"z", ecs_id(ecs_f32_t)}, + {"w", ecs_id(ecs_f32_t)} + } + }); + + test_assert(t != 0); + test_str(ecs_get_name(world, t), "T"); + + meta_test_struct(world, t, T); + meta_test_member(world, t, T, x, ecs_id(ecs_f32_t), 1); + meta_test_member(world, t, T, y, ecs_id(ecs_f32_t), 1); + meta_test_member(world, t, T, z, ecs_id(ecs_f32_t), 1); + meta_test_member(world, t, T, w, ecs_id(ecs_f32_t), 1); + + const EcsComponent *cptr = ecs_get(world, t, EcsComponent); + test_assert(cptr != NULL); + test_int(cptr->size, sizeof(T)); + test_int(cptr->alignment, 16); + + const EcsMetaType *mptr = ecs_get(world, t, EcsMetaType); + test_assert(mptr != NULL); + test_bool(mptr->partial, false); + test_bool(mptr->existing, true); + test_int(mptr->size, sizeof(T)); + test_int(mptr->alignment, 16); + + ecs_fini(world); +} diff --git a/test/meta/src/main.c b/test/meta/src/main.c index 43700d81e8..e4ac1962a8 100644 --- a/test/meta/src/main.c +++ b/test/meta/src/main.c @@ -110,6 +110,7 @@ void StructTypes_invalid_warning_range(void); void StructTypes_overlapping_error_warning_range(void); void StructTypes_overlapping_value_error_range(void); void StructTypes_overlapping_value_warning_range(void); +void StructTypes_struct_w_16_alignment(void); // Testsuite 'NestedStructTypes' void NestedStructTypes_1_bool(void); @@ -1345,6 +1346,10 @@ bake_test_case StructTypes_testcases[] = { { "overlapping_value_warning_range", StructTypes_overlapping_value_warning_range + }, + { + "struct_w_16_alignment", + StructTypes_struct_w_16_alignment } }; @@ -4679,7 +4684,7 @@ static bake_test_suite suites[] = { "StructTypes", NULL, NULL, - 27, + 28, StructTypes_testcases }, {