mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Assert comparing untyped lists #2240.
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
5
test/test_suite/expressions/comparing_untyped.c3
Normal file
5
test/test_suite/expressions/comparing_untyped.c3
Normal 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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user