From cc75fe4fe5640ad16c64225d809636d391691f46 Mon Sep 17 00:00:00 2001 From: radare Date: Sat, 21 Mar 2020 12:24:34 +0100 Subject: [PATCH] builtin: Fix undefined behaviour when allocating empty structs (#4088) --- vlib/builtin/builtin.v | 3 +++ vlib/compiler/tests/struct_test.v | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/vlib/builtin/builtin.v b/vlib/builtin/builtin.v index da37a4f3ae..3d391a7748 100644 --- a/vlib/builtin/builtin.v +++ b/vlib/builtin/builtin.v @@ -177,6 +177,9 @@ pub fn free(ptr voidptr) { } pub fn memdup(src voidptr, sz int) voidptr { + if sz == 0 { + return vcalloc(1) + } mem := malloc(sz) return C.memcpy(mem, src, sz) } diff --git a/vlib/compiler/tests/struct_test.v b/vlib/compiler/tests/struct_test.v index 7769d538f3..5328c3379c 100644 --- a/vlib/compiler/tests/struct_test.v +++ b/vlib/compiler/tests/struct_test.v @@ -1,10 +1,10 @@ -struct A{ +struct A { mut: val int nums []int } -struct B{ +struct B { mut: a A } @@ -26,6 +26,9 @@ struct Foo { @type string } +struct Empty { +} + //We need to make sure that this compiles with all the reserved names. struct ReservedKeywords { delete int @@ -55,6 +58,12 @@ struct ReservedKeywords { while int } +fn test_empty_struct() { + d := &Empty{} + println(d) // != voidptr(0) + println(sizeof(Empty)) // == 0 +} + fn test_struct_levels() { mut c := C{} assert c.nums.len == 0