- Better error messages when slicing a pointer to a slice or vector. #2681

This commit is contained in:
Christoffer Lerno
2025-12-25 22:01:15 +01:00
parent e706c914a8
commit 1028f85daa
3 changed files with 51 additions and 4 deletions

View File

@@ -10,6 +10,7 @@
- Support for NetBSD. - Support for NetBSD.
- Testing for the presence of methods at the top level is prohibited previous to method registration. - Testing for the presence of methods at the top level is prohibited previous to method registration.
- `$$MASK_TO_INT` and `$$INT_TO_MASK` to create bool masks from integers and back. - `$$MASK_TO_INT` and `$$INT_TO_MASK` to create bool masks from integers and back.
- Better error messages when slicing a pointer to a slice or vector. #2681
### Fixes ### Fixes
- Regression with npot vector in struct triggering an assert #2219. - Regression with npot vector in struct triggering an assert #2219.

View File

@@ -4450,7 +4450,7 @@ typedef enum RangeEnv
RANGE_FLEXIBLE, RANGE_FLEXIBLE,
} RangeEnv; } RangeEnv;
INLINE bool sema_expr_analyse_range_internal(SemaContext *context, Range *range, ArrayIndex len, RangeEnv env) INLINE bool sema_expr_analyse_range_internal(SemaContext *context, Range *range, ArrayIndex len, RangeEnv env, FlatType *indexed_type)
{ {
Expr *start = exprptr(range->start); Expr *start = exprptr(range->start);
ASSERT(start); ASSERT(start);
@@ -4482,14 +4482,26 @@ INLINE bool sema_expr_analyse_range_internal(SemaContext *context, Range *range,
{ {
if (range->start_from_end) if (range->start_from_end)
{ {
if (indexed_type->type_kind == TYPE_POINTER && type_is_any_arraylike(indexed_type->pointer))
{
RETURN_SEMA_ERROR(start, "Indexing from the end is not allowed for pointers, did you perhaps forget to dereference the pointer before []?");
}
RETURN_SEMA_ERROR(start, "Indexing from the end is not allowed for pointers or flexible array members."); RETURN_SEMA_ERROR(start, "Indexing from the end is not allowed for pointers or flexible array members.");
} }
if (!end) if (!end)
{ {
if (indexed_type->type_kind == TYPE_POINTER && type_is_any_arraylike(indexed_type->pointer))
{
RETURN_SEMA_ERROR(start, "Omitting the end index is not allowed for pointers, did you perhaps forget to dereference the pointer before slicing wih []?");
}
RETURN_SEMA_ERROR(start, "Omitting end index is not allowed for pointers or flexible array members."); RETURN_SEMA_ERROR(start, "Omitting end index is not allowed for pointers or flexible array members.");
} }
if (end && range->end_from_end) if (end && range->end_from_end)
{ {
if (indexed_type->type_kind == TYPE_POINTER && type_is_any_arraylike(indexed_type->pointer))
{
RETURN_SEMA_ERROR(start, "Indexing from the end is not allowed for pointers, did you perhaps forget to dereference the pointer before []?");
}
RETURN_SEMA_ERROR(end, "Indexing from the end is not allowed for pointers or flexible array members."); RETURN_SEMA_ERROR(end, "Indexing from the end is not allowed for pointers or flexible array members.");
} }
} }
@@ -4609,7 +4621,7 @@ INLINE bool sema_expr_analyse_range_internal(SemaContext *context, Range *range,
} }
static inline bool sema_expr_analyse_range(SemaContext *context, Range *range, ArrayIndex len, RangeEnv env) static inline bool sema_expr_analyse_range(SemaContext *context, Range *range, ArrayIndex len, RangeEnv env, FlatType *indexed_type)
{ {
switch (range->status) switch (range->status)
{ {
@@ -4617,7 +4629,7 @@ static inline bool sema_expr_analyse_range(SemaContext *context, Range *range, A
return true; return true;
case RESOLVE_NOT_DONE: case RESOLVE_NOT_DONE:
range->status = RESOLVE_RUNNING; range->status = RESOLVE_RUNNING;
if (!sema_expr_analyse_range_internal(context, range, len, env)) if (!sema_expr_analyse_range_internal(context, range, len, env, indexed_type))
{ {
range->status = RESOLVE_NOT_DONE; range->status = RESOLVE_NOT_DONE;
return false; return false;
@@ -4733,7 +4745,7 @@ static inline bool sema_expr_analyse_slice(SemaContext *context, Expr *expr)
} }
ArrayIndex length = sema_len_from_expr(subscripted); ArrayIndex length = sema_len_from_expr(subscripted);
Range *range = &expr->slice_expr.range; Range *range = &expr->slice_expr.range;
if (!sema_expr_analyse_range(context, range, length, env)) return false; if (!sema_expr_analyse_range(context, range, length, env, type)) return false;
if (range->is_optional) optional = true; if (range->is_optional) optional = true;
if (sema_cast_const(subscripted) && range->range_type == RANGE_CONST_RANGE) if (sema_cast_const(subscripted) && range->range_type == RANGE_CONST_RANGE)
{ {

View File

@@ -0,0 +1,34 @@
import std;
macro transpose4x4_mat(a, b, c, d)
{
Matrix4x4{float} mat;
mat.m[0..3] = *a[..]; // #error: Omitting the end index is not allowed for pointers, did you perhaps forget to dereference the pointer before slicing wih []?
mat.m[4..7] = *b[..];
mat.m[8..11] = *c[..];
mat.m[12..15] = *d[..];
mat = mat.transpose();
*a = mat.m[0..3];
*b = mat.m[4..7];
*c = mat.m[8..11];
*d = mat.m[12..15];
}
fn void main()
{
float[<4>] a = { 0,1,2,3 };
float[<4>] b = { 4,5,6,7 };
float[<4>] c = { 8,9,10,11 };
float[<4>] d = { 12,13,14,15 };
transpose4x4_mat(&a, &b, &c, &d);
io::printn(a);
io::printn(b);
io::printn(c);
io::printn(d);
}