When a member is checked, still add it to the environment. Addresses #903.

This commit is contained in:
Christoffer Lerno
2023-07-31 12:35:41 +02:00
parent 20699c1262
commit 72f5bac346
3 changed files with 31 additions and 26 deletions

View File

@@ -134,7 +134,12 @@ static inline bool sema_check_param_uniqueness_and_type(Decl **decls, Decl *curr
static inline bool sema_analyse_struct_member(SemaContext *context, Decl *parent, Decl *decl, bool *erase_decl)
{
if (decl->resolve_status == RESOLVE_DONE) return decl_ok(decl);
if (decl->resolve_status == RESOLVE_DONE)
{
if (!decl_ok(decl)) return false;
if (decl->name) sema_decl_stack_push(decl);
return true;
}
if (decl->resolve_status == RESOLVE_RUNNING)
{
RETURN_SEMA_ERROR(decl, "Circular dependency resolving member.");
@@ -216,18 +221,12 @@ static bool sema_analyse_union_members(SemaContext *context, Decl *decl, Decl **
Decl *member = members[i];
if (!decl_ok(member))
{
decl_poison(decl);
continue;
return decl_poison(decl);
}
bool erase_decl = false;
if (!sema_analyse_struct_member(context, decl, member, &erase_decl))
{
if (decl_ok(decl))
{
decl_poison(decl);
continue;
}
continue;
return decl_poison(member) || decl_poison(decl);
}
if (erase_decl)
{
@@ -239,7 +238,7 @@ static bool sema_analyse_union_members(SemaContext *context, Decl *decl, Decl **
if (member->type->type_kind == TYPE_INFERRED_ARRAY)
{
SEMA_ERROR(member, "Flexible array members not allowed in unions.");
return false;
return decl_poison(member) || decl_poison(decl);
}
AlignSize member_alignment;
if (!sema_set_abi_alignment(context, member->type, &member_alignment)) return false;
@@ -324,16 +323,11 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl, Decl *
{
AGAIN:;
Decl *member = struct_members[i];
if (!decl_ok(member))
{
decl_poison(decl);
continue;
}
if (!decl_ok(member)) return decl_poison(decl);
bool erase_decl = false;
if (!sema_analyse_struct_member(context, decl, member, &erase_decl))
{
decl_poison(member);
return decl_poison(decl);
return decl_poison(member) || decl_poison(decl);
}
if (erase_decl)
{
@@ -348,7 +342,7 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl, Decl *
if (i != member_count - 1)
{
SEMA_ERROR(member, "A struct member with a flexible array must be the last element.");
return false;
return decl_poison(member) || decl_poison(decl);
}
decl->has_variable_array = true;
}
@@ -357,12 +351,12 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl, Decl *
if (i != member_count - 1)
{
SEMA_ERROR(member, "The flexible array member must be the last element.");
return false;
return decl_poison(member) || decl_poison(decl);
}
if (i == 0)
{
SEMA_ERROR(member, "The flexible array member cannot be the only element.");
return false;
return decl_poison(member) || decl_poison(decl);
}
member->type = type_get_flexible_array(member->type->array.base);
decl->has_variable_array = true;
@@ -3379,8 +3373,10 @@ RETRY:
case TYPE_TYPEINFO:
case TYPE_MEMBER:
return true;
case TYPE_ENUM:
case TYPE_FUNC:
if (!type->decl) return true;
FALLTHROUGH;
case TYPE_ENUM:
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_BITSTRUCT:
@@ -3416,6 +3412,7 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
SemaContext temp_context;
context = context_transform_for_eval(context, &temp_context, decl->unit);
DEBUG_LOG(">>> Analysing %s.", decl->name ? decl->name : ".anon");
if (decl->resolve_status == RESOLVE_RUNNING)
{

View File

@@ -826,10 +826,11 @@ static inline bool sema_expr_analyse_ternary(SemaContext *context, Expr *expr)
static inline bool sema_expr_analyse_enum_constant(SemaContext *context, Expr *expr, const char *name, Decl *decl)
{
Decl *enum_constant = decl_find_enum_constant(decl, name);
if (!sema_resolve_type_decl(context, decl->type)) return false;
if (!enum_constant) return false;
// Resolve the structure at this point, since we might want to use the enum_constant
if (!sema_resolve_type_structure(context, decl->type, decl->span)) return false;
assert(enum_constant->resolve_status == RESOLVE_DONE);
expr->type = decl->type;
@@ -2914,6 +2915,9 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp
const char *name = identifier->identifier_expr.ident;
bool is_const = identifier->identifier_expr.is_const;
// Make sure that we have the full type structure.
if (!sema_resolve_type_structure(context, parent_type, expr->span)) return false;
if (!is_const)
{
if (sema_expr_rewrite_to_type_property(context, expr, canonical, type_property_by_name(name), parent_type)) return true;
@@ -3508,6 +3512,7 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr,
assert(type == type->canonical);
if (property == TYPE_PROPERTY_NONE) return false;
Type *flat = type_flatten(type);
if (!sema_resolve_type_structure(context, flat, expr->span)) return false;
switch (property)
{
case TYPE_PROPERTY_INF:
@@ -3931,6 +3936,7 @@ CHECK_DEEPER:
// 10. Dump all members and methods into the scope.
Decl *decl = type->decl;
Decl *member = sema_decl_stack_find_decl_member(decl, kw);
if (member && decl_is_enum_kind(decl) && member->decl_kind == DECL_VAR && expr_is_const(parent))
@@ -7576,7 +7582,6 @@ static inline bool sema_expr_analyse_compound_literal(SemaContext *context, Expr
{
if (!sema_resolve_type_info(context, expr->expr_compound_literal.type_info)) return false;
Type *type = expr->expr_compound_literal.type_info->type;
if (!sema_resolve_type_decl(context, type)) return false;
if (type_is_optional(type))
{
SEMA_ERROR(expr->expr_compound_literal.type_info,

View File

@@ -20,6 +20,11 @@ union Cc
{
int a;
int a; // #error: Duplicate member name 'a'
}
union Cc2
{
int a;
struct b
{
@@ -27,7 +32,6 @@ union Cc
int c; // #error: Duplicate member name 'c'
}
}
struct Dd
{
int b;
@@ -37,7 +41,6 @@ struct Dd
union
{
short a; // #error: Duplicate member name 'a'
int b; // #error: Duplicate member name 'b'
}
}
}