Skip to content

Commit

Permalink
Fix bug where !! and ! was not recognized to jump out of the curr…
Browse files Browse the repository at this point in the history
…ent scope. Remove more casts.
  • Loading branch information
lerno committed Dec 30, 2024
1 parent 5af224a commit df74cbf
Show file tree
Hide file tree
Showing 12 changed files with 75 additions and 17 deletions.
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions src/compiler/c_codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
10 changes: 10 additions & 0 deletions src/compiler/compiler_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/compiler/copying.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 1 addition & 2 deletions src/compiler/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,6 @@ typedef enum

typedef enum
{
CAST_ANYPTR,
CAST_ANYBOOL,
CAST_APTSA,
CAST_ARRVEC,
Expand Down Expand Up @@ -562,7 +561,6 @@ typedef enum
CAST_PTRPTR,
CAST_PTRINT,
CAST_SLBOOL,
CAST_SAPTR,
CAST_SLSL,
CAST_SLARR,
CAST_STRPTR,
Expand Down Expand Up @@ -798,6 +796,7 @@ typedef enum
EXPR_OTHER_CONTEXT,
EXPR_POINTER_OFFSET,
EXPR_POISONED,
EXPR_PTR_ACCESS,
EXPR_POST_UNARY,
EXPR_RETHROW,
EXPR_RETVAL,
Expand Down
6 changes: 4 additions & 2 deletions src/compiler/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
6 changes: 5 additions & 1 deletion src/compiler/json_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
29 changes: 20 additions & 9 deletions src/compiler/llvm_codegen_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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));
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
9 changes: 7 additions & 2 deletions src/compiler/sema_casts.c
Original file line number Diff line number Diff line change
Expand Up @@ -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; }

Expand Down Expand Up @@ -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);
}

/**
Expand Down
6 changes: 5 additions & 1 deletion src/compiler/sema_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions src/compiler/sema_liveness.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ static void sema_trace_expr_liveness(Expr *expr)
case EXPR_FORCE_UNWRAP:
case EXPR_RETHROW:
case EXPR_OPTIONAL:
case EXPR_PTR_ACCESS:
expr = expr->inner_expr;
goto RETRY;
case EXPR_DEFAULT_ARG:
Expand Down
19 changes: 19 additions & 0 deletions src/compiler/sema_stmts.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit df74cbf

Please sign in to comment.