mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Allow using $defined(&a[1]) to check if the operation is supported.
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
- Added `$$unaligned_load` and `$$unaligned_store`.
|
||||
- `--no-headers` option to suppress creating headers when generating a library.
|
||||
- Support c-file compilation in libraries.
|
||||
- Allow using $defined(&a[1]) to check if the operation is supported.
|
||||
|
||||
### Fixes
|
||||
- Error with unsigned compare in `@ensure` when early returning 0 #1207.
|
||||
|
||||
@@ -2752,7 +2752,8 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr,
|
||||
assert(expr->expr_kind == EXPR_SUBSCRIPT || expr->expr_kind == EXPR_SUBSCRIPT_ADDR);
|
||||
|
||||
bool is_checking = eval_type == SUBSCRIPT_EVAL_VALID;
|
||||
if (is_checking) eval_type = SUBSCRIPT_EVAL_VALUE;
|
||||
if (is_checking) eval_type = expr->expr_kind == EXPR_SUBSCRIPT_ADDR
|
||||
? SUBSCRIPT_EVAL_REF : SUBSCRIPT_EVAL_VALUE;
|
||||
|
||||
// 1. Evaluate the expression to index.
|
||||
Expr *subscripted = exprptr(expr->subscript_expr.expr);
|
||||
@@ -2826,6 +2827,7 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr,
|
||||
{
|
||||
if (eval_type == SUBSCRIPT_EVAL_REF)
|
||||
{
|
||||
if (is_checking) goto VALID_FAIL_POISON;
|
||||
RETURN_SEMA_ERROR(subscripted, "You need to use && to take the address of a temporary.");
|
||||
}
|
||||
// 4a. This may either be an initializer list or a CT value
|
||||
@@ -2835,6 +2837,7 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr,
|
||||
// 4b. Now we need to check that we actually have a valid type.
|
||||
if (index_value < 0)
|
||||
{
|
||||
if (is_checking) goto VALID_FAIL_POISON;
|
||||
RETURN_SEMA_ERROR(index, "To subscript an untyped list a compile time integer index is needed.");
|
||||
}
|
||||
if (eval_type == SUBSCRIPT_EVAL_ASSIGN) TODO;
|
||||
@@ -2857,10 +2860,10 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr,
|
||||
&index_type,
|
||||
&overload))
|
||||
{
|
||||
SEMA_ERROR(expr,
|
||||
"A function or macro with '@operator(&[])' is not defined for %s, so you need && to take the address of the temporary.",
|
||||
type_quoted_error_string(subscripted->type));
|
||||
return false;
|
||||
if (is_checking) goto VALID_FAIL_POISON;
|
||||
RETURN_SEMA_ERROR(expr, "A function or macro with '@operator(&[])' is not defined for %s, "
|
||||
"so you need && to take the address of the temporary.",
|
||||
type_quoted_error_string(subscripted->type));
|
||||
}
|
||||
}
|
||||
if (is_checking) goto VALID_FAIL_POISON;
|
||||
@@ -2874,8 +2877,7 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr,
|
||||
if (!len)
|
||||
{
|
||||
if (is_checking) goto VALID_FAIL_POISON;
|
||||
SEMA_ERROR(subscripted, "Cannot index '%s' from the end, since there is no 'len' overload.", type_to_error_string(subscripted->type));
|
||||
return false;
|
||||
RETURN_SEMA_ERROR(subscripted, "Cannot index '%s' from the end, since there is no 'len' overload.", type_to_error_string(subscripted->type));
|
||||
}
|
||||
if (!sema_analyse_expr(context, current_expr)) return false;
|
||||
Decl *temp = decl_new_generated_var(current_expr->type, VARDECL_PARAM, current_expr->span);
|
||||
@@ -6298,6 +6300,15 @@ static inline bool sema_expr_analyse_addr(SemaContext *context, Expr *expr, bool
|
||||
goto REDO;
|
||||
case EXPR_SUBSCRIPT:
|
||||
inner->expr_kind = EXPR_SUBSCRIPT_ADDR;
|
||||
if (failed_ref)
|
||||
{
|
||||
if (!sema_expr_analyse_subscript(context, inner, SUBSCRIPT_EVAL_VALID)) return false;
|
||||
if (!expr_ok(inner))
|
||||
{
|
||||
*failed_ref = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!sema_analyse_expr_lvalue_fold_const(context, inner)) return false;
|
||||
expr_replace(expr, inner);
|
||||
return true;
|
||||
|
||||
29
test/test_suite/compile_time_introspection/defined_index.c3t
Normal file
29
test/test_suite/compile_time_introspection/defined_index.c3t
Normal file
@@ -0,0 +1,29 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
struct Abc { int x; }
|
||||
fn int* Abc.get(&self, usz index) @operator(&[]) { return &self.x; }
|
||||
|
||||
struct Bcd { int x; }
|
||||
fn int Bcd.get(&self, usz index) @operator([]) { return 1; }
|
||||
|
||||
fn void main()
|
||||
{
|
||||
Abc a;
|
||||
Bcd b;
|
||||
int[4] c;
|
||||
bool a1 = $defined(&a[0]);
|
||||
bool a2 = $defined(a[0]);
|
||||
bool b1 = $defined(&b[0]);
|
||||
bool b2 = $defined(b[0]);
|
||||
bool c1 = $defined(&c[0]);
|
||||
bool c2 = $defined(c[0]);
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
store i8 1, ptr %a1, align 1
|
||||
store i8 0, ptr %a2, align 1
|
||||
store i8 0, ptr %b1, align 1
|
||||
store i8 1, ptr %b2, align 1
|
||||
store i8 1, ptr %c1, align 1
|
||||
store i8 1, ptr %c2, align 1
|
||||
Reference in New Issue
Block a user