From 679275df8615740fcc1b1f8efb064ef0174e9d6d Mon Sep 17 00:00:00 2001 From: Martin Nowak Date: Tue, 4 Aug 2015 10:43:56 +0200 Subject: [PATCH] fix Issue 14828 - duplicate symbol __ModuleInfoZ - always emit __arrayZ/__assertZ/__unittest_failZ helpers (even in release) to avoid linkage issues when instantiating a template of that module with different compiler flags - also fixes Issue 14748 - Removing std.stdio import causes 2x increase in "Hello, world" same underlying issue, some undefined helper function drag in a different module which happens to have weak definitions of those helpers --- src/backend.d | 1 - src/glue.c | 35 ++++++------------- src/gluestub.c | 5 --- src/mars.c | 13 ------- src/template.c | 15 -------- .../link846a.d => extra-files/lib846.d} | 2 +- .../{link846.d => extra-files/main846.d} | 2 +- test/runnable/ice10857.d | 2 +- test/runnable/link846.sh | 25 +++++++++++++ 9 files changed, 39 insertions(+), 61 deletions(-) rename test/runnable/{imports/link846a.d => extra-files/lib846.d} (96%) rename test/runnable/{link846.d => extra-files/main846.d} (77%) create mode 100755 test/runnable/link846.sh diff --git a/src/backend.d b/src/backend.d index 898ba6796528..6627e6125e9c 100644 --- a/src/backend.d +++ b/src/backend.d @@ -25,7 +25,6 @@ extern extern (C++) void obj_write_deferred(Library library); extern extern (C++) Type getTypeInfoType(Type t, Scope* sc); extern extern (C++) Expression getInternalTypeInfo(Type t, Scope* sc); extern extern (C++) void genObjFile(Module m, bool multiobj); -extern extern (C++) void genhelpers(Module m, bool multiobj); extern extern (C++) Symbol* toInitializer(AggregateDeclaration sd); extern extern (C++) Symbol* toModuleArray(Module m); diff --git a/src/glue.c b/src/glue.c index 9d0647aa917a..2b7413e46099 100644 --- a/src/glue.c +++ b/src/glue.c @@ -60,7 +60,7 @@ Symbol *toModuleAssert(Module *m); Symbol *toModuleUnittest(Module *m); Symbol *toModuleArray(Module *m); Symbol *toSymbolX(Dsymbol *ds, const char *prefix, int sclass, type *t, const char *suffix); -void genhelpers(Module *m, bool iscomdat); +static void genhelpers(Module *m); elem *eictor; symbol *ictorlocalgot; @@ -475,34 +475,23 @@ void genObjFile(Module *m, bool multiobj) return; } - if (global.params.multiobj) - { - /* This is necessary because the main .obj for this module is written - * first, but determining whether marray or massert or munittest are needed is done - * possibly later in the doppelganger modules. - * Another way to fix it is do the main one last. - */ - toModuleAssert(m); - toModuleUnittest(m); - toModuleArray(m); - } - /* Always generate module info, because of templates and -cov. * But module info needs the runtime library, so disable it for betterC. */ if (!global.params.betterC /*|| needModuleInfo()*/) genModuleInfo(m); - genhelpers(m, false); + /* Always generate helper functions b/c of later templates instantiations + * with different -release/-debug/-boundscheck/-unittest flags. + */ + if (!global.params.betterC) + genhelpers(m); objmod->termfile(); } -void genhelpers(Module *m, bool iscomdat) +static void genhelpers(Module *m) { - if (global.params.betterC) - return; - // If module assert for (int i = 0; i < 3; i++) { @@ -511,9 +500,9 @@ void genhelpers(Module *m, bool iscomdat) unsigned bc; switch (i) { - case 0: ma = m->marray; rt = RTLSYM_DARRAY; bc = BCexit; break; - case 1: ma = m->massert; rt = RTLSYM_DASSERT; bc = BCexit; break; - case 2: ma = m->munittest; rt = RTLSYM_DUNITTEST; bc = BCret; break; + case 0: ma = toModuleArray(m); rt = RTLSYM_DARRAY; bc = BCexit; break; + case 1: ma = toModuleAssert(m); rt = RTLSYM_DASSERT; bc = BCexit; break; + case 2: ma = toModuleUnittest(m); rt = RTLSYM_DUNITTEST; bc = BCret; break; default: assert(0); } @@ -553,7 +542,7 @@ void genhelpers(Module *m, bool iscomdat) b->Belem = e; ma->Sfunc->Fstartline.Sfilename = m->arg; ma->Sfunc->Fstartblock = b; - ma->Sclass = iscomdat ? SCcomdat : SCglobal; + ma->Sclass = SCglobal; ma->Sfl = 0; ma->Sflags |= rtlsym[rt]->Sflags & SFLexit; writefunc(ma); @@ -1551,5 +1540,3 @@ elem *toEfilename(Module *m) // Turn static array into dynamic array return el_pair(TYdarray, el_long(TYsize_t, len), el_ptr(m->sfilename)); } - - diff --git a/src/gluestub.c b/src/gluestub.c index 1bfcbb90aa81..456c8d8c0670 100644 --- a/src/gluestub.c +++ b/src/gluestub.c @@ -60,11 +60,6 @@ void genObjFile(Module *m, bool multiobj) { } -void genhelpers(Module *m, bool iscomdat) -{ - assert(0); -} - // msc void backend_init() diff --git a/src/mars.c b/src/mars.c index 0041f6670b6a..7b2aa317597b 100644 --- a/src/mars.c +++ b/src/mars.c @@ -69,7 +69,6 @@ void updateRealEnvironment(StringTable *environment); void parseConfFile(StringTable *environment, const char *path, size_t len, unsigned char *buffer, Strings *sections); void genObjFile(Module *m, bool multiobj); -void genhelpers(Module *m, bool iscomdat); /** Normalize path by turning forward slashes into backslashes */ const char * toWinPath(const char *src) @@ -1674,12 +1673,6 @@ Language changes listed by -transition=id:\n\ if (entrypoint && m == rootHasMain) genObjFile(entrypoint, false); } - for (size_t i = 0; i < Module::amodules.dim; i++) - { - Module *m = Module::amodules[i]; - if (!m->isRoot() && (m->marray || m->massert || m->munittest)) - genhelpers(m, true); - } if (!global.errors && modules.dim) { obj_end(library, modules[0]->objfile); @@ -1697,12 +1690,6 @@ Language changes listed by -transition=id:\n\ genObjFile(m, global.params.multiobj); if (entrypoint && m == rootHasMain) genObjFile(entrypoint, global.params.multiobj); - for (size_t j = 0; j < Module::amodules.dim; j++) - { - Module *mx = Module::amodules[j]; - if (mx != m && mx->importedFrom == m && (mx->marray || mx->massert || mx->munittest)) - genhelpers(mx, true); - } obj_end(library, m->objfile); obj_write_deferred(library); diff --git a/src/template.c b/src/template.c index 42de24ee3768..58ef5d958c9e 100644 --- a/src/template.c +++ b/src/template.c @@ -46,11 +46,6 @@ unsigned char deduceWildHelper(Type *t, Type **at, Type *tparam); MATCH deduceTypeHelper(Type *t, Type **at, Type *tparam); void mangleToBuffer(Expression *e, OutBuffer *buf); -// Glue layer -Symbol *toModuleAssert(Module *m); -Symbol *toModuleUnittest(Module *m); -Symbol *toModuleArray(Module *m); - /******************************************** * These functions substitute for dynamic_cast. dynamic_cast does not work * on earlier versions of gcc. @@ -5912,16 +5907,6 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs) if (errors) goto Lerror; - if (Module *m = tempdecl->scope->module) // should use getModule() instead? - { - // Generate these functions as they may be used - // when template is instantiated in other modules - // even if assertions or bounds checking are disabled in this module - toModuleArray(m); - toModuleAssert(m); - toModuleUnittest(m); - } - /* See if there is an existing TemplateInstantiation that already * implements the typeargs. If so, just refer to that one instead. */ diff --git a/test/runnable/imports/link846a.d b/test/runnable/extra-files/lib846.d similarity index 96% rename from test/runnable/imports/link846a.d rename to test/runnable/extra-files/lib846.d index 1404d009ba26..65547765e22c 100644 --- a/test/runnable/imports/link846a.d +++ b/test/runnable/extra-files/lib846.d @@ -1,4 +1,4 @@ -module imports.link846a; +module link846a; template ElemTypeOf(T) { diff --git a/test/runnable/link846.d b/test/runnable/extra-files/main846.d similarity index 77% rename from test/runnable/link846.d rename to test/runnable/extra-files/main846.d index 2e92f836737e..d0b882ade2ba 100644 --- a/test/runnable/link846.d +++ b/test/runnable/extra-files/main846.d @@ -1,4 +1,4 @@ -import imports.link846a; +import lib846; void main() { diff --git a/test/runnable/ice10857.d b/test/runnable/ice10857.d index 4d08d2f36e05..d38351981ead 100644 --- a/test/runnable/ice10857.d +++ b/test/runnable/ice10857.d @@ -1,3 +1,3 @@ -// EXTRA_SOURCES: imports/ice10857b.d +// EXTRA_SOURCES: imports/ice10857a.d imports/ice10857b.d import imports.ice10857a; diff --git a/test/runnable/link846.sh b/test/runnable/link846.sh new file mode 100755 index 000000000000..2c612300e9d8 --- /dev/null +++ b/test/runnable/link846.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -e + +src=runnable${SEP}extra-files +dir=${RESULTS_DIR}${SEP}runnable +output_file=${dir}/link846.sh.out + +if [ $OS == "win32" -o $OS == "win64" ]; then + LIBEXT=.lib +else + LIBEXT=.a +fi +libname=${dir}${SEP}link846${LIBEXT} + +# build library with -release +$DMD -m${MODEL} -I${src} -of${libname} -release -boundscheck=off -lib ${src}${SEP}lib846.d + +# use lib with -debug +$DMD -m${MODEL} -I${src} -of${dir}${SEP}link846${EXE} -debug ${src}${SEP}main846.d ${libname} + +rm ${libname} +rm ${dir}/{link846${OBJ},link846${EXE}} + +echo Success > ${output_file}