diff options
Diffstat (limited to 'libgo/runtime/go-make-slice.c')
-rw-r--r-- | libgo/runtime/go-make-slice.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/libgo/runtime/go-make-slice.c b/libgo/runtime/go-make-slice.c index 242c9bb7268..591ab37e0c6 100644 --- a/libgo/runtime/go-make-slice.c +++ b/libgo/runtime/go-make-slice.c @@ -15,6 +15,11 @@ #include "arch.h" #include "malloc.h" +/* Dummy word to use as base pointer for make([]T, 0). + Since you cannot take the address of such a slice, + you can't tell that they all have the same base pointer. */ +uintptr runtime_zerobase; + struct __go_open_array __go_make_slice2 (const struct __go_type_descriptor *td, uintptr_t len, uintptr_t cap) @@ -24,7 +29,6 @@ __go_make_slice2 (const struct __go_type_descriptor *td, uintptr_t len, intgo icap; uintptr_t size; struct __go_open_array ret; - unsigned int flag; __go_assert (td->__code == GO_SLICE); std = (const struct __go_slice_type *) td; @@ -44,10 +48,19 @@ __go_make_slice2 (const struct __go_type_descriptor *td, uintptr_t len, ret.__capacity = icap; size = cap * std->__element_type->__size; - flag = ((std->__element_type->__code & GO_NO_POINTERS) != 0 - ? FlagNoPointers - : 0); - ret.__values = runtime_mallocgc (size, flag, 1, 1); + + if (size == 0) + ret.__values = &runtime_zerobase; + else if ((std->__element_type->__code & GO_NO_POINTERS) != 0) + ret.__values = runtime_mallocgc (size, FlagNoPointers, 1, 1); + else + { + ret.__values = runtime_mallocgc (size, 0, 1, 1); + + if (UseSpanType) + runtime_settype (ret.__values, + (uintptr) std->__element_type | TypeInfo_Array); + } return ret; } |