diff --git a/releasenotes.md b/releasenotes.md index 9c8bba03b..763d63385 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -5,6 +5,8 @@ ### Changes / improvements - Add `--custom-libc` option for custom libc implementations. +- Remove use of LLVMGetGlobalContext for single module compilation. +- Fixed bug where constants would get modified when slicing them. #2660 ### Fixes - Regression with npot vector in struct triggering an assert #2219. diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 6e4c7e9d9..43ad99d15 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -1556,7 +1556,7 @@ void **llvm_gen(Module** modules, unsigned module_count) llvm_codegen_setup(); if (compiler.build.single_module == SINGLE_MODULE_ON) { - LLVMContextRef context = LLVMGetGlobalContext(); + LLVMContextRef context = LLVMContextCreate(); for (int i = 0; i < module_count; i++) { GenContext *result = llvm_gen_module(modules[i], context); diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index d6c949403..3f514afa4 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -1765,7 +1765,7 @@ INLINE Expr **sema_splat_struct_insert(SemaContext *context, Expr **args, Expr * args[i + index] = expr; break; case CONST_INIT_VALUE: - expr = expr_copy(c->init_value); + expr = copy_expr_single(c->init_value); break; default: expr = expr_calloc(); @@ -2033,7 +2033,7 @@ INLINE bool sema_call_evaluate_arguments(SemaContext *context, CalledDecl *calle Expr *inner_new = inner; if (type_is_arraylike(inner->type)) { - inner_new = expr_copy(inner); + inner_new = copy_expr_single(inner); if (sema_cast_const(inner_new) && expr_is_const_initializer(inner_new)) { ConstInitializer *initializer = inner_new->const_expr.initializer; @@ -3621,7 +3621,7 @@ static inline bool sema_expr_analyse_typecall(SemaContext *context, Expr *expr) expr_rewrite_const_bool(expr, type_bool, true); return true; } - expr_replace(expr, expr_copy(value)); + expr_replace(expr, copy_expr_single(value)); return true; NOT_FOUND: if (is_has) @@ -3726,7 +3726,7 @@ static inline bool sema_call_analyse_member_get(SemaContext *context, Expr *expr // Constant fold the get if (target_kind == TYPE_ENUM && sema_cast_const(inner) && expr_is_const_enum(inner)) { - expr_replace(expr, expr_copy(inner->const_expr.enum_val->enum_constant.associated[index])); + expr_replace(expr, copy_expr_single(inner->const_expr.enum_val->enum_constant.associated[index])); return true; } expr->expr_kind = target_kind == TYPE_BITSTRUCT ? EXPR_BITACCESS : EXPR_ACCESS_RESOLVED; @@ -6270,7 +6270,7 @@ static inline void sema_expr_flatten_const_ident(Expr *expr) sema_expr_flatten_const_ident(init_expr); if (expr_is_const(init_expr)) { - expr_replace(expr, expr_copy(init_expr)); + expr_replace(expr, copy_expr_single(init_expr)); } } diff --git a/src/compiler/sema_initializers.c b/src/compiler/sema_initializers.c index fd5df5d36..3736bc42b 100644 --- a/src/compiler/sema_initializers.c +++ b/src/compiler/sema_initializers.c @@ -951,7 +951,7 @@ void const_init_rewrite_to_value(ConstInitializer *const_init, Expr *value) Decl *ident = decl_flatten(value->ident_expr); ASSERT(ident->decl_kind == DECL_VAR); ASSERT(ident->var.kind == VARDECL_CONST); - const_init_rewrite_to_value(const_init, expr_copy(ident->var.init_expr)); + const_init_rewrite_to_value(const_init, copy_expr_single(ident->var.init_expr)); return; } const_init->init_value = value; diff --git a/test/test_suite/arrays/slice_constant_mod.c3t b/test/test_suite/arrays/slice_constant_mod.c3t new file mode 100644 index 000000000..fc26a0c2a --- /dev/null +++ b/test/test_suite/arrays/slice_constant_mod.c3t @@ -0,0 +1,27 @@ +module my_module { GENNY }; +import std::io; + +const uint[5] H = { 1, 2, 3, 4, 5 }; + +macro void get(String to_print) +{ + uint[3] slice_thing; + io::printfn(to_print, GENNY); + $if GENNY != 1: + io::printn("not"); + $else + // !< PROBLEM LINES >! + slice_thing[:1] = H[:1]; + slice_thing[1:2] = H[3:2]; + // =================== + io::printn("is!"); + $endif +} + +module testing_branch; +import my_module; + +fn void main() +{ + my_module::get{1}("The %d string"); +} \ No newline at end of file diff --git a/test/test_suite/slices/various_const_slicing.c3t b/test/test_suite/slices/various_const_slicing.c3t index 090d1c1ff..d3d7a1975 100644 --- a/test/test_suite/slices/various_const_slicing.c3t +++ b/test/test_suite/slices/various_const_slicing.c3t @@ -33,7 +33,8 @@ fn int main() /* #expect: test.ll -@test.FOO = local_unnamed_addr constant [2 x i32] [i32 2, i32 3], align 16 + +@test.FOO = local_unnamed_addr constant [4 x i32] [i32 1, i32 2, i32 3, i32 4], align 16 @.__const_slice = private unnamed_addr global [2 x i32] [i32 2, i32 3], align 4 @test.y2 = local_unnamed_addr global %"int[]" { ptr @.__const_slice, i64 2 }, align 8 @.__const = private unnamed_addr constant [1 x i32] [i32 1], align 4 @@ -299,24 +300,31 @@ assign_optional71: ; preds = %noerr_block68 br label %guard_block73 after_check72: ; preds = %noerr_block68 br label %noerr_block74 + guard_block73: ; preds = %assign_optional71 br label %voiderr82 + noerr_block74: ; preds = %after_check72 %47 = call i64 @std.io.File.flush(ptr %36) %not_err76 = icmp eq i64 %47, 0 %48 = call i1 @llvm.expect.i1(i1 %not_err76, i1 true) br i1 %48, label %after_check78, label %assign_optional77 + assign_optional77: ; preds = %noerr_block74 store i64 %47, ptr %error_var75, align 8 br label %guard_block79 + after_check78: ; preds = %noerr_block74 br label %noerr_block80 + guard_block79: ; preds = %assign_optional77 br label %voiderr82 + noerr_block80: ; preds = %after_check78 %49 = load i64, ptr %len52, align 8 %add81 = add i64 %49, 1 br label %voiderr82 + voiderr82: ; preds = %noerr_block80, %guard_block79, %guard_block73, %guard_block67 call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal83, ptr align 4 @.__const.6, i32 12, i1 false) %50 = insertvalue %"int[]" undef, ptr %literal83, 0 @@ -339,13 +347,17 @@ voiderr82: ; preds = %noerr_block80, %gua %not_err96 = icmp eq i64 %58, 0 %59 = call i1 @llvm.expect.i1(i1 %not_err96, i1 true) br i1 %59, label %after_check98, label %assign_optional97 + assign_optional97: ; preds = %voiderr82 store i64 %58, ptr %error_var85, align 8 br label %guard_block99 + after_check98: ; preds = %voiderr82 br label %noerr_block100 + guard_block99: ; preds = %assign_optional97 br label %voiderr114 + noerr_block100: ; preds = %after_check98 %60 = load i64, ptr %retparam90, align 8 store i64 %60, ptr %len84, align 8 @@ -353,29 +365,38 @@ noerr_block100: ; preds = %after_check98 %not_err102 = icmp eq i64 %61, 0 %62 = call i1 @llvm.expect.i1(i1 %not_err102, i1 true) br i1 %62, label %after_check104, label %assign_optional103 + assign_optional103: ; preds = %noerr_block100 store i64 %61, ptr %error_var101, align 8 br label %guard_block105 + after_check104: ; preds = %noerr_block100 br label %noerr_block106 + guard_block105: ; preds = %assign_optional103 br label %voiderr114 + noerr_block106: ; preds = %after_check104 %63 = call i64 @std.io.File.flush(ptr %52) %not_err108 = icmp eq i64 %63, 0 %64 = call i1 @llvm.expect.i1(i1 %not_err108, i1 true) br i1 %64, label %after_check110, label %assign_optional109 + assign_optional109: ; preds = %noerr_block106 store i64 %63, ptr %error_var107, align 8 br label %guard_block111 + after_check110: ; preds = %noerr_block106 br label %noerr_block112 + guard_block111: ; preds = %assign_optional109 br label %voiderr114 + noerr_block112: ; preds = %after_check110 %65 = load i64, ptr %len84, align 8 %add113 = add i64 %65, 1 br label %voiderr114 + voiderr114: ; preds = %noerr_block112, %guard_block111, %guard_block105, %guard_block99 call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal115, ptr align 4 @.__const.8, i32 8, i1 false) call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x116, ptr align 4 %literal115, i32 8, i1 false) @@ -398,13 +419,17 @@ voiderr114: ; preds = %noerr_block112, %gu %not_err130 = icmp eq i64 %72, 0 %73 = call i1 @llvm.expect.i1(i1 %not_err130, i1 true) br i1 %73, label %after_check132, label %assign_optional131 + assign_optional131: ; preds = %voiderr114 store i64 %72, ptr %error_var119, align 8 br label %guard_block133 + after_check132: ; preds = %voiderr114 br label %noerr_block134 + guard_block133: ; preds = %assign_optional131 br label %voiderr148 + noerr_block134: ; preds = %after_check132 %74 = load i64, ptr %retparam124, align 8 store i64 %74, ptr %len118, align 8 @@ -412,29 +437,38 @@ noerr_block134: ; preds = %after_check132 %not_err136 = icmp eq i64 %75, 0 %76 = call i1 @llvm.expect.i1(i1 %not_err136, i1 true) br i1 %76, label %after_check138, label %assign_optional137 + assign_optional137: ; preds = %noerr_block134 store i64 %75, ptr %error_var135, align 8 br label %guard_block139 + after_check138: ; preds = %noerr_block134 br label %noerr_block140 + guard_block139: ; preds = %assign_optional137 br label %voiderr148 + noerr_block140: ; preds = %after_check138 %77 = call i64 @std.io.File.flush(ptr %66) %not_err142 = icmp eq i64 %77, 0 %78 = call i1 @llvm.expect.i1(i1 %not_err142, i1 true) br i1 %78, label %after_check144, label %assign_optional143 + assign_optional143: ; preds = %noerr_block140 store i64 %77, ptr %error_var141, align 8 br label %guard_block145 + after_check144: ; preds = %noerr_block140 br label %noerr_block146 + guard_block145: ; preds = %assign_optional143 br label %voiderr148 + noerr_block146: ; preds = %after_check144 %79 = load i64, ptr %len118, align 8 %add147 = add i64 %79, 1 br label %voiderr148 + voiderr148: ; preds = %noerr_block146, %guard_block145, %guard_block139, %guard_block133 %80 = call ptr @std.io.stdout() %81 = insertvalue %any undef, ptr %80, 0 @@ -454,13 +488,17 @@ voiderr148: ; preds = %noerr_block146, %gu %not_err161 = icmp eq i64 %86, 0 %87 = call i1 @llvm.expect.i1(i1 %not_err161, i1 true) br i1 %87, label %after_check163, label %assign_optional162 + assign_optional162: ; preds = %voiderr148 store i64 %86, ptr %error_var150, align 8 br label %guard_block164 + after_check163: ; preds = %voiderr148 br label %noerr_block165 + guard_block164: ; preds = %assign_optional162 br label %voiderr179 + noerr_block165: ; preds = %after_check163 %88 = load i64, ptr %retparam155, align 8 store i64 %88, ptr %len149, align 8 @@ -468,29 +506,38 @@ noerr_block165: ; preds = %after_check163 %not_err167 = icmp eq i64 %89, 0 %90 = call i1 @llvm.expect.i1(i1 %not_err167, i1 true) br i1 %90, label %after_check169, label %assign_optional168 + assign_optional168: ; preds = %noerr_block165 store i64 %89, ptr %error_var166, align 8 br label %guard_block170 + after_check169: ; preds = %noerr_block165 br label %noerr_block171 + guard_block170: ; preds = %assign_optional168 br label %voiderr179 + noerr_block171: ; preds = %after_check169 %91 = call i64 @std.io.File.flush(ptr %80) %not_err173 = icmp eq i64 %91, 0 %92 = call i1 @llvm.expect.i1(i1 %not_err173, i1 true) br i1 %92, label %after_check175, label %assign_optional174 + assign_optional174: ; preds = %noerr_block171 store i64 %91, ptr %error_var172, align 8 br label %guard_block176 + after_check175: ; preds = %noerr_block171 br label %noerr_block177 + guard_block176: ; preds = %assign_optional174 br label %voiderr179 + noerr_block177: ; preds = %after_check175 %93 = load i64, ptr %len149, align 8 %add178 = add i64 %93, 1 br label %voiderr179 + voiderr179: ; preds = %noerr_block177, %guard_block176, %guard_block170, %guard_block164 ret i32 0 }