mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix bug where !! and ! was not recognized to jump out of the current scope. Remove more casts.
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
- Change CBool to be 1 byte.
|
||||
- `any_to_int` checks value to be int and no longer works with enum.
|
||||
- Add check in formatter printing "%c".
|
||||
- Fix bug where `!!` and `!` was not recognized to jump out of the current scope.
|
||||
|
||||
### Stdlib changes
|
||||
- Increase BitWriter.write_bits limit up to 32 bits.
|
||||
|
||||
@@ -395,6 +395,7 @@ static void c_emit_expr(GenContext *c, CValue *value, Expr *expr)
|
||||
{
|
||||
switch (expr->expr_kind)
|
||||
{
|
||||
case EXPR_PTR_ACCESS:
|
||||
case EXPR_EXT_TRUNC:
|
||||
break;
|
||||
case EXPR_ACCESS:
|
||||
|
||||
@@ -3380,6 +3380,7 @@ static inline void expr_set_span(Expr *expr, SourceSpan loc)
|
||||
case EXPR_DEFAULT_ARG:
|
||||
case EXPR_TYPECALL:
|
||||
case EXPR_MEMBER_GET:
|
||||
case EXPR_PTR_ACCESS:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3591,6 +3592,15 @@ INLINE void expr_rewrite_const_typeid(Expr *expr, Type *type)
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
}
|
||||
|
||||
INLINE void expr_rewrite_ptr_access(Expr *expr, Type *type)
|
||||
{
|
||||
Expr *inner = expr_copy(expr);
|
||||
expr->expr_kind = EXPR_PTR_ACCESS;
|
||||
expr->inner_expr = inner;
|
||||
expr->type = type;
|
||||
}
|
||||
|
||||
|
||||
INLINE void expr_rewrite_ext_trunc(Expr *expr, Type *type, bool is_signed)
|
||||
{
|
||||
Expr *inner = expr_copy(expr);
|
||||
|
||||
@@ -472,6 +472,7 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr)
|
||||
case EXPR_OPTIONAL:
|
||||
case EXPR_SPLAT:
|
||||
case EXPR_STRINGIFY:
|
||||
case EXPR_PTR_ACCESS:
|
||||
MACRO_COPY_EXPR(expr->inner_expr);
|
||||
return expr;
|
||||
case EXPR_DEFAULT_ARG:
|
||||
|
||||
@@ -534,7 +534,6 @@ typedef enum
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CAST_ANYPTR,
|
||||
CAST_ANYBOOL,
|
||||
CAST_APTSA,
|
||||
CAST_ARRVEC,
|
||||
@@ -562,7 +561,6 @@ typedef enum
|
||||
CAST_PTRPTR,
|
||||
CAST_PTRINT,
|
||||
CAST_SLBOOL,
|
||||
CAST_SAPTR,
|
||||
CAST_SLSL,
|
||||
CAST_SLARR,
|
||||
CAST_STRPTR,
|
||||
@@ -798,6 +796,7 @@ typedef enum
|
||||
EXPR_OTHER_CONTEXT,
|
||||
EXPR_POINTER_OFFSET,
|
||||
EXPR_POISONED,
|
||||
EXPR_PTR_ACCESS,
|
||||
EXPR_POST_UNARY,
|
||||
EXPR_RETHROW,
|
||||
EXPR_RETVAL,
|
||||
|
||||
@@ -82,6 +82,7 @@ bool expr_may_addr(Expr *expr)
|
||||
return true;
|
||||
case EXPR_BENCHMARK_HOOK:
|
||||
case EXPR_TEST_HOOK:
|
||||
case EXPR_PTR_ACCESS:
|
||||
return false;
|
||||
case NON_RUNTIME_EXPR:
|
||||
case EXPR_ASM:
|
||||
@@ -185,6 +186,7 @@ bool expr_is_runtime_const(Expr *expr)
|
||||
case EXPR_MEMBER_GET:
|
||||
case EXPR_BITACCESS:
|
||||
case EXPR_COND:
|
||||
case EXPR_PTR_ACCESS:
|
||||
return false;
|
||||
case EXPR_ACCESS:
|
||||
expr = expr->access_expr.parent;
|
||||
@@ -335,7 +337,6 @@ static inline bool expr_cast_is_runtime_const(Expr *expr)
|
||||
case CAST_ERROR:
|
||||
UNREACHABLE
|
||||
case CAST_INTENUM:
|
||||
case CAST_ANYPTR:
|
||||
case CAST_EUBOOL:
|
||||
case CAST_EUER:
|
||||
case CAST_EREU:
|
||||
@@ -357,7 +358,6 @@ static inline bool expr_cast_is_runtime_const(Expr *expr)
|
||||
case CAST_INTPTR:
|
||||
case CAST_PTRPTR:
|
||||
case CAST_APTSA:
|
||||
case CAST_SAPTR:
|
||||
case CAST_SLSL:
|
||||
case CAST_VOID:
|
||||
case CAST_ANYBOOL:
|
||||
@@ -604,6 +604,8 @@ bool expr_is_pure(Expr *expr)
|
||||
case EXPR_BENCHMARK_HOOK:
|
||||
case EXPR_TEST_HOOK:
|
||||
return false;
|
||||
case EXPR_PTR_ACCESS:
|
||||
return expr_is_pure(expr->inner_expr);
|
||||
case EXPR_EXT_TRUNC:
|
||||
return expr_is_pure(expr->ext_trunc_expr.inner);
|
||||
case EXPR_OTHER_CONTEXT:
|
||||
|
||||
@@ -243,13 +243,17 @@ void print_var_expr(FILE *file, Expr *expr)
|
||||
|
||||
switch (expr->expr_kind)
|
||||
{
|
||||
case EXPR_BITASSIGN:
|
||||
case EXPR_BITASSIGN:
|
||||
case EXPR_BITACCESS:
|
||||
case EXPR_ACCESS:
|
||||
print_var_expr(file, expr->access_expr.parent);
|
||||
fputs(".", file);
|
||||
print_var_expr(file, expr->access_expr.child);
|
||||
break;
|
||||
case EXPR_PTR_ACCESS:
|
||||
print_var_expr(file, expr->access_expr.parent);
|
||||
fputs(".ptr", file);
|
||||
break;
|
||||
case EXPR_EXT_TRUNC:
|
||||
TODO
|
||||
case EXPR_BINARY:
|
||||
|
||||
@@ -1468,9 +1468,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
|
||||
value->value = LLVMBuildIsNotNull(c->builder, value->value, "anybool");
|
||||
value->kind = BE_BOOLEAN;
|
||||
break;
|
||||
case CAST_ANYPTR:
|
||||
llvm_emit_any_pointer(c, value, value);
|
||||
break;
|
||||
case CAST_ERROR:
|
||||
UNREACHABLE
|
||||
case CAST_STRPTR:
|
||||
@@ -1484,10 +1481,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu
|
||||
case CAST_APTSA:
|
||||
llvm_emit_arr_to_slice_cast(c, value, to_type);
|
||||
break;
|
||||
case CAST_SAPTR:
|
||||
llvm_value_fold_optional(c, value);
|
||||
llvm_emit_slice_pointer(c, value, value);
|
||||
break;
|
||||
case CAST_EREU:
|
||||
// This is a no op.
|
||||
ASSERT0(type_lowering(to_type) == type_lowering(from_type));
|
||||
@@ -6147,8 +6140,8 @@ static void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr
|
||||
{
|
||||
ASSERT0(arg_count);
|
||||
Expr *any_val = args[0];
|
||||
ASSERT0(any_val->expr_kind == EXPR_CAST);
|
||||
args[0] = exprptr(any_val->cast_expr.expr);
|
||||
ASSERT0(any_val->expr_kind == EXPR_PTR_ACCESS);
|
||||
args[0] = any_val->inner_expr;
|
||||
}
|
||||
|
||||
if (!expr->call_expr.is_func_ref)
|
||||
@@ -7200,6 +7193,21 @@ void llvm_emit_expr_global_value(GenContext *c, BEValue *value, Expr *expr)
|
||||
ASSERT0(!llvm_value_is_addr(value));
|
||||
}
|
||||
|
||||
static void llvm_emit_ptr_access(GenContext *c, BEValue *value, Expr *expr)
|
||||
{
|
||||
llvm_emit_expr(c, value, expr->inner_expr);
|
||||
llvm_value_fold_optional(c, value);
|
||||
if (value->kind == BE_ADDRESS)
|
||||
{
|
||||
AlignSize alignment;
|
||||
LLVMValueRef ptr = llvm_emit_struct_gep_raw(c, value->value, llvm_get_type(c, value->type), 0, value->alignment, &alignment);
|
||||
llvm_value_set_address(value, ptr, expr->type, alignment);
|
||||
return;
|
||||
}
|
||||
LLVMValueRef ptr = llvm_emit_extract_value(c, value->value, 0);
|
||||
llvm_value_set(value, ptr, expr->type);
|
||||
}
|
||||
|
||||
static void llvm_emit_ext_trunc(GenContext *c, BEValue *value, Expr *expr)
|
||||
{
|
||||
llvm_emit_expr(c, value, expr->ext_trunc_expr.inner);
|
||||
@@ -7229,6 +7237,9 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
case EXPR_MEMBER_GET:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
UNREACHABLE
|
||||
case EXPR_PTR_ACCESS:
|
||||
llvm_emit_ptr_access(c, value, expr);
|
||||
return;
|
||||
case EXPR_EXT_TRUNC:
|
||||
llvm_emit_ext_trunc(c, value, expr);
|
||||
return;
|
||||
|
||||
@@ -1479,7 +1479,11 @@ static void cast_fault_to_int(SemaContext *context, Expr *expr, Type *type)
|
||||
}
|
||||
static void cast_typeid_to_ptr(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_IDPTR, type); }
|
||||
static void cast_any_to_bool(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_ANYBOOL, type); }
|
||||
static void cast_any_to_ptr(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_ANYPTR, type); }
|
||||
static void cast_any_to_ptr(SemaContext *context, Expr *expr, Type *type)
|
||||
{
|
||||
expr_rewrite_ptr_access(expr, type);
|
||||
}
|
||||
|
||||
static void cast_all_to_void(SemaContext *context, Expr *expr, Type *to_type) { insert_runtime_cast(expr, CAST_VOID, type_void); }
|
||||
static void cast_retype(SemaContext *context, Expr *expr, Type *to_type) { expr->type = to_type; }
|
||||
|
||||
@@ -1911,7 +1915,8 @@ static void cast_slice_to_ptr(SemaContext *context, Expr *expr, Type *type)
|
||||
expr->type = type;
|
||||
return;
|
||||
}
|
||||
insert_runtime_cast(expr, CAST_SAPTR, type);
|
||||
|
||||
expr_rewrite_ptr_access(expr, type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -569,6 +569,7 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
|
||||
case EXPR_LAST_FAULT:
|
||||
case EXPR_MEMBER_GET:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
case EXPR_PTR_ACCESS:
|
||||
goto ERR;
|
||||
}
|
||||
UNREACHABLE
|
||||
@@ -596,6 +597,7 @@ static bool expr_may_ref(Expr *expr)
|
||||
case EXPR_TYPECALL:
|
||||
case EXPR_MEMBER_GET:
|
||||
case EXPR_EXT_TRUNC:
|
||||
case EXPR_PTR_ACCESS:
|
||||
return false;
|
||||
case EXPR_OTHER_CONTEXT:
|
||||
return expr_may_ref(expr->expr_other_context.inner);
|
||||
@@ -7650,7 +7652,6 @@ static inline bool sema_expr_analyse_rethrow(SemaContext *context, Expr *expr)
|
||||
"but the function does not allow optional results. Did you mean to use '!!' instead?");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8929,6 +8930,7 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr
|
||||
case EXPR_MEMBER_GET:
|
||||
case EXPR_SPLAT:
|
||||
case EXPR_EXT_TRUNC:
|
||||
case EXPR_PTR_ACCESS:
|
||||
if (!sema_analyse_expr(active_context, main_expr)) return false;
|
||||
break;
|
||||
}
|
||||
@@ -9306,6 +9308,8 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr,
|
||||
case EXPR_TRY_UNWRAP_CHAIN:
|
||||
case EXPR_TYPEID_INFO:
|
||||
UNREACHABLE
|
||||
case EXPR_PTR_ACCESS:
|
||||
return sema_analyse_expr(context, expr->inner_expr);
|
||||
case EXPR_EXT_TRUNC:
|
||||
return sema_analyse_expr(context, expr->ext_trunc_expr.inner);
|
||||
case EXPR_SPLAT:
|
||||
|
||||
@@ -325,6 +325,7 @@ RETRY:
|
||||
case EXPR_FORCE_UNWRAP:
|
||||
case EXPR_RETHROW:
|
||||
case EXPR_OPTIONAL:
|
||||
case EXPR_PTR_ACCESS:
|
||||
expr = expr->inner_expr;
|
||||
goto RETRY;
|
||||
case EXPR_DEFAULT_ARG:
|
||||
|
||||
@@ -739,6 +739,7 @@ static inline bool sema_expr_valid_try_expression(Expr *expr)
|
||||
case EXPR_ASM:
|
||||
case EXPR_DEFAULT_ARG:
|
||||
case EXPR_EXT_TRUNC:
|
||||
case EXPR_PTR_ACCESS:
|
||||
return true;
|
||||
}
|
||||
UNREACHABLE
|
||||
@@ -1189,6 +1190,24 @@ static inline bool sema_analyse_expr_stmt(SemaContext *context, Ast *statement)
|
||||
if (!sema_expr_check_discard(context, expr)) return false;
|
||||
switch (expr->expr_kind)
|
||||
{
|
||||
case EXPR_RETHROW:
|
||||
if (expr->rethrow_expr.inner->expr_kind == EXPR_OPTIONAL)
|
||||
{
|
||||
context->active_scope.jump_end = true;
|
||||
}
|
||||
break;
|
||||
case EXPR_FORCE_UNWRAP:
|
||||
if (expr->inner_expr->expr_kind == EXPR_OPTIONAL)
|
||||
{
|
||||
context->active_scope.jump_end = true;
|
||||
}
|
||||
break;
|
||||
case EXPR_POST_UNARY:
|
||||
if (expr->rethrow_expr.inner->expr_kind == EXPR_OPTIONAL)
|
||||
{
|
||||
context->active_scope.jump_end = true;
|
||||
}
|
||||
break;
|
||||
case EXPR_CALL:
|
||||
if (expr->call_expr.no_return) context->active_scope.jump_end = true;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user