- Constant shifting incorrectly doesn't flatten the underlying vector base #2825

- String not set as attributes resolved breaking has_tagof #2824
- Self referencing forward resolved const enum fails to be properly detected #2823
This commit is contained in:
Christoffer Lerno
2026-01-24 18:32:26 +01:00
parent 5e23817a3d
commit 397d065a74
6 changed files with 36 additions and 5 deletions

View File

@@ -113,6 +113,9 @@
- Comparing a flexible array member to another type would hit an assert. #2830
- Underlying slice type not checked correctly in $defined #2829
- Checking for exhaustive cases is done even in if-chain switch if all is enum #2828
- Constant shifting incorrectly doesn't flatten the underlying vector base #2825
- String not set as attributes resolved breaking has_tagof #2824
- Self referencing forward resolved const enum fails to be properly detected #2823
### Stdlib changes
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.

View File

@@ -1187,14 +1187,19 @@ static inline bool sema_expr_analyse_enum_constant(SemaContext *context, Expr *e
Decl *enum_constant = decl_find_enum_constant(decl, name);
if (!enum_constant) return false;
if (!sema_analyse_decl(context, decl)) return false;
if (!sema_analyse_decl(context, decl)) return expr_poison(expr), true;
ASSERT_SPAN(expr, enum_constant->resolve_status != RESOLVE_NOT_DONE);
if (enum_constant->resolve_status == RESOLVE_NOT_DONE)
{
SEMA_ERROR(expr, "Unable to properly resolve enum constant value, this can sometimes happen in recursive definitions.");
return expr_poison(expr), true;
}
expr->type = decl->type;
if (enum_constant->enum_constant.is_raw)
{
expr_replace(expr, copy_expr_single(enum_constant->enum_constant.value));
return sema_analyse_expr_rvalue(context, expr);
if (!sema_analyse_expr_rvalue(context, expr)) expr_poison(expr);
return true;
}
expr->expr_kind = EXPR_CONST;
expr->const_expr.const_kind = CONST_ENUM;
@@ -5077,7 +5082,7 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp
RETURN_SEMA_ERROR(expr, "'%s' has no enumeration value '%s'.", decl->name, name);
return false;
}
return true;
return expr_ok(expr);
}
break;
case DECL_UNION:
@@ -8304,7 +8309,7 @@ static bool sema_expr_check_shift_rhs(SemaContext *context, Expr *expr, Expr *le
{
// Make sure the value does not exceed the bitsize of
// the left hand side. We ignore this check for lhs being a constant.
Type *base = type_vector_base(left_type_flat);
Type *base = type_flatten(type_vector_base(left_type_flat));
ASSERT_SPAN(expr, type_kind_is_any_integer(base->type_kind));
if (int_ucomp(right->const_expr.ixx, base->builtin.bitsize, BINARYOP_GE))
{

View File

@@ -1548,6 +1548,7 @@ void type_setup(PlatformTarget *target)
type_wildcard_optional = type_get_optional(type_wildcard);
Decl *string_decl = decl_new_with_type(symtab_preset("String", TOKEN_TYPE_IDENT), INVALID_SPAN, DECL_TYPEDEF);
string_decl->unit = compiler.context.core_unit;
string_decl->resolved_attributes = true;
string_decl->extname = string_decl->name;
string_decl->is_substruct = true;
string_decl->distinct = type_info_new_base(type_chars, INVALID_SPAN);

View File

@@ -0,0 +1,11 @@
enum MyEnum : const
{
VAL1 = VAL3, // #error: Unable to properly resolve enum constant value, this can sometimes happen in recursive definitions
VAL2 ,
VAL3
}
fn int main()
{
return 0;
}

View File

@@ -0,0 +1,5 @@
typedef Foo = int;
Foo[<2>] f3 = (Foo[<2>]) 1 << 2; // #error: The expression must be a constant value
fn int main() => 0;

View File

@@ -0,0 +1,6 @@
fn int main()
{
$if String.has_tagof(""):
$endif
return 0;
}