Skip to content

Commit

Permalink
Struct/union members now correctly rejects members without storage size
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed Feb 19, 2024
1 parent 0373022 commit 928d7b0
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 13 deletions.
2 changes: 1 addition & 1 deletion releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
- Disallow multiple `_` in a row in digits, e.g. `1__000`.

### Fixes
None
- Struct/union members now correctly rejects members without storage size #1147.

### Stdlib changes
None
Expand Down
1 change: 1 addition & 0 deletions src/compiler/compiler_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -2837,6 +2837,7 @@ INLINE bool type_is_invalid_storage_type(Type *type)
if (type == type_wildcard_optional) return true;
switch (type->type_kind)
{
case TYPE_VOID:
case TYPE_MEMBER:
case TYPE_UNTYPED_LIST:
case TYPE_TYPEINFO:
Expand Down
13 changes: 11 additions & 2 deletions src/compiler/sema_decls.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,22 @@ static inline bool sema_analyse_struct_member(SemaContext *context, Decl *parent
switch (decl->decl_kind)
{
case DECL_VAR:
{
assert(decl->var.kind == VARDECL_MEMBER);
decl->resolve_status = RESOLVE_RUNNING;
// Inferred types are not strictly allowed, but we use the int[*] for the flexible array member.
if (!sema_resolve_type_info(context, type_infoptrzero(decl->var.type_info), RESOLVE_TYPE_ALLOW_FLEXIBLE)) return decl_poison(decl);
decl->type = typeget(decl->var.type_info);
assert(type_infoptrzero(decl->var.type_info));
TypeInfo *type_info = type_infoptr(decl->var.type_info);
if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_ALLOW_FLEXIBLE)) return decl_poison(decl);
Type *type = type_info->type;
if (type_is_invalid_storage_type(type))
{
RETURN_SEMA_ERROR(type_info, "Members cannot be of type %s.", type_quoted_error_string(type));
}
decl->type = type;
decl->resolve_status = RESOLVE_DONE;
return true;
}
case DECL_STRUCT:
case DECL_UNION:
case DECL_BITSTRUCT:
Expand Down
10 changes: 5 additions & 5 deletions src/compiler/sema_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1276,7 +1276,7 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
{
if (!sema_analyse_expr(context, arg)) return false;
Type *type = arg->type;
if (type_is_invalid_storage_type(type) || type == type_void)
if (type_is_invalid_storage_type(type))
{
RETURN_SEMA_ERROR(arg, "A value of type %s cannot be passed as a variadic argument.",
type_quoted_error_string(type));
Expand Down Expand Up @@ -1489,7 +1489,7 @@ static inline bool sema_call_analyse_invocation(SemaContext *context, Expr *call
else
{
if (!sema_analyse_expr(context, val)) return false;
if (type_is_invalid_storage_type(val->type) || val->type == type_void)
if (type_is_invalid_storage_type(val->type))
{
SEMA_ERROR(val, "A value of type %s cannot be passed as a variadic argument.",
type_quoted_error_string(val->type));
Expand Down Expand Up @@ -1561,7 +1561,7 @@ static inline bool sema_call_analyse_invocation(SemaContext *context, Expr *call
if (!type_is_any_interface_ptr(arg->type)) expr_insert_addr(arg);
*optional |= IS_OPTIONAL(arg);
if (!sema_call_check_contract_param_match(context, param, arg)) return false;
if (type_is_invalid_storage_type(type) || type == type_void)
if (type_is_invalid_storage_type(type))
{
SEMA_ERROR(arg, "A value of type %s cannot be passed by reference.", type_quoted_error_string(type));
return false;
Expand Down Expand Up @@ -6391,7 +6391,7 @@ static inline bool sema_expr_analyse_taddr(SemaContext *context, Expr *expr, boo
if (!sema_analyse_expr(context, inner)) return false;

Type *type = inner->type;
if (type_is_invalid_storage_type(type) || type == type_void)
if (type_is_invalid_storage_type(type))
{
if (failed_ref)
{
Expand Down Expand Up @@ -7141,7 +7141,7 @@ static inline bool sema_expr_analyse_ct_alignof(SemaContext *context, Expr *expr
Decl *decl = sema_expr_analyse_var_path(context, main_var);
if (!decl) return false;
Type *type = decl->type;
if (type_is_invalid_storage_type(type) || type == type_void)
if (type_is_invalid_storage_type(type))
{
SEMA_ERROR(main_var, "Cannot use '$alignof' on type %s.", type_quoted_error_string(type));
return false;
Expand Down
11 changes: 6 additions & 5 deletions src/compiler/sema_types.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ INLINE bool sema_resolve_evaltype(SemaContext *context, TypeInfo *type_info, Res
}
TypeInfo *inner_type = inner->type_expr;
if (!sema_resolve_type(context, inner_type, resolve_kind)) return false;
if (type_is_invalid_storage_type(inner_type->type))
if (inner_type->type != type_void && type_is_invalid_storage_type(inner_type->type))
{
SEMA_ERROR(expr, "Compile-time types may not be used with $evaltype.");
return false;
Expand All @@ -313,19 +313,20 @@ INLINE bool sema_resolve_typeof(SemaContext *context, TypeInfo *type_info)
{
Expr *expr = type_info->unresolved_type_expr;
if (!sema_analyse_expr(context, expr)) return false;
if (type_is_invalid_storage_type(expr->type))
Type *expr_type = expr->type;
if (expr_type != type_void && type_is_invalid_storage_type(expr->type))
{
if (expr->type == type_wildcard)
if (expr_type == type_wildcard)
{
RETURN_SEMA_ERROR(expr, "This expression has no concrete type.");
}
if (expr->type == type_wildcard_optional)
if (expr_type == type_wildcard_optional)
{
RETURN_SEMA_ERROR(expr, "This optional expression is untyped.");
}
RETURN_SEMA_ERROR(expr, "Expected a regular runtime expression here.");
}
type_info->type = expr->type;
type_info->type = expr_type;
return true;
}

Expand Down
7 changes: 7 additions & 0 deletions test/test_suite/struct/struct_bad_member.c3
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
struct Foo {
void bar; // #error: Members cannot be of
}

fn void main(String[] args) {
Foo foo;
}

0 comments on commit 928d7b0

Please sign in to comment.