mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Compiler didn't check foreach over flexible array member, and folding a flexible array member was allowed #2164.
This commit is contained in:
@@ -52,6 +52,7 @@
|
||||
- `$$sat_mul` was missing.
|
||||
- `for` with incorrect `var` declaration caused crash #2154.
|
||||
- Check pointer/slice/etc on `[out]` and `&` params. #2156.
|
||||
- Compiler didn't check foreach over flexible array member, and folding a flexible array member was allowed #2164.
|
||||
|
||||
### Stdlib changes
|
||||
- Added `String.quick_ztr` and `String.is_zstr`
|
||||
|
||||
@@ -2374,7 +2374,7 @@ static inline bool unit_add_method(SemaContext *context, Type *parent_type, Decl
|
||||
other = sema_resolve_method(unit, parent, name, &ambiguous, &private);
|
||||
if (other)
|
||||
{
|
||||
if (unit->module->generic_module && other->unit->module->generic_module == unit->module->generic_module)
|
||||
if (unit->module->generic_module && other->unit->module->generic_module == unit->module->generic_module && other->unit->module != unit->module)
|
||||
{
|
||||
const char *module_name = unit->module->generic_module->name->module;
|
||||
RETURN_SEMA_ERROR(method, "The same method is generated by multiple instances of '%s': '%s%s' and '%s%s'. "
|
||||
|
||||
@@ -4981,6 +4981,7 @@ EVAL:
|
||||
switch (result->kind)
|
||||
{
|
||||
case CONST_INIT_ZERO:
|
||||
if (member->type->type_kind == TYPE_FLEXIBLE_ARRAY) return false;
|
||||
expr_rewrite_to_const_zero(expr, member->type);
|
||||
break;
|
||||
case CONST_INIT_STRUCT:
|
||||
@@ -5688,6 +5689,10 @@ CHECK_DEEPER:
|
||||
{
|
||||
if (!sema_expr_fold_to_member(expr, current_parent, member))
|
||||
{
|
||||
if (member->type->type_kind == TYPE_FLEXIBLE_ARRAY)
|
||||
{
|
||||
RETURN_SEMA_ERROR(expr, "Could not fold to member '%s', it's a flexible array member which is always empty.", member->name);
|
||||
}
|
||||
RETURN_SEMA_ERROR(expr, "Could not fold to member '%s' – it wasn't the last assigned member.", member->name);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -1497,6 +1497,10 @@ static inline bool sema_analyse_foreach_stmt(SemaContext *context, Ast *statemen
|
||||
// At this point we should have dereferenced any pointer or bailed.
|
||||
ASSERT_SPAN(enumerator, !type_is_pointer(enumerator->type));
|
||||
|
||||
if (enumerator->type->type_kind == TYPE_FLEXIBLE_ARRAY)
|
||||
{
|
||||
RETURN_SEMA_ERROR(enumerator, "It is not possible to enumerate over a flexible array member.", type_quoted_error_string(enumerator->type));
|
||||
}
|
||||
// Check that we can even index this expression, this will dig into the flattened type.
|
||||
Type *value_type = type_get_indexed_type(enumerator->type);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ struct Widget
|
||||
List {any} children;
|
||||
}
|
||||
|
||||
fn void Widget{Label}.draw(Widget* self) // #error: This identifier is recursively using gui::widget
|
||||
fn void Widget{Label}.draw(Widget* self) // #error: The same method is generated by multiple instances
|
||||
{
|
||||
io::printfn("Hello Label");
|
||||
}
|
||||
|
||||
15
test/test_suite/statements/foreach_fails.c3
Normal file
15
test/test_suite/statements/foreach_fails.c3
Normal file
@@ -0,0 +1,15 @@
|
||||
struct Abc
|
||||
{
|
||||
int a;
|
||||
int[*] b;
|
||||
}
|
||||
fn void test()
|
||||
{
|
||||
Abc y = {};
|
||||
foreach (x : y.b) {} // #error: It is not possible to enumerate over a flexible
|
||||
}
|
||||
fn int main()
|
||||
{
|
||||
foreach (x : (Abc){}.b) {} // #error: it's a flexible array member
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user