diff --git a/src/build/build_options.c b/src/build/build_options.c index 646b14807..a4060b91f 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -409,7 +409,7 @@ static void print_version(void) #if LLVM_AVAILABLE PRINTF("LLVM version: %s", llvm_version); PRINTF("LLVM default target: %s", llvm_target); -#endif +#endif } static void parse_option(BuildOptions *options) diff --git a/src/compiler/c_codegen.c b/src/compiler/c_codegen.c index 06e2c0379..ed58176aa 100644 --- a/src/compiler/c_codegen.c +++ b/src/compiler/c_codegen.c @@ -396,6 +396,7 @@ static void c_emit_expr(GenContext *c, CValue *value, Expr *expr) switch (expr->expr_kind) { case EXPR_PTR_ACCESS: + case EXPR_RVALUE: case EXPR_EXT_TRUNC: case EXPR_MAKE_ANY: case EXPR_INT_TO_BOOL: diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 668c1278e..9f832bd29 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -3436,6 +3436,7 @@ static inline void expr_set_span(Expr *expr, SourceSpan loc) case EXPR_TYPECALL: case EXPR_MEMBER_GET: case EXPR_PTR_ACCESS: + case EXPR_RVALUE: break; } } @@ -3583,7 +3584,13 @@ INLINE Ast *ast_next(AstId *current_ptr) } - +INLINE void expr_rewrite_rvalue(Expr *expr, Type *type) +{ + Expr *inner = expr_copy(expr); + expr->expr_kind = EXPR_RVALUE; + expr->inner_expr = inner; + expr->type = type; +} INLINE void expr_rewrite_const_bool(Expr *expr, Type *type, bool b) { diff --git a/src/compiler/copying.c b/src/compiler/copying.c index dd84e6fb2..cbabdcb08 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -476,6 +476,7 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr) case EXPR_SPLAT: case EXPR_STRINGIFY: case EXPR_PTR_ACCESS: + case EXPR_RVALUE: MACRO_COPY_EXPR(expr->inner_expr); return expr; case EXPR_MAKE_ANY: diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 5c8a6c055..0ce25bb40 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -556,7 +556,6 @@ typedef enum CAST_INTFP, CAST_IDPTR, CAST_PTRBOOL, - CAST_PTRPTR, CAST_PTRINT, CAST_SLBOOL, CAST_SLSL, @@ -798,6 +797,7 @@ typedef enum EXPR_POST_UNARY, EXPR_RETHROW, EXPR_RETVAL, + EXPR_RVALUE, EXPR_SLICE, EXPR_SLICE_ASSIGN, EXPR_SLICE_COPY, diff --git a/src/compiler/expr.c b/src/compiler/expr.c index 4ce5f2767..d24765f89 100644 --- a/src/compiler/expr.c +++ b/src/compiler/expr.c @@ -83,6 +83,7 @@ bool expr_may_addr(Expr *expr) case EXPR_BENCHMARK_HOOK: case EXPR_TEST_HOOK: case EXPR_PTR_ACCESS: + case EXPR_RVALUE: return false; case NON_RUNTIME_EXPR: case EXPR_ASM: @@ -190,6 +191,8 @@ bool expr_is_runtime_const(Expr *expr) case EXPR_COND: case EXPR_PTR_ACCESS: return false; + case EXPR_RVALUE: + return expr_is_runtime_const(expr->inner_expr); case EXPR_MAKE_ANY: if (!expr_is_runtime_const(expr->make_any_expr.typeid)) return false; expr = expr->make_any_expr.inner; @@ -361,7 +364,6 @@ static inline bool expr_cast_is_runtime_const(Expr *expr) case CAST_ARRVEC: return exprid_is_runtime_const(expr->cast_expr.expr); case CAST_INTPTR: - case CAST_PTRPTR: case CAST_APTSA: case CAST_SLSL: case CAST_VOID: @@ -608,6 +610,7 @@ bool expr_is_pure(Expr *expr) case EXPR_MAKE_ANY: return expr_is_pure(expr->make_any_expr.inner) && expr_is_pure(expr->make_any_expr.typeid); case EXPR_PTR_ACCESS: + case EXPR_RVALUE: return expr_is_pure(expr->inner_expr); case EXPR_INT_TO_BOOL: return expr_is_pure(expr->int_to_bool_expr.inner); diff --git a/src/compiler/json_output.c b/src/compiler/json_output.c index 5b8ffbd19..47c652c8e 100644 --- a/src/compiler/json_output.c +++ b/src/compiler/json_output.c @@ -253,6 +253,11 @@ void print_var_expr(FILE *file, Expr *expr) fputs(".", file); print_var_expr(file, expr->access_expr.child); break; + case EXPR_RVALUE: + fputs("(", file); + print_var_expr(file, expr->access_expr.parent); + fputs(")", file); + break; case EXPR_PTR_ACCESS: print_var_expr(file, expr->access_expr.parent); fputs(".ptr", file); diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 61629ac31..aa44bfd80 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -1456,9 +1456,6 @@ void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *valu UNREACHABLE; case CAST_ERROR: UNREACHABLE - case CAST_PTRPTR: - llvm_value_rvalue(c, value); - break; case CAST_PTRINT: llvm_value_rvalue(c, value); value->value = LLVMBuildPtrToInt(c->builder, value->value, llvm_get_type(c, to_type), "ptrxi"); @@ -7328,6 +7325,11 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr) case EXPR_MAKE_ANY: llvm_emit_make_any(c, value, expr); return; + case EXPR_RVALUE: + llvm_emit_expr(c, value, expr->inner_expr); + llvm_value_rvalue(c, value); + value->type = type_lowering(expr->type); + return; case EXPR_PTR_ACCESS: llvm_emit_ptr_access(c, value, expr); return; diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index a67128e6c..a131aecf1 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -1505,12 +1505,9 @@ static void vector_const_initializer_convert_to_type(SemaContext *context, Const */ static void cast_ptr_to_ptr(SemaContext *context, Expr *expr, Type *type) { - if (insert_runtime_cast_unless_const(expr, CAST_PTRPTR, type)) return; - - // Strings cannot be compile-time folded, so insert a runtime cast. - if (expr->const_expr.const_kind == CONST_STRING) + if (!sema_cast_const(expr) || expr->const_expr.const_kind == CONST_STRING) { - insert_runtime_cast(expr, CAST_PTRPTR, type); + expr_rewrite_rvalue(expr, type); return; } @@ -1799,7 +1796,7 @@ static void cast_vec_to_vec(SemaContext *context, Expr *expr, Type *to_type) case TYPE_TYPEID: case TYPE_ANYFAULT: case TYPE_FAULTTYPE: - insert_runtime_cast(expr, CAST_PTRPTR, to_type); + expr_rewrite_rvalue(expr, to_type); return; default: UNREACHABLE; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index d62fdbdf6..36c015ccf 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -571,6 +571,7 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp case EXPR_MEMBER_GET: case EXPR_NAMED_ARGUMENT: case EXPR_PTR_ACCESS: + case EXPR_RVALUE: case EXPR_MAKE_ANY: goto ERR; } @@ -601,6 +602,7 @@ static bool expr_may_ref(Expr *expr) case EXPR_EXT_TRUNC: case EXPR_PTR_ACCESS: case EXPR_INT_TO_BOOL: + case EXPR_RVALUE: return false; case EXPR_OTHER_CONTEXT: return expr_may_ref(expr->expr_other_context.inner); @@ -5894,8 +5896,11 @@ static Type *defer_iptr_cast(Expr *maybe_pointer, Expr *maybe_diff) && maybe_pointer->cast_expr.kind == CAST_PTRINT && type_flatten(maybe_pointer->type) == type_flatten(type_iptr)) { + + Expr *inner = exprptr(maybe_pointer->cast_expr.expr); + maybe_pointer->expr_kind = EXPR_RVALUE; + maybe_pointer->inner_expr = inner; Type *cast_to_iptr = maybe_pointer->type; - maybe_pointer->cast_expr.kind = CAST_PTRPTR; maybe_pointer->type = type_get_ptr(type_char); return cast_to_iptr; } @@ -8951,6 +8956,7 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr case EXPR_EXT_TRUNC: case EXPR_INT_TO_BOOL: case EXPR_PTR_ACCESS: + case EXPR_RVALUE: case EXPR_MAKE_ANY: if (!sema_analyse_expr(active_context, main_expr)) return false; break; @@ -9332,6 +9338,8 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr, case EXPR_MAKE_ANY: if (!sema_analyse_expr(context, expr->make_any_expr.typeid)) return false; return sema_analyse_expr(context, expr->make_any_expr.inner); + case EXPR_RVALUE: + return sema_analyse_expr(context, expr->inner_expr); case EXPR_PTR_ACCESS: return sema_analyse_expr(context, expr->inner_expr); case EXPR_INT_TO_BOOL: diff --git a/src/compiler/sema_liveness.c b/src/compiler/sema_liveness.c index c1918ce1b..b6b7b8d7c 100644 --- a/src/compiler/sema_liveness.c +++ b/src/compiler/sema_liveness.c @@ -330,6 +330,7 @@ RETRY: case EXPR_RETHROW: case EXPR_OPTIONAL: case EXPR_PTR_ACCESS: + case EXPR_RVALUE: expr = expr->inner_expr; goto RETRY; case EXPR_DEFAULT_ARG: diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index b2e53d091..3d86db9d7 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -281,6 +281,9 @@ static inline Expr *sema_dive_into_expression(Expr *expr) { switch (expr->expr_kind) { + case EXPR_RVALUE: + expr = expr->inner_expr; + continue; case EXPR_MAKE_ANY: expr = expr->make_any_expr.inner; continue; @@ -760,6 +763,7 @@ static inline bool sema_expr_valid_try_expression(Expr *expr) case EXPR_EXT_TRUNC: case EXPR_INT_TO_BOOL: case EXPR_PTR_ACCESS: + case EXPR_RVALUE: return true; } UNREACHABLE