diff --git a/lib/monomorph_tree.ml b/lib/monomorph_tree.ml index 40305d30..5f1f085b 100644 --- a/lib/monomorph_tree.ml +++ b/lib/monomorph_tree.ml @@ -1513,7 +1513,7 @@ and prep_let p id uniq e pass toplvl = let cnt = new_id constant_uniq_state in Hashtbl.add constant_tbl uniq (cnt, e1, toplvl); ({ p with vars = Vars.add un (Const uniq) p.vars }, Some uniq) - | { global = true; _ } | { const = true; _ } -> + | { global = true; _ } | { const = true; _ } when toplvl -> (* Globals are 'preallocated' at module level *) set_alloca p func.alloc; let uniq = Module.unique_name ~mname:p.mname id uniq in diff --git a/test/functions.t/run.t b/test/functions.t/run.t index 6d0905a1..c0a9da67 100644 --- a/test/functions.t/run.t +++ b/test/functions.t/run.t @@ -1425,7 +1425,6 @@ Don't copy mutable types in setup of tailrecursive functions %r = type { i64 } @schmu_rf = global %bref zeroinitializer, align 1 - @schmu_i = internal global i64 0, align 8 @0 = private unnamed_addr constant { i64, i64, [6 x i8] } { i64 5, i64 5, [6 x i8] c"false\00" } @1 = private unnamed_addr constant { i64, i64, [5 x i8] } { i64 4, i64 4, [5 x i8] c"true\00" } @2 = private unnamed_addr constant { i64, i64, [4 x i8] } { i64 3, i64 3, [4 x i8] c"%s\0A\00" } @@ -1763,22 +1762,24 @@ Don't copy mutable types in setup of tailrecursive functions %12 = load i64*, i64** %8, align 8 %13 = load i64, i64* %12, align 8 call void (i8*, ...) @printf(i8* getelementptr (i8, i8* bitcast ({ i64, i64, [5 x i8] }* @3 to i8*), i64 16), i64 %13) - call void @schmu_change-int(i64* @schmu_i, i64 0) - %14 = load i64, i64* @schmu_i, align 8 - call void (i8*, ...) @printf(i8* getelementptr (i8, i8* bitcast ({ i64, i64, [5 x i8] }* @3 to i8*), i64 16), i64 %14) - %15 = alloca i64*, align 8 - %16 = call i8* @malloc(i64 24) - %17 = bitcast i8* %16 to i64* - store i64* %17, i64** %15, align 8 - store i64 0, i64* %17, align 8 - %cap4 = getelementptr i64, i64* %17, i64 1 + %14 = alloca i64, align 8 + store i64 0, i64* %14, align 8 + call void @schmu_change-int(i64* %14, i64 0) + %15 = load i64, i64* %14, align 8 + call void (i8*, ...) @printf(i8* getelementptr (i8, i8* bitcast ({ i64, i64, [5 x i8] }* @3 to i8*), i64 16), i64 %15) + %16 = alloca i64*, align 8 + %17 = call i8* @malloc(i64 24) + %18 = bitcast i8* %17 to i64* + store i64* %18, i64** %16, align 8 + store i64 0, i64* %18, align 8 + %cap4 = getelementptr i64, i64* %18, i64 1 store i64 1, i64* %cap4, align 8 - %18 = getelementptr i8, i8* %16, i64 16 - call void @schmu_test(i64** %15, i64 0) - %19 = load i64*, i64** %15, align 8 - %20 = load i64, i64* %19, align 8 - call void (i8*, ...) @printf(i8* getelementptr (i8, i8* bitcast ({ i64, i64, [5 x i8] }* @3 to i8*), i64 16), i64 %20) - call void @__free_ai(i64** %15) + %19 = getelementptr i8, i8* %17, i64 16 + call void @schmu_test(i64** %16, i64 0) + %20 = load i64*, i64** %16, align 8 + %21 = load i64, i64* %20, align 8 + call void (i8*, ...) @printf(i8* getelementptr (i8, i8* bitcast ({ i64, i64, [5 x i8] }* @3 to i8*), i64 16), i64 %21) + call void @__free_ai(i64** %16) call void @__free_ai(i64** %8) ret i64 0 } diff --git a/test/mutable_value_semantics.t/mutable_locals.smu b/test/mutable_value_semantics.t/mutable_locals.smu new file mode 100644 index 00000000..bad6e97a --- /dev/null +++ b/test/mutable_value_semantics.t/mutable_locals.smu @@ -0,0 +1,6 @@ +(defn dont-be-global (_) + (let ((localmut& false)) + (print (fmt-str localmut)) + (if (not localmut) (set &localmut !true)))) + +(iter-range 0 3 dont-be-global) diff --git a/test/mutable_value_semantics.t/run.t b/test/mutable_value_semantics.t/run.t index 3bc5144b..abbb9da4 100644 --- a/test/mutable_value_semantics.t/run.t +++ b/test/mutable_value_semantics.t/run.t @@ -5,7 +5,6 @@ Test simple setting of mutable variables target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" @schmu_b = global i64 10, align 8 - @schmu_b__2 = internal global i64 10, align 8 @schmu_a = global i64** null, align 8 @schmu_b__3 = global i64** null, align 8 @schmu_c = global i64* null, align 8 @@ -13,7 +12,9 @@ Test simple setting of mutable variables define i64 @schmu_hmm() { entry: - store i64 15, i64* @schmu_b__2, align 8 + %0 = alloca i64, align 8 + store i64 10, i64* %0, align 8 + store i64 15, i64* %0, align 8 ret i64 15 } @@ -1377,11 +1378,11 @@ Fix codegen source_filename = "context" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" - @schmu_x = internal global i64 10, align 8 - define i64 @schmu_t() { entry: - store i64 11, i64* @schmu_x, align 8 + %0 = alloca i64, align 8 + store i64 10, i64* %0, align 8 + store i64 11, i64* %0, align 8 ret i64 11 } @@ -1415,3 +1416,9 @@ Track unmutated binding warnings across projections 8 | (defn testfn (a& [b& int]) ^^^^^^ +Mutable locals must not be globals even if constexpr + $ schmu mutable_locals.smu + $ ./mutable_locals + false + false + false