From 74890b1ec2abbb0bb26cc03055d3dbdf0e0014c0 Mon Sep 17 00:00:00 2001 From: k-hara Date: Thu, 4 Apr 2013 19:40:05 +0900 Subject: [PATCH 1/7] fix Issue 9346 - nested struct calls disabled postblit Move postblit call generation from glue layer to front-end layer. --- src/e2ir.c | 4 ++-- src/expression.c | 2 +- test/fail_compilation/fail9346.d | 28 ++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 test/fail_compilation/fail9346.d diff --git a/src/e2ir.c b/src/e2ir.c index 770c18924051..ffee72900039 100644 --- a/src/e2ir.c +++ b/src/e2ir.c @@ -5203,7 +5203,7 @@ elem *StructLiteralExp::toElem(IRState *irs) { if (t2b->implicitConvTo(t1b)) { -#if DMDV2 +#if 0 // Determine if postblit is needed int postblit = 0; if (needsPostblit(t1b)) @@ -5252,7 +5252,7 @@ elem *StructLiteralExp::toElem(IRState *irs) { e1->Eoper = OPstreq; e1->ET = v->type->toCtype(); } -#if DMDV2 +#if 0 /* Call postblit() on e1 */ StructDeclaration *sd = needsPostblit(v->type); diff --git a/src/expression.c b/src/expression.c index 0ec5c9941e93..aa94d506b7c6 100644 --- a/src/expression.c +++ b/src/expression.c @@ -4161,7 +4161,7 @@ Expression *StructLiteralExp::semantic(Scope *sc) if (e->op == TOKerror) return e; - (*elements)[i] = e; + (*elements)[i] = callCpCtor(e->loc, sc, e, 1); } /* Fill out remainder of elements[] with default initializers for fields[] diff --git a/test/fail_compilation/fail9346.d b/test/fail_compilation/fail9346.d new file mode 100644 index 000000000000..d3c7a593db27 --- /dev/null +++ b/test/fail_compilation/fail9346.d @@ -0,0 +1,28 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/fail9346.d(26): Error: struct fail9346.S is not copyable because it is annotated with @disable +fail_compilation/fail9346.d(27): Error: struct fail9346.S is not copyable because it is annotated with @disable +--- +*/ + +struct S +{ + @disable this(this); +} +struct SS1 +{ + S s; +} +struct SS2 +{ + S s; + this(this){} +} + +void main() +{ + S s; + SS1 ss1 = SS1(s); + SS2 ss2 = SS2(s); +} From b4ca1b038cb54d9ebd88bbeb6eaa917a42f5c31b Mon Sep 17 00:00:00 2001 From: k-hara Date: Fri, 22 Mar 2013 09:59:07 +0900 Subject: [PATCH 2/7] Move code for handling lvalue SliceExp to glue-layer. --- src/cast.c | 19 ++++--------------- src/e2ir.c | 11 ++++++++++- src/expression.c | 15 +++++++++++++++ src/expression.h | 2 ++ 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/cast.c b/src/cast.c index 070cc20e6105..6623844c574a 100644 --- a/src/cast.c +++ b/src/cast.c @@ -1809,22 +1809,11 @@ Expression *SliceExp::castTo(Scope *sc, Type *t) Expression *e; if (typeb->ty == Tarray && tb->ty == Tsarray) { - e = copy(); - - /* Rewrite: - * arr[lwr .. upr] - * as: - * *(cast(T[dim]*)(arr[lwr .. upr].ptr)) - * - * Note that: - * static assert(dim == upr - lwr); + /* If a SliceExp has Tsarray, it will become lvalue. + * That's handled in SliceExp::isLvalue and toLvalue */ - e = new DotIdExp(e->loc, e, Id::ptr); - e = e->semantic(sc); - e = e->castTo(sc, t->pointerTo()); - e = new PtrExp(e->loc, e); - e = e->semantic(sc); - //printf("e = %s, %s => %s %s\n", toChars(), type->toChars(), e->toChars(), e->type->toChars()); + e = copy(); + e->type = t; } else { diff --git a/src/e2ir.c b/src/e2ir.c index 770c18924051..0fc10825c506 100644 --- a/src/e2ir.c +++ b/src/e2ir.c @@ -4633,6 +4633,8 @@ elem *ArrayLengthExp::toElem(IRState *irs) elem *SliceExp::toElem(IRState *irs) { //printf("SliceExp::toElem()\n"); + Type *tb = type->toBasetype(); + assert(tb->ty == Tarray || tb->ty == Tsarray && lwr); Type *t1 = e1->type->toBasetype(); elem *e = e1->toElem(irs); if (lwr) @@ -4717,7 +4719,14 @@ elem *SliceExp::toElem(IRState *irs) elem *elength = el_bin(OPmin, TYsize_t, eupr, elwr2); eptr = el_bin(OPadd, TYnptr, eptr, el_bin(OPmul, TYsize_t, el_copytree(elwr2), el_long(TYsize_t, sz))); - e = el_pair(TYdarray, elength, eptr); + if (tb->ty == Tarray) + e = el_pair(TYdarray, elength, eptr); + else + { assert(tb->ty == Tsarray); + e = el_una(OPind, type->totym(), eptr); + if (tybasic(e->Ety) == TYstruct) + e->ET = type->toCtype(); + } e = el_combine(elwr, e); e = el_combine(einit, e); } diff --git a/src/expression.c b/src/expression.c index 2d6f08e07aa0..21c3d581a5f4 100644 --- a/src/expression.c +++ b/src/expression.c @@ -9617,6 +9617,21 @@ int SliceExp::checkModifiable(Scope *sc, int flag) return 1; } +int SliceExp::isLvalue() +{ + /* slice expression is rvalue in default, but + * conversion to reference of static array is only allowed. + */ + return (type && type->toBasetype()->ty == Tsarray); +} + +Expression *SliceExp::toLvalue(Scope *sc, Expression *e) +{ + //printf("SliceExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL); + return (type && type->toBasetype()->ty == Tsarray) + ? this : Expression::toLvalue(sc, e); +} + Expression *SliceExp::modifiableLvalue(Scope *sc, Expression *e) { error("slice expression %s is not a modifiable lvalue", toChars()); diff --git a/src/expression.h b/src/expression.h index 72f0e3ddf088..4dc237537a48 100644 --- a/src/expression.h +++ b/src/expression.h @@ -1146,6 +1146,8 @@ struct SliceExp : UnaExp void checkEscape(); void checkEscapeRef(); int checkModifiable(Scope *sc, int flag); + int isLvalue(); + Expression *toLvalue(Scope *sc, Expression *e); Expression *modifiableLvalue(Scope *sc, Expression *e); int isBool(int result); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); From 3021471e3600a01c8175389dbdde8238bb154332 Mon Sep 17 00:00:00 2001 From: k-hara Date: Fri, 5 Apr 2013 14:00:25 +0900 Subject: [PATCH 3/7] fix Issue 9880 - Redundant template instance displaying in error message --- src/template.c | 2 +- test/fail_compilation/diag9880.d | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test/fail_compilation/diag9880.d diff --git a/src/template.c b/src/template.c index 17dfd948838a..6c6821d12c12 100644 --- a/src/template.c +++ b/src/template.c @@ -5724,7 +5724,7 @@ bool TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs) errorSupplemental(loc, "while looking for match for %s", toChars()); else if (tempdecl && !tempdecl->overnext) // Only one template, so we can give better error message - error("%s does not match template declaration %s", toChars(), tempdecl->toChars()); + error("does not match template declaration %s", tempdecl->toChars()); else ::error(loc, "%s %s.%s does not match any template declaration", tempdecl->kind(), tempdecl->parent->toPrettyChars(), tempdecl->ident->toChars()); diff --git a/test/fail_compilation/diag9880.d b/test/fail_compilation/diag9880.d new file mode 100644 index 000000000000..a2703b2f88de --- /dev/null +++ b/test/fail_compilation/diag9880.d @@ -0,0 +1,9 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/diag9880.d(9): Error: template instance foo!(string) does not match template declaration foo(T)(int) if (is(T == int)) +--- +*/ + +void foo(T)(int) if (is(T == int)) {} +void main() { alias f = foo!string; } From d0b57424694b69fff531b8cb4d39b3f810790412 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Thu, 4 Apr 2013 21:14:50 -0700 Subject: [PATCH 4/7] don't pretend we found a match --- src/expression.c | 4 ++++ src/func.c | 14 ++++++++------ test/fail_compilation/diag9420.d | 3 +-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/expression.c b/src/expression.c index d64b5aa0d851..0146a550fba7 100644 --- a/src/expression.c +++ b/src/expression.c @@ -4735,6 +4735,8 @@ Expression *NewExp::semantic(Scope *sc) newargs->shift(e); f = resolveFuncCall(loc, sc, cd->aggNew, NULL, NULL, newargs); + if (!f) + goto Lerr; allocator = f->isNewDeclaration(); assert(allocator); @@ -4773,6 +4775,8 @@ Expression *NewExp::semantic(Scope *sc) newargs->shift(e); FuncDeclaration *f = resolveFuncCall(loc, sc, sd->aggNew, NULL, NULL, newargs); + if (!f) + goto Lerr; allocator = f->isNewDeclaration(); assert(allocator); diff --git a/src/func.c b/src/func.c index 29cb9bb3f122..8b008bb71687 100644 --- a/src/func.c +++ b/src/func.c @@ -2594,13 +2594,17 @@ FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Ex m.lastf->functionSemantic(); return m.lastf; } - else if (m.last != MATCHnomatch && (flags & 2) && !ethis && m.lastf->needThis()) + + if (m.last != MATCHnomatch && (flags & 2) && !ethis && m.lastf->needThis()) { return m.lastf; } - else if (m.last == MATCHnomatch && (flags & 1)) + + /* Failed to find a best match. + * Do nothing or print error. + */ + if (m.last == MATCHnomatch && (flags & 1)) { // if do not print error messages - return NULL; // no match } else { @@ -2635,8 +2639,6 @@ FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Ex tf->modToChars(), buf.toChars()); } - - return m.anyf; // as long as it's not a FuncAliasDeclaration } else { @@ -2647,9 +2649,9 @@ FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Ex buf.toChars(), m.lastf->loc.filename, m.lastf->loc.linnum, m.lastf->toPrettyChars(), Parameter::argsTypesToChars(t1->parameters, t1->varargs), m.nextf->loc.filename, m.nextf->loc.linnum, m.nextf->toPrettyChars(), Parameter::argsTypesToChars(t2->parameters, t2->varargs)); - return m.lastf; } } + return NULL; } /************************************* diff --git a/test/fail_compilation/diag9420.d b/test/fail_compilation/diag9420.d index 7c384d7dee50..dfaf7c84a09d 100644 --- a/test/fail_compilation/diag9420.d +++ b/test/fail_compilation/diag9420.d @@ -1,8 +1,7 @@ /* TEST_OUTPUT --- -fail_compilation/diag9420.d(21): Error: function diag9420.S.t3!().tx () is not callable using argument types (int) -fail_compilation/diag9420.d(21): Error: expected 0 arguments, not 1 for non-variadic function type pure nothrow @safe void() +fail_compilation/diag9420.d(20): Error: function diag9420.S.t3!().tx () is not callable using argument types (int) --- */ From 41d76380ac09cfac2641e0b320df453bf76d5ce6 Mon Sep 17 00:00:00 2001 From: Andrej Mitrovic Date: Thu, 4 Apr 2013 19:43:57 +0200 Subject: [PATCH 5/7] Refactor type implementation. --- src/mtype.c | 194 ++++++++++++---------------------------------------- src/mtype.h | 1 + 2 files changed, 46 insertions(+), 149 deletions(-) diff --git a/src/mtype.c b/src/mtype.c index 72916bcf6a1c..32acc4c66adb 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -308,6 +308,34 @@ Type *Type::trySemantic(Loc loc, Scope *sc) return t; } +/******************************** + * Return a copy of this type with all attributes null-initialized. + * Useful for creating a type with different modifiers. + */ + +Type *Type::nullAttributes() +{ + unsigned sz = sizeTy[ty]; + Type *t = (Type *)mem.malloc(sz); + memcpy(t, this, sz); + // t->mod = NULL; // leave mod unchanged + t->deco = NULL; + t->arrayof = NULL; + t->pto = NULL; + t->rto = NULL; + t->cto = NULL; + t->ito = NULL; + t->sto = NULL; + t->scto = NULL; + t->wto = NULL; + t->swto = NULL; + t->vtinfo = NULL; + t->ctype = NULL; + if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref; + if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref; + return t; +} + /******************************** * Convert to 'const'. */ @@ -458,23 +486,9 @@ Type *Type::unSharedOf() if (!t) { - unsigned sz = sizeTy[ty]; - t = (Type *)mem.malloc(sz); - memcpy(t, this, sz); + t = this->nullAttributes(); t->mod = mod & ~MODshared; - t->deco = NULL; - t->arrayof = NULL; - t->pto = NULL; - t->rto = NULL; - t->cto = NULL; - t->ito = NULL; - t->sto = NULL; - t->scto = NULL; - t->wto = NULL; - t->swto = NULL; - t->vtinfo = NULL; - if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref; - if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref; + t->ctype = ctype; t = t->merge(); t->fixTo(this); @@ -868,175 +882,57 @@ void Type::check() Type *Type::makeConst() { //printf("Type::makeConst() %p, %s\n", this, toChars()); - if (cto) - return cto; - unsigned sz = sizeTy[ty]; - Type *t = (Type *)mem.malloc(sz); - memcpy(t, this, sz); + if (cto) return cto; + Type *t = this->nullAttributes(); t->mod = MODconst; - t->deco = NULL; - t->arrayof = NULL; - t->pto = NULL; - t->rto = NULL; - t->cto = NULL; - t->ito = NULL; - t->sto = NULL; - t->scto = NULL; - t->wto = NULL; - t->swto = NULL; - t->vtinfo = NULL; - t->ctype = NULL; - if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref; - if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref; //printf("-Type::makeConst() %p, %s\n", t, toChars()); return t; } Type *Type::makeInvariant() { - if (ito) - return ito; - unsigned sz = sizeTy[ty]; - Type *t = (Type *)mem.malloc(sz); - memcpy(t, this, sz); + if (ito) return ito; + Type *t = this->nullAttributes(); t->mod = MODimmutable; - t->deco = NULL; - t->arrayof = NULL; - t->pto = NULL; - t->rto = NULL; - t->cto = NULL; - t->ito = NULL; - t->sto = NULL; - t->scto = NULL; - t->wto = NULL; - t->swto = NULL; - t->vtinfo = NULL; - t->ctype = NULL; - if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref; - if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref; return t; } Type *Type::makeShared() { - if (sto) - return sto; - unsigned sz = sizeTy[ty]; - Type *t = (Type *)mem.malloc(sz); - memcpy(t, this, sz); + if (sto) return sto; + Type *t = this->nullAttributes(); t->mod = MODshared; - t->deco = NULL; - t->arrayof = NULL; - t->pto = NULL; - t->rto = NULL; - t->cto = NULL; - t->ito = NULL; - t->sto = NULL; - t->scto = NULL; - t->wto = NULL; - t->swto = NULL; - t->vtinfo = NULL; - t->ctype = NULL; - if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref; - if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref; return t; } Type *Type::makeSharedConst() { - if (scto) - return scto; - unsigned sz = sizeTy[ty]; - Type *t = (Type *)mem.malloc(sz); - memcpy(t, this, sz); + if (scto) return scto; + Type *t = this->nullAttributes(); t->mod = MODshared | MODconst; - t->deco = NULL; - t->arrayof = NULL; - t->pto = NULL; - t->rto = NULL; - t->cto = NULL; - t->ito = NULL; - t->sto = NULL; - t->scto = NULL; - t->wto = NULL; - t->swto = NULL; - t->vtinfo = NULL; - t->ctype = NULL; - if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref; - if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref; return t; } Type *Type::makeWild() { - if (wto) - return wto; - unsigned sz = sizeTy[ty]; - Type *t = (Type *)mem.malloc(sz); - memcpy(t, this, sz); + if (wto) return wto; + Type *t = this->nullAttributes(); t->mod = MODwild; - t->deco = NULL; - t->arrayof = NULL; - t->pto = NULL; - t->rto = NULL; - t->cto = NULL; - t->ito = NULL; - t->sto = NULL; - t->scto = NULL; - t->wto = NULL; - t->swto = NULL; - t->vtinfo = NULL; - t->ctype = NULL; - if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref; - if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref; return t; } Type *Type::makeSharedWild() { - if (swto) - return swto; - unsigned sz = sizeTy[ty]; - Type *t = (Type *)mem.malloc(sz); - memcpy(t, this, sz); + if (swto) return swto; + Type *t = this->nullAttributes(); t->mod = MODshared | MODwild; - t->deco = NULL; - t->arrayof = NULL; - t->pto = NULL; - t->rto = NULL; - t->cto = NULL; - t->ito = NULL; - t->sto = NULL; - t->scto = NULL; - t->wto = NULL; - t->swto = NULL; - t->vtinfo = NULL; - t->ctype = NULL; - if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref; - if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref; return t; } Type *Type::makeMutable() { - unsigned sz = sizeTy[ty]; - Type *t = (Type *)mem.malloc(sz); - memcpy(t, this, sz); - t->mod = mod & MODshared; - t->deco = NULL; - t->arrayof = NULL; - t->pto = NULL; - t->rto = NULL; - t->cto = NULL; - t->ito = NULL; - t->sto = NULL; - t->scto = NULL; - t->wto = NULL; - t->swto = NULL; - t->vtinfo = NULL; - t->ctype = NULL; - if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref; - if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref; + Type *t = this->nullAttributes(); + t->mod = mod & MODshared; return t; } @@ -8490,7 +8386,7 @@ Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident) e = new DotTypeExp(0, e, sym); return e; } - + ClassDeclaration *cbase = sym->searchBase(e->loc, ident); if (cbase) { diff --git a/src/mtype.h b/src/mtype.h index da97cebdf2fd..3246e13e45ee 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -272,6 +272,7 @@ struct Type : Object int isWild() { return mod & MODwild; } int isSharedWild() { return mod == (MODshared | MODwild); } int isNaked() { return mod == 0; } + Type *nullAttributes(); Type *constOf(); Type *invariantOf(); Type *mutableOf(); From c29aaef47e0777c86ecf45d078e4d536981d4049 Mon Sep 17 00:00:00 2001 From: Andrej Mitrovic Date: Tue, 12 Mar 2013 00:53:13 +0100 Subject: [PATCH 6/7] Fixes Issue 9692 - allMembers trait should work on module without a package. --- src/traits.c | 7 ++++++- test/compilable/imports/test9692b.d | 2 ++ test/compilable/test9692.d | 7 +++++++ test/compilable/test9692a.d | 2 ++ 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 test/compilable/imports/test9692b.d create mode 100644 test/compilable/test9692.d create mode 100644 test/compilable/test9692a.d diff --git a/src/traits.c b/src/traits.c index c05fbcbd3ff0..ec13a360a4f7 100644 --- a/src/traits.c +++ b/src/traits.c @@ -458,7 +458,12 @@ Expression *TraitsExp::semantic(Scope *sc) error("argument has no members"); goto Lfalse; } - if ((sd = s->isScopeDsymbol()) == NULL) + Import *import; + if ((import = s->isImport()) != NULL) + { // Bugzilla 9692 + sd = import->mod; + } + else if ((sd = s->isScopeDsymbol()) == NULL) { error("%s %s has no members", s->kind(), s->toChars()); goto Lfalse; diff --git a/test/compilable/imports/test9692b.d b/test/compilable/imports/test9692b.d new file mode 100644 index 000000000000..25be84b3413c --- /dev/null +++ b/test/compilable/imports/test9692b.d @@ -0,0 +1,2 @@ +module imports.test9692b; +int j; diff --git a/test/compilable/test9692.d b/test/compilable/test9692.d new file mode 100644 index 000000000000..df76f1a06301 --- /dev/null +++ b/test/compilable/test9692.d @@ -0,0 +1,7 @@ +module test9692; + +import test9692a; +import imports.test9692b; + +enum x = __traits(allMembers, imports.test9692b); // ok +enum y = __traits(allMembers, test9692a); // ng: should work diff --git a/test/compilable/test9692a.d b/test/compilable/test9692a.d new file mode 100644 index 000000000000..6fd304b2d1ae --- /dev/null +++ b/test/compilable/test9692a.d @@ -0,0 +1,2 @@ +module test9692a; +int j; From 4ca8a034c89c7c2bc8fe083d3770c0d17a176fcc Mon Sep 17 00:00:00 2001 From: Andrej Mitrovic Date: Sun, 10 Mar 2013 06:45:14 +0100 Subject: [PATCH 7/7] Fixes Issue 9680 - Print main function and location in verbose mode. Add test-case script by Kenji Hara. --- src/func.c | 15 ++++++++++++ test/compilable/extra-files/test9680dllmain.d | 6 +++++ test/compilable/extra-files/test9680main.d | 1 + test/compilable/extra-files/test9680winmain.d | 6 +++++ test/compilable/test9680.sh | 23 +++++++++++++++++++ 5 files changed, 51 insertions(+) create mode 100644 test/compilable/extra-files/test9680dllmain.d create mode 100644 test/compilable/extra-files/test9680main.d create mode 100644 test/compilable/extra-files/test9680winmain.d create mode 100755 test/compilable/test9680.sh diff --git a/src/func.c b/src/func.c index 29cb9bb3f122..5ae5163235fb 100644 --- a/src/func.c +++ b/src/func.c @@ -830,6 +830,21 @@ void FuncDeclaration::semantic(Scope *sc) */ scope = new Scope(*sc); scope->setNoFree(); + + static bool printedMain = false; // semantic might run more than once + if (global.params.verbose && !printedMain) + { + const char *type = isMain() ? "main" : isWinMain() ? "winmain" : isDllMain() ? "dllmain" : NULL; + Module *mod = sc->module; + + if (type && mod) + { + printedMain = true; + const char *name = FileName::searchPath(global.path, mod->srcfile->toChars(), 1); + printf("%-10s%-10s\t%s\n", "entry", type, name); + } + } + return; } diff --git a/test/compilable/extra-files/test9680dllmain.d b/test/compilable/extra-files/test9680dllmain.d new file mode 100644 index 000000000000..bd388fafa94a --- /dev/null +++ b/test/compilable/extra-files/test9680dllmain.d @@ -0,0 +1,6 @@ +import core.sys.windows.windows; +extern (Windows) +BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved) +{ + return 0; +} diff --git a/test/compilable/extra-files/test9680main.d b/test/compilable/extra-files/test9680main.d new file mode 100644 index 000000000000..fe08d98e404c --- /dev/null +++ b/test/compilable/extra-files/test9680main.d @@ -0,0 +1 @@ +void main() { } diff --git a/test/compilable/extra-files/test9680winmain.d b/test/compilable/extra-files/test9680winmain.d new file mode 100644 index 000000000000..b92eefa28d0c --- /dev/null +++ b/test/compilable/extra-files/test9680winmain.d @@ -0,0 +1,6 @@ +import core.sys.windows.windows; +extern(Windows) +int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) +{ + return 0; +} diff --git a/test/compilable/test9680.sh b/test/compilable/test9680.sh new file mode 100755 index 000000000000..b5b0841a4ce4 --- /dev/null +++ b/test/compilable/test9680.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +name=`basename $0 .sh` +dir=${RESULTS_DIR}/compilable + +for kind in main winmain dllmain +do + file_name=${name}${kind} + src_file=compilable/extra-files/${file_name}.d + expect_file=compilable/extra-files/${file_name}.out + output_file=${dir}/${file_name}.out + + rm -f ${output_file}{,.2} + + $DMD -m${MODEL} -v -o- ${src_file} > ${output_file} + grep "^entry ${kind}" ${output_file} > ${output_file}.2 + if [ `wc -c ${output_file}.2 | while read a b; do echo $a; done` -eq 0 ]; then + echo "Error: not found expected entry point '${kind}' in ${src_file}" + exit 1; + fi + + rm ${output_file}.2 +done