diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 8a87a08e4..594ae3dd2 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -1662,6 +1662,7 @@ struct CompilationUnit_ HTable local_symbols; int lambda_count; Decl **local_method_extensions; + TypeInfo **check_type_variable_array; struct { void *debug_file; diff --git a/src/compiler/sema_passes.c b/src/compiler/sema_passes.c index b29b61e9b..728184c23 100644 --- a/src/compiler/sema_passes.c +++ b/src/compiler/sema_passes.c @@ -592,6 +592,9 @@ void sema_analysis_pass_decls(Module *module) { sema_analyse_decl(&context, unit->generic_defines[i]); } + FOREACH_BEGIN(TypeInfo *info, unit->check_type_variable_array) + sema_check_type_variable_array(&context, info); + FOREACH_END(); sema_context_destroy(&context); } DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 8da8b273d..067d58942 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -101,8 +101,11 @@ static inline bool sema_resolve_array_type(SemaContext *context, TypeInfo *type, if (!sema_resolve_type(context, type->array.base, resolve_type_kind)) return type_info_poison(type); Type *distinct_base = type_flatten(type->array.base->type); + + // We don't want to allow arrays with flexible members if (distinct_base->type_kind == TYPE_STRUCT) { + // If the struct is resolved, we can check immediately if (distinct_base->decl->resolve_status == RESOLVE_DONE) { if (distinct_base->decl->has_variable_array) @@ -111,6 +114,11 @@ static inline bool sema_resolve_array_type(SemaContext *context, TypeInfo *type, return type_info_poison(type); } } + else + { + // Otherwise we have to defer it: + vec_add(context->unit->check_type_variable_array, type); + } } TypeInfo *base_info = type->array.base; Type *base = base_info->type; diff --git a/test/test_suite/struct/flexible_array_resolve.c3 b/test/test_suite/struct/flexible_array_resolve.c3 new file mode 100644 index 000000000..cd0f5f91e --- /dev/null +++ b/test/test_suite/struct/flexible_array_resolve.c3 @@ -0,0 +1,16 @@ +struct Abc +{ + Foo[4] x; // #error: Arrays of structs with flexible array members +} + +struct Foo +{ + int a; + int[*] x; +} + +struct Foo2 +{ + int a; + int[*] x, y; // #error: must be the last element +}