aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2025-11-11 21:08:11 +0000
committerGitHub <noreply@github.com>2025-11-11 21:08:11 +0000
commit33341c47a14911548433e42b14235351776c9f69 (patch)
treee1b3808878bf5d14332e9d196a6a0eba277e4a0d
parent68272c0c6cfa4585b723c9eecfe8bfe4bc109bc0 (diff)
parent6450459008ee02d00b4d9592763ccbd498acadfe (diff)
Merge pull request #5908 from slowhei/master
Fix allocation of anonymous globals
-rw-r--r--src/llvm_backend.cpp1
-rw-r--r--tests/internal/test_anonymous_globals.odin67
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,
+}