Alias and distinct types didn't check the underlying type wasn't compile time or optional.

This commit is contained in:
Christoffer Lerno
2025-09-19 18:05:29 +02:00
parent 59fd777198
commit b03ae8bb17
4 changed files with 50 additions and 4 deletions

View File

@@ -1910,7 +1910,7 @@ static inline Decl *parse_typedef_declaration(ParseContext *c)
return poisoned_decl;
}
// 2. Now parse the type which we know is here.
ASSIGN_TYPE_OR_RET(decl->distinct, parse_type(c), poisoned_decl);
ASSIGN_TYPE_OR_RET(decl->distinct, parse_optional_type(c), poisoned_decl);
ASSERT(!tok_is(c, TOKEN_LBRACE));

View File

@@ -41,7 +41,7 @@ static bool sema_analyse_attributes_for_var(SemaContext *context, Decl *decl, bo
static bool sema_check_section(SemaContext *context, Attr *attr);
static inline bool sema_analyse_attribute_decl(SemaContext *context, SemaContext *c, Decl *decl, bool *erase_decl);
static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl, bool *erase_decl);
static inline bool sema_analyse_type_alias(SemaContext *context, Decl *decl, bool *erase_decl);
static bool sema_analyse_variable_type(SemaContext *context, Type *type, SourceSpan span);
static inline bool sema_analyse_alias(SemaContext *context, Decl *decl, bool *erase_decl);
static inline bool sema_analyse_distinct(SemaContext *context, Decl *decl, bool *erase_decl);
@@ -1460,7 +1460,7 @@ static inline bool sema_analyse_fntype(SemaContext *context, Decl *decl, bool *e
return sema_analyse_function_signature(context, decl, NULL, sig->abi, sig);
}
static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl, bool *erase_decl)
static inline bool sema_analyse_type_alias(SemaContext *context, Decl *decl, bool *erase_decl)
{
if (!sema_analyse_attributes(context, decl, decl->attributes, ATTR_ALIAS, erase_decl)) return decl_poison(decl);
if (*erase_decl) return true;
@@ -1478,6 +1478,24 @@ static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl, bool *
TypeInfo *info = decl->type_alias_decl.type_info;
info->in_def = true;
if (!sema_resolve_type_info(context, info, RESOLVE_TYPE_DEFAULT)) return false;
if (type_is_optional(info->type))
{
RETURN_SEMA_ERROR(info, "You cannot create an alias for an optional type like %s.", type_quoted_error_string(info->type));
}
switch (sema_resolve_storage_type(context, info->type))
{
case STORAGE_ERROR:
return false;
case STORAGE_NORMAL:
case STORAGE_UNKNOWN:
case STORAGE_VOID:
break;
case STORAGE_WILDCARD:
RETURN_SEMA_ERROR(info, "You cannot create an alias for the wildcard type.");
case STORAGE_COMPILE_TIME:
RETURN_SEMA_ERROR(info, "You cannot create an alias for %s as it is a compile time type.",
type_invalid_storage_type_name(info->type));
}
decl->type->canonical = info->type->canonical;
// Do we need anything else?
return true;
@@ -1504,6 +1522,20 @@ static inline bool sema_analyse_distinct(SemaContext *context, Decl *decl, bool
// Optional isn't allowed of course.
if (type_is_optional(info->type)) RETURN_SEMA_ERROR(decl, "You cannot create a distinct type from an optional.");
switch (sema_resolve_storage_type(context, info->type))
{
case STORAGE_ERROR:
return false;
case STORAGE_NORMAL:
case STORAGE_UNKNOWN:
case STORAGE_VOID:
break;
case STORAGE_WILDCARD:
RETURN_SEMA_ERROR(info, "You cannot create a distinct type from the wildcard type.");
case STORAGE_COMPILE_TIME:
RETURN_SEMA_ERROR(info, "You cannot create a distinct type for %s as it is a compile time type.",
type_invalid_storage_type_name(info->type));
}
// Distinct types drop the canonical part.
info->type = info->type->canonical;
@@ -5386,7 +5418,7 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
if (!sema_analyse_distinct(context, decl, &erase_decl)) goto FAILED;
break;
case DECL_TYPEDEF:
if (!sema_analyse_typedef(context, decl, &erase_decl)) goto FAILED;
if (!sema_analyse_type_alias(context, decl, &erase_decl)) goto FAILED;
break;
case DECL_ENUM:
if (!sema_analyse_enum(context, decl, &erase_decl)) goto FAILED;