mirror of
https://github.com/odin-lang/Odin.git
synced 2026-07-20 14:41:09 +00:00
Fix allocation of anonymous globals
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
64
tests/internal/test_anonymous_globals.odin
Normal file
64
tests/internal/test_anonymous_globals.odin
Normal file
@@ -0,0 +1,64 @@
|
||||
package test_internal
|
||||
|
||||
import "core:testing"
|
||||
|
||||
|
||||
|
||||
@(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,
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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,
|
||||
}
|
||||
Reference in New Issue
Block a user