Skip to content

Commit 61076ac

Browse files
committed
#1016 allow meta computed alignment to be smaller than actual alignment
1 parent e2041a4 commit 61076ac

File tree

5 files changed

+77
-10
lines changed

5 files changed

+77
-10
lines changed

flecs.c

+9-4
Original file line numberDiff line numberDiff line change
@@ -25274,10 +25274,15 @@ int flecs_init_type(
2527425274
return -1;
2527525275
}
2527625276
if (comp->size == size && comp->alignment != alignment) {
25277-
ecs_err("computed size for '%s' matches with actual type but "
25278-
"alignment is different (%d vs. %d)", ecs_get_name(world, type),
25279-
alignment, comp->alignment);
25280-
return -1;
25277+
if (comp->alignment < alignment) {
25278+
ecs_err("computed size for '%s' matches with actual type but "
25279+
"alignment is different (%d vs. %d)", ecs_get_name(world, type),
25280+
alignment, comp->alignment);
25281+
} else {
25282+
/* If this is an existing type, the alignment can be larger but
25283+
* not smaller than the computed alignment. */
25284+
alignment = comp->alignment;
25285+
}
2528125286
}
2528225287

2528325288
meta_type->partial = comp->size != size;

src/addons/meta/meta.c

+9-4
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,15 @@ int flecs_init_type(
295295
return -1;
296296
}
297297
if (comp->size == size && comp->alignment != alignment) {
298-
ecs_err("computed size for '%s' matches with actual type but "
299-
"alignment is different (%d vs. %d)", ecs_get_name(world, type),
300-
alignment, comp->alignment);
301-
return -1;
298+
if (comp->alignment < alignment) {
299+
ecs_err("computed size for '%s' matches with actual type but "
300+
"alignment is different (%d vs. %d)", ecs_get_name(world, type),
301+
alignment, comp->alignment);
302+
} else {
303+
/* If this is an existing type, the alignment can be larger but
304+
* not smaller than the computed alignment. */
305+
alignment = comp->alignment;
306+
}
302307
}
303308

304309
meta_type->partial = comp->size != size;

test/meta/project.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@
120120
"invalid_warning_range",
121121
"overlapping_error_warning_range",
122122
"overlapping_value_error_range",
123-
"overlapping_value_warning_range"
123+
"overlapping_value_warning_range",
124+
"struct_w_16_alignment"
124125
]
125126
}, {
126127
"id": "NestedStructTypes",

test/meta/src/StructTypes.c

+51
Original file line numberDiff line numberDiff line change
@@ -771,3 +771,54 @@ void StructTypes_overlapping_value_warning_range() {
771771

772772
ecs_fini(world);
773773
}
774+
775+
void StructTypes_struct_w_16_alignment() {
776+
#ifndef _MSC_VER
777+
typedef __attribute((aligned(16)))
778+
#else
779+
typedef __declspec(align(16))
780+
#endif
781+
struct T {
782+
float x;
783+
float y;
784+
float z;
785+
float w;
786+
} T;
787+
788+
ecs_world_t *world = ecs_init();
789+
790+
ECS_COMPONENT(world, T);
791+
792+
ecs_entity_t t = ecs_struct(world, {
793+
.entity = ecs_id(T),
794+
.members = {
795+
{"x", ecs_id(ecs_f32_t)},
796+
{"y", ecs_id(ecs_f32_t)},
797+
{"z", ecs_id(ecs_f32_t)},
798+
{"w", ecs_id(ecs_f32_t)}
799+
}
800+
});
801+
802+
test_assert(t != 0);
803+
test_str(ecs_get_name(world, t), "T");
804+
805+
meta_test_struct(world, t, T);
806+
meta_test_member(world, t, T, x, ecs_id(ecs_f32_t), 1);
807+
meta_test_member(world, t, T, y, ecs_id(ecs_f32_t), 1);
808+
meta_test_member(world, t, T, z, ecs_id(ecs_f32_t), 1);
809+
meta_test_member(world, t, T, w, ecs_id(ecs_f32_t), 1);
810+
811+
const EcsComponent *cptr = ecs_get(world, t, EcsComponent);
812+
test_assert(cptr != NULL);
813+
test_int(cptr->size, sizeof(T));
814+
test_int(cptr->alignment, 16);
815+
816+
const EcsMetaType *mptr = ecs_get(world, t, EcsMetaType);
817+
test_assert(mptr != NULL);
818+
test_bool(mptr->partial, false);
819+
test_bool(mptr->existing, true);
820+
test_int(mptr->size, sizeof(T));
821+
test_int(mptr->alignment, 16);
822+
823+
ecs_fini(world);
824+
}

test/meta/src/main.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ void StructTypes_invalid_warning_range(void);
110110
void StructTypes_overlapping_error_warning_range(void);
111111
void StructTypes_overlapping_value_error_range(void);
112112
void StructTypes_overlapping_value_warning_range(void);
113+
void StructTypes_struct_w_16_alignment(void);
113114

114115
// Testsuite 'NestedStructTypes'
115116
void NestedStructTypes_1_bool(void);
@@ -1345,6 +1346,10 @@ bake_test_case StructTypes_testcases[] = {
13451346
{
13461347
"overlapping_value_warning_range",
13471348
StructTypes_overlapping_value_warning_range
1349+
},
1350+
{
1351+
"struct_w_16_alignment",
1352+
StructTypes_struct_w_16_alignment
13481353
}
13491354
};
13501355

@@ -4679,7 +4684,7 @@ static bake_test_suite suites[] = {
46794684
"StructTypes",
46804685
NULL,
46814686
NULL,
4682-
27,
4687+
28,
46834688
StructTypes_testcases
46844689
},
46854690
{

0 commit comments

Comments
 (0)