1 change: 0 additions & 1 deletion src/backend.d
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/cast.c
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,8 @@ MATCH implicitConvTo(Expression *e, Type *t)
for (size_t i = 0; i < e->arguments->dim; ++i)
{
Expression *earg = (*e->arguments)[i];
if (!earg) // Bugzilla 14853: if it's on overlapped field
continue;
Type *targ = earg->type->toBasetype();
#if LOG
printf("[%d] earg: %s, targ: %s\n", (int)i, earg->toChars(), targ->toChars());
Expand Down
14 changes: 14 additions & 0 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -11572,6 +11572,20 @@ Expression *AssignExp::semantic(Scope *sc)
if (e1x->checkPostblit(sc, t1))
return new ErrorExp();
}

// e2 matches to t1 because of the implicit length match, so
if (isUnaArrayOp(e2x->op) || isBinArrayOp(e2x->op))
{
// convert e1 to e1[]
// e.g. e1[] = a[] + b[];
e1x = new SliceExp(e1x->loc, e1x, NULL, NULL);
e1x = e1x->semantic(sc);
}
else
{
// convert e2 to t1 later
// e.g. e1 = [1, 2, 3];
}
}
else
{
Expand Down
35 changes: 11 additions & 24 deletions src/glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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++)
{
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1552,5 +1541,3 @@ elem *toEfilename(Module *m)
// Turn static array into dynamic array
return el_pair(TYdarray, el_long(TYsize_t, len), el_ptr(m->sfilename));
}


5 changes: 0 additions & 5 deletions src/gluestub.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,6 @@ void genObjFile(Module *m, bool multiobj)
{
}

void genhelpers(Module *m, bool iscomdat)
{
assert(0);
}

// msc

void backend_init()
Expand Down
13 changes: 0 additions & 13 deletions src/mars.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,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)
Expand Down Expand Up @@ -1677,12 +1676,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);
Expand All @@ -1700,12 +1693,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);

Expand Down
15 changes: 0 additions & 15 deletions src/template.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
*/
Expand Down
9 changes: 4 additions & 5 deletions src/traits.c
Original file line number Diff line number Diff line change
Expand Up @@ -945,19 +945,18 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
goto Ldimerror;
RootObject *o = (*e->args)[0];
Dsymbol *s = getDsymbol(o);
ScopeDsymbol *sds;
if (!s)
{
e->error("argument has no members");
goto Lfalse;
}
Import *import;
if ((import = s->isImport()) != NULL)
if (Import *imp = s->isImport())
{
// Bugzilla 9692
sds = import->mod;
s = imp->mod;
}
else if ((sds = s->isScopeDsymbol()) == NULL)
ScopeDsymbol *sds = s->isScopeDsymbol();
if (!sds || sds->isTemplateDeclaration())
{
e->error("%s %s has no members", s->kind(), s->toChars());
goto Lfalse;
Expand Down
21 changes: 21 additions & 0 deletions test/fail_compilation/ice14844.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
TEST_OUTPUT:
---
fail_compilation/ice14844.d(20): Error: template opDispatch(string name) has no members
---
*/

struct Typedef
{
template opDispatch(string name)
{
static if (true)
{
}
}
}

void runUnitTestsImpl()
{
auto x = [__traits(allMembers, Typedef.opDispatch)];
}
15 changes: 15 additions & 0 deletions test/runnable/arrayop.d
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,20 @@ void test14649()
assert(r == [('a'+'d'), ('b'+'e'), ('c'+'f')]);
}

/************************************************************************/
// 14851

void test14851()
{
int[8] a, b, c;

c = a[] | b[]; // OK <- NG from 2.068.0-b2
c = a[] ^ b[]; // OK <- NG from 2.068.0-b2

c[] = a[] | b[]; // OK
c[] = a[] ^ b[]; // OK
}

/************************************************************************/

int main()
Expand All @@ -905,6 +919,7 @@ int main()
test12780();
test13497();
test14649();
test14851();

printf("Success\n");
return 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module imports.link846a;
module link846a;

template ElemTypeOf(T)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import imports.link846a;
import lib846;

void main()
{
Expand Down
2 changes: 1 addition & 1 deletion test/runnable/ice10857.d
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// EXTRA_SOURCES: imports/ice10857b.d
// EXTRA_SOURCES: imports/ice10857a.d imports/ice10857b.d

import imports.ice10857a;
25 changes: 25 additions & 0 deletions test/runnable/link846.sh
Original file line number Diff line number Diff line change
@@ -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}
33 changes: 33 additions & 0 deletions test/runnable/xtest46.d
Original file line number Diff line number Diff line change
Expand Up @@ -7483,6 +7483,39 @@ class Outer14552
class Inner {}
}

/***************************************************/
// 14853

struct Queue14853(T)
{
struct Node
{
T mfPayload = T.init;
union
{
typeof(this)* mfPrev;
shared(typeof(this)*) mfShPrev;
}
union
{
typeof(this)* mfNext;
shared(typeof(this)*) mfShNext;
}
}

Node root;

void pfPut(T v, Node* r = null)
{
shared n = new Node(v); // problem!
}
}

void test14853()
{
auto b1 = new Queue14853!uint;
}

/***************************************************/

int main()
Expand Down