diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2025-11-11 21:08:11 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-11 21:08:11 +0000 |
| commit | 33341c47a14911548433e42b14235351776c9f69 (patch) | |
| tree | e1b3808878bf5d14332e9d196a6a0eba277e4a0d | |
| parent | 68272c0c6cfa4585b723c9eecfe8bfe4bc109bc0 (diff) | |
| parent | 6450459008ee02d00b4d9592763ccbd498acadfe (diff) | |
Merge pull request #5908 from slowhei/master
Fix allocation of anonymous globals
| -rw-r--r-- | src/llvm_backend.cpp | 1 | ||||
| -rw-r--r-- | tests/internal/test_anonymous_globals.odin | 67 |
2 files changed, 68 insertions, 0 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index d6bd7d72d..71bca42ab 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2090,6 +2090,7 @@ gb_internal void lb_create_startup_runtime_generate_body(lbModule *m, lbProcedur name = gb_string_append_length(name, ename.text, ename.len); lbProcedure *dummy = lb_create_dummy_procedure(m, make_string_c(name), dummy_type); + dummy->is_startup = true; LLVMSetVisibility(dummy->value, LLVMHiddenVisibility); LLVMSetLinkage(dummy->value, LLVMWeakAnyLinkage); diff --git a/tests/internal/test_anonymous_globals.odin b/tests/internal/test_anonymous_globals.odin new file mode 100644 index 000000000..fc214ebde --- /dev/null +++ b/tests/internal/test_anonymous_globals.odin @@ -0,0 +1,67 @@ +package test_internal + +import "core:testing" + + + +// https://github.com/odin-lang/Odin/pull/5908 +@(test) +test_address_of_anonymous_global :: proc(t: ^testing.T) { + // This loop exists so that we do more computation with stack memory + // This increases the likelihood of catching a bug where anonymous globals are incorrectly allocated on the stack + // instead of the data segment + for _ in 0..<10 { + testing.expect(t, global_variable.inner.field == 0xDEADBEEF) + } +} + +global_variable := Outer_Struct{ + inner = &Inner_Struct{ + field = 0xDEADBEEF, + }, +} +Outer_Struct :: struct{ + inner: ^Inner_Struct, + + // Must have a second field to prevent the compiler from simplifying the `Outer_Struct` type to `^Inner_Struct` + // ...I think? In any case, don't remove this field + _: int, +} +Inner_Struct :: struct{ + field: int, +} + + + +// https://github.com/odin-lang/Odin/pull/5908 +// +// Regression test for commit f1e3977cf94dfc0457f05d499cc280d8e1329086 where a larger anonymous global is needed to trigger +// the bug +@(test) +test_address_of_large_anonymous_global :: proc(t: ^testing.T) { + // This loop exists so that we do more computation with stack memory + // This increases the likelihood of catching a bug where anonymous globals are incorrectly allocated on the stack + // instead of the data segment + for _ in 0..<10 { + for i in 0..<8 { + testing.expect(t, global_variable_64.inner.field[i] == i) + } + } +} + +#assert(size_of(Inner_Struct_64) == 64) +global_variable_64 := Outer_Struct_64{ + inner = &Inner_Struct_64{ + field = [8]int{0, 1, 2, 3, 4, 5, 6, 7}, + }, +} +Outer_Struct_64 :: struct{ + inner: ^Inner_Struct_64, + + // Must have a second field to prevent the compiler from simplifying the `Outer_Struct` type to `^Inner_Struct` + // ...I think? In any case, don't remove this field + _: int, +} +Inner_Struct_64 :: struct{ + field: [8]int, +} |