Assert comparing untyped lists #2240.

This commit is contained in:
Christoffer Lerno
2025-06-24 12:47:08 +02:00
parent 605a7c4091
commit a894adbdd6
5 changed files with 14 additions and 9 deletions

View File

@@ -64,6 +64,7 @@
- Compiler segfault when using distinct type in attribute imported from other module #2234. - Compiler segfault when using distinct type in attribute imported from other module #2234.
- Assert casting bitstruct to short/char #2237. - Assert casting bitstruct to short/char #2237.
- @tag didn't work with members #2236. - @tag didn't work with members #2236.
- Assert comparing untyped lists #2240.
### Stdlib changes ### Stdlib changes
- Deprecate `String.is_zstr` and `String.quick_zstr` #2188. - Deprecate `String.is_zstr` and `String.quick_zstr` #2188.

View File

@@ -208,11 +208,9 @@ bool expr_const_compare(const ExprConst *left, const ExprConst *right, BinaryOp
is_eq = !memcmp(left->bytes.ptr, right->bytes.ptr, left->bytes.len); is_eq = !memcmp(left->bytes.ptr, right->bytes.ptr, left->bytes.len);
goto RETURN; goto RETURN;
case CONST_SLICE: case CONST_SLICE:
return false;
case CONST_INITIALIZER: case CONST_INITIALIZER:
return false;
case CONST_UNTYPED_LIST: case CONST_UNTYPED_LIST:
return false; UNREACHABLE;
case CONST_MEMBER: case CONST_MEMBER:
is_eq = left->member.decl == right->member.decl; is_eq = left->member.decl == right->member.decl;
goto RETURN; goto RETURN;

View File

@@ -7650,16 +7650,13 @@ static bool sema_expr_analyse_and_or(SemaContext *context, Expr *expr, Expr *lef
return true; return true;
} }
static bool sema_binary_is_unsigned_always_same_comparison(SemaContext *context, Expr *expr, Expr *left, Expr *right, static bool sema_binary_is_unsigned_always_same_comparison(SemaContext *context, Expr *expr, Expr *left, Expr *right,
Type *lhs_type, Type *rhs_type) Type *lhs_type, Type *rhs_type)
{ {
if (context->active_scope.flags & (SCOPE_MACRO | SCOPE_ENSURE | SCOPE_ENSURE_MACRO)) return true; if (context->active_scope.flags & (SCOPE_MACRO | SCOPE_ENSURE | SCOPE_ENSURE_MACRO)) return true;
if (!sema_cast_const(left) && !sema_cast_const(right)) return true; if (!sema_cast_const(left) && !sema_cast_const(right)) return true;
if (!type_is_integer(left->type)) return true; if (!type_is_integer(left->type)) return true;
if (expr_is_const(left) && type_is_unsigned(rhs_type)) if (expr_is_const_int(left) && type_is_unsigned(rhs_type))
{ {
if (int_is_neg(left->const_expr.ixx)) if (int_is_neg(left->const_expr.ixx))
{ {
@@ -7685,7 +7682,7 @@ static bool sema_binary_is_unsigned_always_same_comparison(SemaContext *context,
return true; return true;
} }
} }
if (!expr_is_const(right) || !type_is_unsigned(lhs_type)) return true; if (!expr_is_const_int(right) || !type_is_unsigned(lhs_type)) return true;
if (int_is_neg(right->const_expr.ixx)) if (int_is_neg(right->const_expr.ixx))
{ {
SEMA_ERROR(right, "Comparing an unsigned value with a negative constant is only allowed inside of macros."); SEMA_ERROR(right, "Comparing an unsigned value with a negative constant is only allowed inside of macros.");
@@ -7807,6 +7804,10 @@ NEXT:
RETURN_SEMA_ERROR(expr, "Vector types can only be tested for equality, for other comparison, use vector comparison functions."); RETURN_SEMA_ERROR(expr, "Vector types can only be tested for equality, for other comparison, use vector comparison functions.");
} }
if (max == type_untypedlist)
{
RETURN_SEMA_ERROR(expr, "Both sides are untyped and cannot be compared. Please cast one or both sides to a type, e.g. (Foo){ 1, 2 } == { 1, 2 }.");
}
if (!type_is_comparable(max)) if (!type_is_comparable(max))
{ {
CHECK_ON_DEFINED(failed_ref); CHECK_ON_DEFINED(failed_ref);

View File

@@ -511,6 +511,7 @@ bool type_is_comparable(Type *type)
case TYPE_FLEXIBLE_ARRAY: case TYPE_FLEXIBLE_ARRAY:
case TYPE_OPTIONAL: case TYPE_OPTIONAL:
case TYPE_MEMBER: case TYPE_MEMBER:
case TYPE_UNTYPED_LIST:
return false; return false;
case TYPE_UNION: case TYPE_UNION:
case TYPE_STRUCT: case TYPE_STRUCT:
@@ -540,7 +541,6 @@ bool type_is_comparable(Type *type)
case TYPE_ENUM: case TYPE_ENUM:
case TYPE_FUNC_PTR: case TYPE_FUNC_PTR:
case TYPE_FUNC_RAW: case TYPE_FUNC_RAW:
case TYPE_UNTYPED_LIST:
case TYPE_TYPEINFO: case TYPE_TYPEINFO:
case TYPE_VECTOR: case TYPE_VECTOR:
case TYPE_WILDCARD: case TYPE_WILDCARD:

View File

@@ -0,0 +1,5 @@
fn int main()
{
assert({0, 1, 2} == {0, 1, 2}, "Slices must be equivalent"); // #error: Both sides are untyped and cannot be compared
return 0;
}