From 0bb16606a23851680c818a64e6bb69e6a8e6650e Mon Sep 17 00:00:00 2001 From: JinShil Date: Wed, 9 May 2018 11:27:16 +0900 Subject: [PATCH] Fix Issue 18828 - [-betterC] helpless error in object.d --- posix.mak | 2 +- src/object.d | 17 +++++++++++------ test/betterc/Makefile | 12 ++++++++++++ test/betterc/src/test18828.d | 10 ++++++++++ 4 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 test/betterc/Makefile create mode 100644 test/betterc/src/test18828.d diff --git a/posix.mak b/posix.mak index 901c810a35..6a9e3945ce 100644 --- a/posix.mak +++ b/posix.mak @@ -241,7 +241,7 @@ UT_MODULES:=$(patsubst src/%.d,$(ROOT)/unittest/%,$(SRCS)) HAS_ADDITIONAL_TESTS:=$(shell test -d test && echo 1) ifeq ($(HAS_ADDITIONAL_TESTS),1) ADDITIONAL_TESTS:=test/init_fini test/exceptions test/coverage test/profile test/cycles test/allocations test/typeinfo \ - test/thread test/unittest test/imports + test/thread test/unittest test/imports test/betterc ADDITIONAL_TESTS+=$(if $(SHARED),test/shared,) endif diff --git a/src/object.d b/src/object.d index fb4349eb24..534bdc0e1c 100644 --- a/src/object.d +++ b/src/object.d @@ -3027,14 +3027,19 @@ unittest /// ditto void destroy(T)(ref T obj) if (is(T == struct)) { + // We need to re-initialize `obj`. Previously, the code + // `auto init = cast(ubyte[])typeid(T).initializer()` was used, but + // `typeid` is a runtime call and requires the `TypeInfo` object which is + // not usable when compiling with -betterC. If we do `obj = T.init` then we + // end up needlessly calling postblits and destructors. So, we create a + // static immutable lvalue that can be re-used with subsequent calls to `destroy` + shared static immutable T init = T.init; + _destructRecurse(obj); () @trusted { - auto buf = (cast(ubyte*) &obj)[0 .. T.sizeof]; - auto init = cast(ubyte[])typeid(T).initializer(); - if (init.ptr is null) // null ptr means initialize to 0s - buf[] = 0; - else - buf[] = init[]; + auto dest = (cast(ubyte*) &obj)[0 .. T.sizeof]; + auto src = (cast(ubyte*) &init)[0 .. T.sizeof]; + dest[] = src[]; } (); } diff --git a/test/betterc/Makefile b/test/betterc/Makefile new file mode 100644 index 0000000000..f77dfa0510 --- /dev/null +++ b/test/betterc/Makefile @@ -0,0 +1,12 @@ +include ../common.mak + +TESTS:=test18828 + +.PHONY: all clean +all: $(addprefix $(ROOT)/,$(addsuffix ,$(TESTS))) + +$(ROOT)/%: $(SRC)/%.d + $(QUIET)$(DMD) -betterC -c -of$@ $< + +clean: + rm -rf $(ROOT) diff --git a/test/betterc/src/test18828.d b/test/betterc/src/test18828.d new file mode 100644 index 0000000000..44bc8c232d --- /dev/null +++ b/test/betterc/src/test18828.d @@ -0,0 +1,10 @@ +/*******************************************/ +// https://issues.dlang.org/show_bug.cgi?id=18828 + +struct S18828 { } + +void test18828() +{ + S18828 s; + destroy(s); +}