From: Iain Buclaw Date: Sun, 5 Jan 2025 13:24:49 +0000 (+0100) Subject: d: Merge upstream dmd, druntime 07bc5b9b3c, phobos de1dea109 X-Git-Tag: basepoints/gcc-16~2992 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a676a516701789730aa482bcef4adcb683ba0140;p=thirdparty%2Fgcc.git d: Merge upstream dmd, druntime 07bc5b9b3c, phobos de1dea109 Synchronizing with the upstream release of v2.109.0. D front-end changes: - Import dmd v2.109.0. D runtime changes: - Import druntime v2.109.0. Phobos changes: - Import phobos v2.109.0. gcc/d/ChangeLog: * decl.cc (DeclVisitor::finish_vtable): Update for new front-end interface. * dmd/MERGE: Merge upstream dmd 07bc5b9b3c. * dmd/VERSION: Bump version to v2.109.0. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 07bc5b9b3c. * src/MERGE: Merge upstream phobos de1dea109. --- diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc index 34953d862d65..fa9c429a7ce1 100644 --- a/gcc/d/decl.cc +++ b/gcc/d/decl.cc @@ -561,10 +561,8 @@ public: if (fd2->isFuture ()) continue; - if (FuncDeclaration::leastAsSpecialized (fd, fd2, NULL) - == MATCH::nomatch - && FuncDeclaration::leastAsSpecialized (fd2, fd, NULL) - == MATCH::nomatch) + if (dmd::leastAsSpecialized (fd, fd2, NULL) == MATCH::nomatch + && dmd::leastAsSpecialized (fd2, fd, NULL) == MATCH::nomatch) continue; /* Hiding detected; same name, overlapping specializations. */ diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 46d435ef8dba..77e8562abcc3 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -c11e1d1708646c9ac81ac2aafb57fa1ef5d289ad +07bc5b9b3c81cc0d4314e0040de981124b363ea5 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/README.md b/gcc/d/dmd/README.md index d784d07df213..baac0d79b30d 100644 --- a/gcc/d/dmd/README.md +++ b/gcc/d/dmd/README.md @@ -201,11 +201,9 @@ Note that these groups have no strict meaning, the category assignments are a bi | [libelf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libelf.d) | Library in ELF format (Unix) | | [libmach.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libmach.d) | Library in Mach-O format (macOS) | | [libmscoff.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libmscoff.d) | Library in COFF format (32/64-bit Windows) | -| [libomf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/libomf.d) | Library in OMF format (legacy 32-bit Windows) | | [scanelf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanelf.d) | Extract symbol names from a library in ELF format | | [scanmach.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanmach.d) | Extract symbol names from a library in Mach-O format | | [scanmscoff.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanmscoff.d) | Extract symbol names from a library in COFF format | -| [scanomf.d](https://github.com/dlang/dmd/blob/master/compiler/src/dmd/scanomf.d) | Extract symbol names from a library in OMF format | ### Code generation / back-end interfacing diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 99582f5e05fa..3d80c3d19134 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.108.1 +v2.109.0 diff --git a/gcc/d/dmd/cxxfrontend.d b/gcc/d/dmd/cxxfrontend.d index c0805b838ff9..403588b35e77 100644 --- a/gcc/d/dmd/cxxfrontend.d +++ b/gcc/d/dmd/cxxfrontend.d @@ -265,6 +265,12 @@ bool functionSemantic3(FuncDeclaration fd) return dmd.funcsem.functionSemantic3(fd); } +MATCH leastAsSpecialized(FuncDeclaration f, FuncDeclaration g, Identifiers* names) +{ + import dmd.funcsem; + return dmd.funcsem.leastAsSpecialized(f, g, names); +} + /*********************************************************** * hdrgen.d */ diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h index 998beba97dde..fdfe8a86a48b 100644 --- a/gcc/d/dmd/declaration.h +++ b/gcc/d/dmd/declaration.h @@ -34,6 +34,7 @@ namespace dmd { bool functionSemantic(FuncDeclaration* fd); bool functionSemantic3(FuncDeclaration* fd); + MATCH leastAsSpecialized(FuncDeclaration *f, FuncDeclaration *g, Identifiers *names); } //enum STC : ulong from astenums.d: @@ -706,7 +707,6 @@ public: bool overloadInsert(Dsymbol *s) override; bool inUnittest(); - static MATCH leastAsSpecialized(FuncDeclaration *f, FuncDeclaration *g, Identifiers *names); LabelDsymbol *searchLabel(Identifier *ident, const Loc &loc); const char *toPrettyChars(bool QualifyTypes = false) override; const char *toFullSignature(); // for diagnostics, e.g. 'int foo(int x, int y) pure' diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index a1a337bd3a52..005f1c9d0e29 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -766,7 +766,7 @@ extern (C++) final class Module : Package { filetype = FileType.c; - global.compileEnv.masm = target.os == Target.OS.Windows && !target.omfobj; // Microsoft inline assembler format + global.compileEnv.masm = target.os == Target.OS.Windows; // Microsoft inline assembler format scope p = new CParser!AST(this, buf, cast(bool) docfile, global.errorSink, target.c, &defines, &global.compileEnv); global.compileEnv.masm = false; p.nextToken(); diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d index 339b22323af1..416bd57f24bb 100644 --- a/gcc/d/dmd/dstruct.d +++ b/gcc/d/dmd/dstruct.d @@ -320,11 +320,6 @@ extern (C++) class StructDeclaration : AggregateDeclaration */ structsize = 4; } - else if (target.c.bitFieldStyle == TargetC.BitFieldStyle.DM) - { - structsize = 0; - alignsize = 0; - } else structsize = 0; break; diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 65a1b0436502..4a21b1473423 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -7259,25 +7259,6 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor return; } } - else if (style == TargetC.BitFieldStyle.DM) - { - if (anon && bfd.fieldWidth && (!fieldState.inFlight || fieldState.bitOffset == 0)) - return; // this probably should be a bug in DMC - if (ad.alignsize == 0) - ad.alignsize = 1; - if (bfd.fieldWidth == 0) - { - if (fieldState.inFlight && !isunion) - { - const alsz = memsize; - fieldState.offset = (fieldState.offset + alsz - 1) & ~(alsz - 1); - ad.structsize = fieldState.offset; - } - - fieldState.inFlight = false; - return; - } - } if (!fieldState.inFlight) { @@ -7307,8 +7288,7 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor } } } - else if (style == TargetC.BitFieldStyle.DM || - style == TargetC.BitFieldStyle.MS) + else if (style == TargetC.BitFieldStyle.MS) { if (memsize != fieldState.fieldSize || fieldState.bitOffset + bfd.fieldWidth > fieldState.fieldSize * 8) diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index fb11821f42cf..33ec6b1849f6 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -751,6 +751,17 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol return buf.extractChars(); } + /**************************** + * Similar to `toChars`, but does not print the template constraints + */ + const(char)* toCharsNoConstraints() const + { + HdrGenState hgs = { skipConstraints: true }; + OutBuffer buf; + toCharsMaybeConstraints(this, buf, hgs); + return buf.extractChars(); + } + override Visibility visible() pure nothrow @nogc @safe { return visibility; diff --git a/gcc/d/dmd/enumsem.d b/gcc/d/dmd/enumsem.d index 3886ca25e97b..c67ac618ec3e 100644 --- a/gcc/d/dmd/enumsem.d +++ b/gcc/d/dmd/enumsem.d @@ -325,7 +325,10 @@ void enumSemantic(Scope* sc, EnumDeclaration ed) if (EnumMember em = s.isEnumMember()) { em.type = commonType; - em.value = em.value.castTo(sc, commonType); + // optimize out the cast so that other parts of the compiler can + // assume that an integral enum's members are `IntegerExp`s. + // https://issues.dlang.org/show_bug.cgi?id=24504 + em.value = em.value.castTo(sc, commonType).optimize(WANTvalue); } }); } diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index 1ff6c4c863e4..ad792817c1b9 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -889,6 +889,7 @@ public: // Possible to cast to one type while painting to another type Type *to; // type to cast to unsigned char mod; // MODxxxxx + d_bool trusted; // assume cast is safe CastExp *syntaxCopy() override; bool isLvalue() override; diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 3502a1cecf79..481806d392bd 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -14306,14 +14306,16 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc) if (auto te = exp.e1.isTupleExp()) { - if (exp.ident == Id.offsetof) + if (exp.ident == Id.offsetof || + exp.ident == Id.bitoffsetof || + exp.ident == Id.bitwidth) { /* 'distribute' the .offsetof to each of the tuple elements. */ auto exps = new Expressions(te.exps.length); foreach (i, e; (*te.exps)[]) { - (*exps)[i] = new DotIdExp(e.loc, e, Id.offsetof); + (*exps)[i] = new DotIdExp(e.loc, e, exp.ident); } // Don't evaluate te.e0 in runtime Expression e = new TupleExp(exp.loc, null, exps); @@ -14636,6 +14638,8 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag) !cfile && (exp.ident == Id._mangleof || exp.ident == Id.offsetof || + exp.ident == Id.bitoffsetof || + exp.ident == Id.bitwidth || exp.ident == Id._init || exp.ident == Id.stringof) )) @@ -15282,6 +15286,9 @@ Expression resolveLoc(Expression exp, const ref Loc loc, Scope* sc) Expression visitStructLiteral(StructLiteralExp exp) { + if (!exp.elements) + return exp; + foreach (ref element; *exp.elements) { if (element) @@ -15300,6 +15307,9 @@ Expression resolveLoc(Expression exp, const ref Loc loc, Scope* sc) if (exp.lowering) exp.lowering = exp.lowering.resolveLoc(loc, sc); + if (!exp.arguments) + return exp; + foreach (ref element; *exp.arguments) { if (element) @@ -15311,6 +15321,9 @@ Expression resolveLoc(Expression exp, const ref Loc loc, Scope* sc) Expression visitCall(CallExp exp) { + if (!exp.arguments) + return exp; + foreach (ref element; *exp.arguments) { if (element) @@ -15324,6 +15337,9 @@ Expression resolveLoc(Expression exp, const ref Loc loc, Scope* sc) { exp.e1 = exp.e1.resolveLoc(loc, sc); + if (!exp.arguments) + return exp; + foreach (ref element; *exp.arguments) { if (element) @@ -15357,6 +15373,9 @@ Expression resolveLoc(Expression exp, const ref Loc loc, Scope* sc) if (exp.basis) exp.basis = exp.basis.resolveLoc(loc, sc); + if (!exp.elements) + return exp; + foreach (ref element; *exp.elements) { if (element) diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index f3d7aba26ba6..cb19b14dfb41 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -423,27 +423,6 @@ extern (C++) class FuncDeclaration : Declaration return false; } - /**************************************************** - * Determine if 'this' overrides fd. - * Return !=0 if it does. - */ - extern (D) final int overrides(FuncDeclaration fd) - { - int result = 0; - if (fd.ident == ident) - { - const cov = type.covariant(fd.type); - if (cov != Covariant.distinct) - { - ClassDeclaration cd1 = toParent().isClassDeclaration(); - ClassDeclaration cd2 = fd.toParent().isClassDeclaration(); - if (cd1 && cd2 && cd2.isBaseOf(cd1, null)) - result = 1; - } - } - return result; - } - /**************************************************** * Overload this FuncDeclaration with the new one f. * Return true if successful; i.e. no conflict. @@ -547,91 +526,6 @@ extern (C++) class FuncDeclaration : Declaration return false; } - /************************************* - * Determine partial specialization order of functions `f` vs `g`. - * This is very similar to TemplateDeclaration::leastAsSpecialized(). - * Params: - * f = first function - * g = second function - * names = names of parameters - * Returns: - * match 'this' is at least as specialized as g - * 0 g is more specialized than 'this' - */ - static MATCH leastAsSpecialized(FuncDeclaration f, FuncDeclaration g, Identifiers* names) - { - enum LOG_LEASTAS = 0; - static if (LOG_LEASTAS) - { - import core.stdc.stdio : printf; - printf("leastAsSpecialized(%s, %s, %s)\n", f.toChars(), g.toChars(), names ? names.toChars() : "null"); - printf("%s, %s\n", f.type.toChars(), g.type.toChars()); - } - - /* This works by calling g() with f()'s parameters, and - * if that is possible, then f() is at least as specialized - * as g() is. - */ - - TypeFunction tf = f.type.toTypeFunction(); - TypeFunction tg = g.type.toTypeFunction(); - - /* If both functions have a 'this' pointer, and the mods are not - * the same and g's is not const, then this is less specialized. - */ - if (f.needThis() && g.needThis() && tf.mod != tg.mod) - { - if (f.isCtorDeclaration()) - { - if (!MODimplicitConv(tg.mod, tf.mod)) - return MATCH.nomatch; - } - else - { - if (!MODimplicitConv(tf.mod, tg.mod)) - return MATCH.nomatch; - } - } - - /* Create a dummy array of arguments out of the parameters to f() - */ - Expressions args; - foreach (u, p; tf.parameterList) - { - Expression e; - if (p.isReference()) - { - e = new IdentifierExp(Loc.initial, p.ident); - e.type = p.type; - } - else - e = p.type.defaultInitLiteral(Loc.initial); - args.push(e); - } - - MATCH m = tg.callMatch(null, ArgumentList(&args, names), 1); - if (m > MATCH.nomatch) - { - /* A variadic parameter list is less specialized than a - * non-variadic one. - */ - if (tf.parameterList.varargs && !tg.parameterList.varargs) - goto L1; // less specialized - - static if (LOG_LEASTAS) - { - printf(" matches %d, so is least as specialized\n", m); - } - return m; - } - L1: - static if (LOG_LEASTAS) - { - printf(" doesn't match, so is not as specialized\n"); - } - return MATCH.nomatch; - } - /******************************** * Searches for a label with the given identifier. This function will insert a new * `LabelDsymbol` into `labtab` if it does not contain a mapping for `ident`. @@ -1607,27 +1501,6 @@ extern (C++) class FuncDeclaration : Declaration return false; } - /**************************************************** - * Determine whether an 'out' contract is declared inside - * the given function or any of its overrides. - * Params: - * fd = the function to search - * Returns: - * true found an 'out' contract - */ - static bool needsFensure(FuncDeclaration fd) @safe - { - if (fd.fensures) - return true; - - foreach (fdv; fd.foverrides) - { - if (needsFensure(fdv)) - return true; - } - return false; - } - /********************************************* * Returns: the function's parameter list, and whether * it is variadic or not. @@ -1684,179 +1557,6 @@ extern (C++) class FuncDeclaration : Declaration return fd; } - /+ - + Checks the parameter and return types iff this is a `main` function. - + - + The following signatures are allowed for a `D main`: - + - Either no or a single parameter of type `string[]` - + - Return type is either `void`, `int` or `noreturn` - + - + The following signatures are standard C: - + - `int main()` - + - `int main(int, char**)` - + - + This function accepts the following non-standard extensions: - + - `char** envp` as a third parameter - + - `void` / `noreturn` as return type - + - + This function will issue errors for unexpected arguments / return types. - +/ - extern (D) final void checkMain() - { - if (ident != Id.main || isMember() || isNested()) - return; // Not a main function - - TypeFunction tf = type.toTypeFunction(); - - Type retType = tf.nextOf(); - if (!retType) - { - // auto main(), check after semantic - assert(this.inferRetType); - return; - } - - /// Checks whether `t` is equivalent to `char**` - /// Ignores qualifiers and treats enums according to their base type - static bool isCharPtrPtr(Type t) - { - auto tp = t.toBasetype().isTypePointer(); - if (!tp) - return false; - - tp = tp.next.toBasetype().isTypePointer(); - if (!tp) - return false; - - return tp.next.toBasetype().ty == Tchar; - } - - // Neither of these qualifiers is allowed because they affect the ABI - enum invalidSTC = STC.out_ | STC.ref_ | STC.lazy_; - - const nparams = tf.parameterList.length; - bool argerr; - - const linkage = resolvedLinkage(); - if (linkage == LINK.d) - { - if (nparams == 1) - { - auto fparam0 = tf.parameterList[0]; - auto t = fparam0.type.toBasetype(); - if (t.ty != Tarray || - t.nextOf().ty != Tarray || - t.nextOf().nextOf().ty != Tchar || - fparam0.storageClass & invalidSTC) - { - argerr = true; - } - } - - if (tf.parameterList.varargs || nparams >= 2 || argerr) - .error(loc, "%s `%s` parameter list must be empty or accept one parameter of type `string[]`", kind, toPrettyChars); - } - - else if (linkage == LINK.c) - { - if (nparams == 2 || nparams == 3) - { - // Argument count must be int - auto argCount = tf.parameterList[0]; - argerr |= !!(argCount.storageClass & invalidSTC); - argerr |= argCount.type.toBasetype().ty != Tint32; - - // Argument pointer must be char** - auto argPtr = tf.parameterList[1]; - argerr |= !!(argPtr.storageClass & invalidSTC); - argerr |= !isCharPtrPtr(argPtr.type); - - // `char** environ` is a common extension, see J.5.1 of the C standard - if (nparams == 3) - { - auto envPtr = tf.parameterList[2]; - argerr |= !!(envPtr.storageClass & invalidSTC); - argerr |= !isCharPtrPtr(envPtr.type); - } - } - else - argerr = nparams != 0; - - // Disallow variadic main() - except for K&R declarations in C files. - // E.g. int main(), int main(argc, argv) int argc, char** argc { ... } - if (tf.parameterList.varargs && (!this.isCsymbol() || (!tf.parameterList.hasIdentifierList && nparams))) - argerr |= true; - - if (argerr) - { - .error(loc, "%s `%s` parameters must match one of the following signatures", kind, toPrettyChars); - loc.errorSupplemental("`main()`"); - loc.errorSupplemental("`main(int argc, char** argv)`"); - loc.errorSupplemental("`main(int argc, char** argv, char** environ)` [POSIX extension]"); - } - } - else - return; // Neither C nor D main, ignore (should probably be an error) - - // Allow enums with appropriate base types (same ABI) - retType = retType.toBasetype(); - - if (retType.ty != Tint32 && retType.ty != Tvoid && retType.ty != Tnoreturn) - .error(loc, "%s `%s` must return `int`, `void` or `noreturn`, not `%s`", kind, toPrettyChars, tf.nextOf().toChars()); - } - - /*********************************************** - * Check all return statements for a function to verify that returning - * using NRVO is possible. - * - * Returns: - * `false` if the result cannot be returned by hidden reference. - */ - extern (D) final bool checkNRVO() - { - if (!isNRVO() || returns is null) - return false; - - auto tf = type.toTypeFunction(); - if (tf.isref) - return false; - - foreach (rs; *returns) - { - if (auto ve = rs.exp.isVarExp()) - { - auto v = ve.var.isVarDeclaration(); - if (!v || v.isReference()) - return false; - else if (nrvo_var is null) - { - // Variables in the data segment (e.g. globals, TLS or not), - // parameters and closure variables cannot be NRVOed. - if (v.isDataseg() || v.isParameter() || v.toParent2() != this) - return false; - if (v.nestedrefs.length && needsClosure()) - return false; - // don't know if the return storage is aligned - version (MARS) - { - if (alignSectionVars && (*alignSectionVars).contains(v)) - return false; - } - // The variable type needs to be equivalent to the return type. - if (!v.type.equivalent(tf.next)) - return false; - //printf("Setting nrvo to %s\n", v.toChars()); - nrvo_var = v; - } - else if (nrvo_var != v) - return false; - } - else //if (!exp.isLvalue()) // keep NRVO-ability - return false; - } - return true; - } - override final inout(FuncDeclaration) isFuncDeclaration() inout { return this; @@ -2066,23 +1766,6 @@ unittest assert(mismatches.isMutable); } -/************************************** - * Returns an indirect type one step from t. - */ -Type getIndirection(Type t) -{ - t = t.baseElemOf(); - if (t.ty == Tarray || t.ty == Tpointer) - return t.nextOf().toBasetype(); - if (t.ty == Taarray || t.ty == Tclass) - return t; - if (t.ty == Tstruct) - return t.hasPointers() ? t : null; // TODO - - // should consider TypeDelegate? - return null; -} - /************************************** * Performs type-based alias analysis between a newly created value and a pre- * existing memory reference: diff --git a/gcc/d/dmd/funcsem.d b/gcc/d/dmd/funcsem.d index e058deb0f94d..ee36a165d62c 100644 --- a/gcc/d/dmd/funcsem.d +++ b/gcc/d/dmd/funcsem.d @@ -65,6 +65,10 @@ import dmd.tokens; import dmd.typesem; import dmd.visitor; +version (IN_GCC) {} +else version (IN_LLVM) {} +else version = MARS; + /* Tweak all return statements and dtor call for nrvo_var, for correct NRVO. */ extern (C++) final class NrvoWalker : StatementRewriteWalker @@ -742,7 +746,10 @@ void funcDeclarationSemantic(Scope* sc, FuncDeclaration funcdecl) { if (fdv.isFuture()) { - deprecation(funcdecl.loc, "`@__future` base class method `%s` is being overridden by `%s`; rename the latter", fdv.toPrettyChars(), funcdecl.toPrettyChars()); + deprecation(funcdecl.loc, "method `%s` implicitly overrides `@__future` base class method; rename the former", + funcdecl.toPrettyChars()); + deprecationSupplemental(fdv.loc, "base method `%s` defined here", + fdv.toPrettyChars()); // Treat 'this' as an introducing function, giving it a separate hierarchy in the vtbl[] goto Lintro; } @@ -1743,10 +1750,24 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration)) // max num of overloads to print (-v or -verror-supplements overrides this). const uint DisplayLimit = global.params.v.errorSupplementCount(); const(char)* constraintsTip; - // determine if the first candidate was printed - int printed; - bool matchSymbol(Dsymbol s, bool print, bool single_candidate = false) + int printed = 0; // number of candidates printed + int count = 0; // total candidates + bool child; // true if inside an eponymous template + const(char)* errorPrefix() @safe + { + if (child) + return " - Containing: "; + + // align with blank spaces after first message + enum plural = "Candidates are: "; + enum spaces = " "; + if (printed) + return spaces; + + return (count == 1) ? "Candidate is: " : plural; + } + bool matchSymbol(Dsymbol s, bool print) { if (auto fd = s.isFuncDeclaration()) { @@ -1762,16 +1783,14 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration)) return true; auto tf = cast(TypeFunction) fd.type; OutBuffer buf; - buf.writestring(fd.toPrettyChars()); + buf.writestring(child ? fd.toChars() : fd.toPrettyChars()); buf.writestring(parametersTypeToChars(tf.parameterList)); if (tf.mod) { buf.writeByte(' '); buf.MODtoBuffer(tf.mod); } - .errorSupplemental(fd.loc, - printed ? " `%s`" : - single_candidate ? "Candidate is: `%s`" : "Candidates are: `%s`", buf.peekChars()); + .errorSupplemental(fd.loc, "%s`%s`", errorPrefix(), buf.peekChars()); } else if (auto td = s.isTemplateDeclaration()) { @@ -1779,35 +1798,43 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration)) if (!print) return true; + + // td.onemember may not have overloads set + // (see fail_compilation/onemember_overloads.d) + // assume if more than one member it is overloaded internally + bool recurse = td.onemember && td.members.length > 1; OutBuffer buf; HdrGenState hgs; hgs.skipConstraints = true; + hgs.showOneMember = !recurse; toCharsMaybeConstraints(td, buf, hgs); const tmsg = buf.peekChars(); - const cmsg = td.getConstraintEvalError(constraintsTip); - - // add blank space if there are multiple candidates - // the length of the blank space is `strlen("Candidates are: ")` + const cmsg = child ? null : td.getConstraintEvalError(constraintsTip); if (cmsg) - { - .errorSupplemental(td.loc, - printed ? " `%s`\n%s" : - single_candidate ? "Candidate is: `%s`\n%s" : "Candidates are: `%s`\n%s", - tmsg, cmsg); - } + .errorSupplemental(td.loc, "%s`%s`\n%s", errorPrefix(), tmsg, cmsg); else + .errorSupplemental(td.loc, "%s`%s`", errorPrefix(), tmsg); + + if (recurse) { - .errorSupplemental(td.loc, - printed ? " `%s`" : - single_candidate ? "Candidate is: `%s`" : "Candidates are: `%s`", - tmsg); + child = true; + foreach (d; *td.members) + { + if (d.ident != td.ident) + continue; + + if (auto fd2 = d.isFuncDeclaration()) + matchSymbol(fd2, print); + else if (auto td2 = d.isTemplateDeclaration()) + matchSymbol(td2, print); + } + child = false; } } return true; } // determine if there's > 1 candidate - int count = 0; overloadApply(declaration, (s) { if (matchSymbol(s, false)) count++; @@ -1817,7 +1844,7 @@ if (is(Decl == TemplateDeclaration) || is(Decl == FuncDeclaration)) overloadApply(declaration, (s) { if (global.params.v.verbose || printed < DisplayLimit) { - if (matchSymbol(s, true, count == 1)) + if (matchSymbol(s, true)) printed++; } else @@ -1928,6 +1955,112 @@ FuncDeclaration overloadExactMatch(FuncDeclaration thisfd, Type t) return fd; } +/**************************************************** + * Determine if fd1 overrides fd2. + * Return !=0 if it does. + */ +int overrides(FuncDeclaration fd1, FuncDeclaration fd2) +{ + int result = 0; + if (fd1.ident == fd2.ident) + { + const cov = fd1.type.covariant(fd2.type); + if (cov != Covariant.distinct) + { + ClassDeclaration cd1 = fd1.toParent().isClassDeclaration(); + ClassDeclaration cd2 = fd2.toParent().isClassDeclaration(); + if (cd1 && cd2 && cd2.isBaseOf(cd1, null)) + result = 1; + } + } + return result; +} + +/************************************* + * Determine partial specialization order of functions `f` vs `g`. + * This is very similar to TemplateDeclaration::leastAsSpecialized(). + * Params: + * f = first function + * g = second function + * names = names of parameters + * Returns: + * match 'this' is at least as specialized as g + * 0 g is more specialized than 'this' + */ +MATCH leastAsSpecialized(FuncDeclaration f, FuncDeclaration g, Identifiers* names) +{ + enum LOG_LEASTAS = 0; + static if (LOG_LEASTAS) + { + import core.stdc.stdio : printf; + printf("leastAsSpecialized(%s, %s, %s)\n", f.toChars(), g.toChars(), names ? names.toChars() : "null"); + printf("%s, %s\n", f.type.toChars(), g.type.toChars()); + } + + /* This works by calling g() with f()'s parameters, and + * if that is possible, then f() is at least as specialized + * as g() is. + */ + + TypeFunction tf = f.type.toTypeFunction(); + TypeFunction tg = g.type.toTypeFunction(); + + /* If both functions have a 'this' pointer, and the mods are not + * the same and g's is not const, then this is less specialized. + */ + if (f.needThis() && g.needThis() && tf.mod != tg.mod) + { + if (f.isCtorDeclaration()) + { + if (!MODimplicitConv(tg.mod, tf.mod)) + return MATCH.nomatch; + } + else + { + if (!MODimplicitConv(tf.mod, tg.mod)) + return MATCH.nomatch; + } + } + + /* Create a dummy array of arguments out of the parameters to f() + */ + Expressions args; + foreach (u, p; tf.parameterList) + { + Expression e; + if (p.isReference()) + { + e = new IdentifierExp(Loc.initial, p.ident); + e.type = p.type; + } + else + e = p.type.defaultInitLiteral(Loc.initial); + args.push(e); + } + + MATCH m = tg.callMatch(null, ArgumentList(&args, names), 1); + if (m > MATCH.nomatch) + { + /* A variadic parameter list is less specialized than a + * non-variadic one. + */ + if (tf.parameterList.varargs && !tg.parameterList.varargs) + goto L1; // less specialized + + static if (LOG_LEASTAS) + { + printf(" matches %d, so is least as specialized\n", m); + } + return m; + } +L1: + static if (LOG_LEASTAS) + { + printf(" doesn't match, so is not as specialized\n"); + } + return MATCH.nomatch; +} + /******************************************** * Find function in overload list that matches to the 'this' modifier. * There's four result types. @@ -2493,6 +2626,27 @@ void buildEnsureRequire(FuncDeclaration thisfd) } } +/**************************************************** + * Determine whether an 'out' contract is declared inside + * the given function or any of its overrides. + * Params: + * fd = the function to search + * Returns: + * true found an 'out' contract + */ +bool needsFensure(FuncDeclaration fd) @safe +{ + if (fd.fensures) + return true; + + foreach (fdv; fd.foverrides) + { + if (needsFensure(fdv)) + return true; + } + return false; +} + /**************************************************** * Merge into this function the 'out' contracts of all it overrides. * 'out's are AND'd together, i.e. all of them need to pass. @@ -2515,7 +2669,7 @@ Statement mergeFensure(FuncDeclaration fd, Statement sf, Identifier oid, Express * https://issues.dlang.org/show_bug.cgi?id=3602 and * https://issues.dlang.org/show_bug.cgi?id=5230 */ - if (fd.needsFensure(fdv) && fdv.semanticRun != PASS.semantic3done) + if (needsFensure(fdv) && fdv.semanticRun != PASS.semantic3done) { assert(fdv._scope); Scope* sc = fdv._scope.push(); @@ -2735,3 +2889,176 @@ bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char) return false; } } + +/+ + + Checks the parameter and return types iff this is a `main` function. + + + + The following signatures are allowed for a `D main`: + + - Either no or a single parameter of type `string[]` + + - Return type is either `void`, `int` or `noreturn` + + + + The following signatures are standard C: + + - `int main()` + + - `int main(int, char**)` + + + + This function accepts the following non-standard extensions: + + - `char** envp` as a third parameter + + - `void` / `noreturn` as return type + + + + This function will issue errors for unexpected arguments / return types. + +/ +extern (D) void checkMain(FuncDeclaration fd) +{ + if (fd.ident != Id.main || fd.isMember() || fd.isNested()) + return; // Not a main function + + TypeFunction tf = fd.type.toTypeFunction(); + + Type retType = tf.nextOf(); + if (!retType) + { + // auto main(), check after semantic + assert(fd.inferRetType); + return; + } + + /// Checks whether `t` is equivalent to `char**` + /// Ignores qualifiers and treats enums according to their base type + static bool isCharPtrPtr(Type t) + { + auto tp = t.toBasetype().isTypePointer(); + if (!tp) + return false; + + tp = tp.next.toBasetype().isTypePointer(); + if (!tp) + return false; + + return tp.next.toBasetype().ty == Tchar; + } + + // Neither of these qualifiers is allowed because they affect the ABI + enum invalidSTC = STC.out_ | STC.ref_ | STC.lazy_; + + const nparams = tf.parameterList.length; + bool argerr; + + const linkage = fd.resolvedLinkage(); + if (linkage == LINK.d) + { + if (nparams == 1) + { + auto fparam0 = tf.parameterList[0]; + auto t = fparam0.type.toBasetype(); + if (t.ty != Tarray || + t.nextOf().ty != Tarray || + t.nextOf().nextOf().ty != Tchar || + fparam0.storageClass & invalidSTC) + { + argerr = true; + } + } + + if (tf.parameterList.varargs || nparams >= 2 || argerr) + .error(fd.loc, "%s `%s` parameter list must be empty or accept one parameter of type `string[]`", fd.kind, fd.toPrettyChars); + } + + else if (linkage == LINK.c) + { + if (nparams == 2 || nparams == 3) + { + // Argument count must be int + auto argCount = tf.parameterList[0]; + argerr |= !!(argCount.storageClass & invalidSTC); + argerr |= argCount.type.toBasetype().ty != Tint32; + + // Argument pointer must be char** + auto argPtr = tf.parameterList[1]; + argerr |= !!(argPtr.storageClass & invalidSTC); + argerr |= !isCharPtrPtr(argPtr.type); + + // `char** environ` is a common extension, see J.5.1 of the C standard + if (nparams == 3) + { + auto envPtr = tf.parameterList[2]; + argerr |= !!(envPtr.storageClass & invalidSTC); + argerr |= !isCharPtrPtr(envPtr.type); + } + } + else + argerr = nparams != 0; + + // Disallow variadic main() - except for K&R declarations in C files. + // E.g. int main(), int main(argc, argv) int argc, char** argc { ... } + if (tf.parameterList.varargs && (!fd.isCsymbol() || (!tf.parameterList.hasIdentifierList && nparams))) + argerr |= true; + + if (argerr) + { + .error(fd.loc, "%s `%s` parameters must match one of the following signatures", fd.kind, fd.toPrettyChars); + fd.loc.errorSupplemental("`main()`"); + fd.loc.errorSupplemental("`main(int argc, char** argv)`"); + fd.loc.errorSupplemental("`main(int argc, char** argv, char** environ)` [POSIX extension]"); + } + } + else + return; // Neither C nor D main, ignore (should probably be an error) + + // Allow enums with appropriate base types (same ABI) + retType = retType.toBasetype(); + + if (retType.ty != Tint32 && retType.ty != Tvoid && retType.ty != Tnoreturn) + .error(fd.loc, "%s `%s` must return `int`, `void` or `noreturn`, not `%s`", fd.kind, fd.toPrettyChars, tf.nextOf().toChars()); +} + +/*********************************************** + * Check all return statements for a function to verify that returning + * using NRVO is possible. + * + * Returns: + * `false` if the result cannot be returned by hidden reference. + */ +extern (D) bool checkNRVO(FuncDeclaration fd) +{ + if (!fd.isNRVO() || fd.returns is null) + return false; + + auto tf = fd.type.toTypeFunction(); + if (tf.isref) + return false; + + foreach (rs; *fd.returns) + { + if (auto ve = rs.exp.isVarExp()) + { + auto v = ve.var.isVarDeclaration(); + if (!v || v.isReference()) + return false; + else if (fd.nrvo_var is null) + { + // Variables in the data segment (e.g. globals, TLS or not), + // parameters and closure variables cannot be NRVOed. + if (v.isDataseg() || v.isParameter() || v.toParent2() != fd) + return false; + if (v.nestedrefs.length && fd.needsClosure()) + return false; + // don't know if the return storage is aligned + version (MARS) + { + if (fd.alignSectionVars && (*fd.alignSectionVars).contains(v)) + return false; + } + // The variable type needs to be equivalent to the return type. + if (!v.type.equivalent(tf.next)) + return false; + //printf("Setting nrvo to %s\n", v.toChars()); + fd.nrvo_var = v; + } + else if (fd.nrvo_var != v) + return false; + } + else //if (!exp.isLvalue()) // keep NRVO-ability + return false; + } + return true; +} diff --git a/gcc/d/dmd/gluelayer.d b/gcc/d/dmd/gluelayer.d index a3a3bd01f135..72e6c521bff2 100644 --- a/gcc/d/dmd/gluelayer.d +++ b/gcc/d/dmd/gluelayer.d @@ -25,7 +25,7 @@ version (NoBackend) struct Symbol; struct code; struct block; - struct Blockx; + struct BlockState; struct elem; struct TYPE; alias type = TYPE; @@ -51,9 +51,9 @@ else version (IN_GCC) } else { - public import dmd.backend.cc : block, Blockx, Symbol; + public import dmd.backend.cc : block, BlockState, Symbol; public import dmd.backend.type : type; public import dmd.backend.el : elem; - public import dmd.backend.code_x86 : code; + public import dmd.backend.x86.code_x86 : code; public import dmd.objc_glue : ObjcGlue; } diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index 41da11dedbec..1e72cf709c66 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -62,6 +62,7 @@ struct HdrGenState bool doFuncBodies; /// include function bodies in output bool vcg_ast; /// write out codegen-ast bool skipConstraints; // skip constraints when doing templates + bool showOneMember = true; bool fullQual; /// fully qualify types when printing int tpltMember; @@ -1974,7 +1975,7 @@ void toCharsMaybeConstraints(const TemplateDeclaration td, ref OutBuffer buf, re } buf.writeByte(')'); - if (td.onemember) + if (hgs.showOneMember && td.onemember) { if (const fd = td.onemember.isFuncDeclaration()) { diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d index 6dbc60b020cc..dfaf8f5200b3 100644 --- a/gcc/d/dmd/id.d +++ b/gcc/d/dmd/id.d @@ -102,6 +102,8 @@ immutable Msgtable[] msgtable = { "ctfe", "__ctfe" }, { "offset" }, { "offsetof" }, + { "bitoffsetof" }, + { "bitwidth" }, { "ModuleInfo" }, { "ClassInfo" }, { "classinfo" }, @@ -455,6 +457,7 @@ immutable Msgtable[] msgtable = { "isAbstractClass" }, { "isArithmetic" }, { "isAssociativeArray" }, + { "isBitfield" }, { "isFinalClass" }, { "isTemplate" }, { "isPOD" }, diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index dcfe18355949..a91a0a4ef630 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -597,6 +597,14 @@ extern (C++) abstract class Type : ASTNode tsize_t = basic[isLP64 ? Tuns64 : Tuns32]; tptrdiff_t = basic[isLP64 ? Tint64 : Tint32]; thash_t = tsize_t; + + static if (__VERSION__ == 2081) + { + // Related issue: https://issues.dlang.org/show_bug.cgi?id=19134 + // D 2.081.x regressed initializing class objects at compile time. + // As a workaround initialize this global at run-time instead. + TypeTuple.empty = new TypeTuple(); + } } /** @@ -4405,7 +4413,10 @@ extern (C++) final class TypeClass : Type extern (C++) final class TypeTuple : Type { // 'logically immutable' cached global - don't modify! - __gshared TypeTuple empty = new TypeTuple(); + static if (__VERSION__ == 2081) + __gshared TypeTuple empty; // See comment in Type._init + else + __gshared TypeTuple empty = new TypeTuple(); Parameters* arguments; // types making up the tuple diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index d88face9c6c8..963fa9238a08 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -314,7 +314,7 @@ private extern(C++) final class Semantic3Visitor : Visitor fds.checkInContractOverrides(); // Remember whether we need to generate an 'out' contract. - immutable bool needEnsure = FuncDeclaration.needsFensure(funcdecl); + immutable bool needEnsure = funcdecl.needsFensure(); if (funcdecl.fbody || funcdecl.frequires || needEnsure) { diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index ae68d6a67e71..d0e1b9a23d9e 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -3542,6 +3542,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc) ls2.statement = ls; sc = sc.push(); + sc.lastVar = sc.enclosing.lastVar; sc.scopesym = sc.enclosing.scopesym; sc.ctorflow.orCSX(CSX.label); @@ -3549,6 +3550,10 @@ Statement statementSemanticVisit(Statement s, Scope* sc) sc.slabel = ls; if (ls.statement) ls.statement = ls.statement.statementSemantic(sc); + + //issue 24534: lastVar may have been updated in the nested scope + sc.enclosing.lastVar = sc.lastVar; + sc.pop(); result = ls; diff --git a/gcc/d/dmd/target.d b/gcc/d/dmd/target.d index 87826b50df1d..dadf51912db4 100644 --- a/gcc/d/dmd/target.d +++ b/gcc/d/dmd/target.d @@ -113,6 +113,7 @@ extern (C++) struct Target const(char)[] architectureName; CPU cpu; // CPU instruction set to target bool isX86_64; // generate 64 bit code for x86_64; true by default for 64 bit dmd + bool isX86; // generate 32 bit Intel x86 code bool isLP64; // pointers are 64 bits // Environmental @@ -120,7 +121,6 @@ extern (C++) struct Target const(char)[] lib_ext; /// extension for static library files const(char)[] dll_ext; /// extension for dynamic library files bool run_noext; /// allow -run sources without extensions - bool omfobj; // for Win32: write OMF object files instead of MsCoff /** * Values representing all properties for floating point types */ @@ -302,7 +302,6 @@ struct TargetC { Unspecified, Bionic, - DigitalMars, Glibc, Microsoft, Musl, @@ -314,7 +313,6 @@ struct TargetC enum BitFieldStyle : ubyte { Unspecified, - DM, /// Digital Mars 32 bit C compiler MS, /// Microsoft 32 and 64 bit C compilers /// https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160 /// https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160 @@ -347,7 +345,6 @@ struct TargetCPP { Unspecified, Clang, - DigitalMars, Gcc, Microsoft, Sun diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h index 6237cf148361..a5caa74c80e8 100644 --- a/gcc/d/dmd/target.h +++ b/gcc/d/dmd/target.h @@ -50,7 +50,6 @@ struct TargetC { Unspecified, Bionic, - DigitalMars, Glibc, Microsoft, Musl, @@ -62,7 +61,6 @@ struct TargetC enum class BitFieldStyle : unsigned char { Unspecified, - DM, // Digital Mars 32 bit C compiler MS, // Microsoft 32 and 64 bit C compilers // https://docs.microsoft.com/en-us/cpp/c-language/c-bit-fields?view=msvc-160 // https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160 @@ -87,7 +85,6 @@ struct TargetCPP { Unspecified, Clang, - DigitalMars, Gcc, Microsoft, Sun @@ -157,6 +154,7 @@ struct Target DString architectureName; // name of the platform architecture (e.g. X86_64) CPU cpu; // CPU instruction set to target d_bool isX86_64; // generate 64 bit code for x86_64; true by default for 64 bit dmd + d_bool isX86; // generate 32 bit Intel x86 code d_bool isLP64; // pointers are 64 bits // Environmental @@ -164,7 +162,6 @@ struct Target DString lib_ext; /// extension for static library files DString dll_ext; /// extension for dynamic library files d_bool run_noext; /// allow -run sources without extensions - d_bool omfobj; /// for Win32: write OMF object files instead of COFF template struct FPTypeProperties diff --git a/gcc/d/dmd/templatesem.d b/gcc/d/dmd/templatesem.d index bd3cd89588f7..d26e35d814a4 100644 --- a/gcc/d/dmd/templatesem.d +++ b/gcc/d/dmd/templatesem.d @@ -56,6 +56,8 @@ import dmd.tokens; import dmd.typesem; import dmd.visitor; +alias funcLeastAsSpecialized = dmd.funcsem.leastAsSpecialized; + /************************************ * Perform semantic analysis on template. * Params: @@ -2021,8 +2023,8 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc, * This is because f() is "more specialized." */ { - MATCH c1 = FuncDeclaration.leastAsSpecialized(fd, m.lastf, argumentList.names); - MATCH c2 = FuncDeclaration.leastAsSpecialized(m.lastf, fd, argumentList.names); + MATCH c1 = funcLeastAsSpecialized(fd, m.lastf, argumentList.names); + MATCH c2 = funcLeastAsSpecialized(m.lastf, fd, argumentList.names); //printf("c1 = %d, c2 = %d\n", c1, c2); if (c1 > c2) return firstIsBetter(); if (c1 < c2) return 0; @@ -2301,8 +2303,8 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc, } { // Disambiguate by picking the most specialized FunctionDeclaration - MATCH c1 = FuncDeclaration.leastAsSpecialized(fd, m.lastf, argumentList.names); - MATCH c2 = FuncDeclaration.leastAsSpecialized(m.lastf, fd, argumentList.names); + MATCH c1 = funcLeastAsSpecialized(fd, m.lastf, argumentList.names); + MATCH c2 = funcLeastAsSpecialized(m.lastf, fd, argumentList.names); //printf("3: c1 = %d, c2 = %d\n", c1, c2); if (c1 > c2) goto Ltd; if (c1 < c2) goto Ltd_best; diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index 81d42e6e8be5..5ec38449123c 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -503,6 +503,17 @@ Expression semanticTraits(TraitsExp e, Scope* sc) sm => sm.isTemplateDeclaration() !is null) != 0; }); } + if (e.ident == Id.isBitfield) + { + if (dim != 1) + return dimError(1); + + return isDsymX((s) + { + s = s.toAlias(); + return s.isBitFieldDeclaration() !is null; + }); + } if (e.ident == Id.isPOD) { if (dim != 1) diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index 195fdc723a21..31ebc4c809c6 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -1282,6 +1282,23 @@ bool hasPointers(Type t) } } +/************************************** + * Returns an indirect type one step from t. + */ +Type getIndirection(Type t) +{ + t = t.baseElemOf(); + if (t.ty == Tarray || t.ty == Tpointer) + return t.nextOf().toBasetype(); + if (t.ty == Taarray || t.ty == Tclass) + return t; + if (t.ty == Tstruct) + return t.hasPointers() ? t : null; // TODO + + // should consider TypeDelegate? + return null; +} + /****************************************** * Perform semantic analysis on a type. * Params: @@ -4083,7 +4100,9 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag } if (v) { - if (ident == Id.offsetof) + if (ident == Id.offsetof || + ident == Id.bitoffsetof || + ident == Id.bitwidth) { v.dsymbolSemantic(null); if (v.isField()) @@ -4093,7 +4112,20 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag ad.size(e.loc); if (ad.sizeok != Sizeok.done) return ErrorExp.get(); - return new IntegerExp(e.loc, v.offset, Type.tsize_t); + uint value; + if (ident == Id.offsetof) + value = v.offset; + else // Id.bitoffsetof || Id.bitwidth + { + auto bf = v.isBitFieldDeclaration(); + if (bf) + { + value = ident == Id.bitoffsetof ? bf.bitOffset : bf.fieldWidth; + } + else + error(v.loc, "`%s` is not a bitfield, cannot apply `%s`", v.toChars(), ident.toChars()); + } + return new IntegerExp(e.loc, value, Type.tsize_t); } } else if (ident == Id._init) @@ -4512,6 +4544,8 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag ident != Id._mangleof && ident != Id.stringof && ident != Id.offsetof && + ident != Id.bitoffsetof && + ident != Id.bitwidth && // https://issues.dlang.org/show_bug.cgi?id=15045 // Don't forward special built-in member functions. ident != Id.ctor && @@ -6687,7 +6721,7 @@ Type substWildTo(Type type, uint mod) t = new TypeSArray(t, (cast(TypeSArray)type).dim.syntaxCopy()); else if (type.ty == Taarray) { - t = new TypeAArray(t, (cast(TypeAArray)type).index.syntaxCopy()); + t = new TypeAArray(t, (cast(TypeAArray)type).index.substWildTo(mod)); } else if (type.ty == Tdelegate) { diff --git a/gcc/testsuite/gdc.test/compilable/b20243.d b/gcc/testsuite/gdc.test/compilable/b20243.d new file mode 100644 index 000000000000..792dcf302d16 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/b20243.d @@ -0,0 +1,9 @@ +module b20243; + +inout(int) f(inout(int)[inout(string)] x); +const(int)[const(string)] x; +static assert(is(typeof(f(x)) == const(int))); + +inout(int)[inout(string)] g(inout(int) y); +const(int) y; +static assert(is(typeof(g(y)) == const(int)[const(string)])); diff --git a/gcc/testsuite/gdc.test/compilable/cppmangle.d b/gcc/testsuite/gdc.test/compilable/cppmangle.d index 264b374dd553..948fee2cfdaa 100644 --- a/gcc/testsuite/gdc.test/compilable/cppmangle.d +++ b/gcc/testsuite/gdc.test/compilable/cppmangle.d @@ -8,7 +8,6 @@ import core.stdc.stdio; version (CppRuntime_Clang) version = CppMangle_Itanium; -version (CppRuntime_DigitalMars) version = CppMangle_MSVC; version (CppRuntime_Gcc) version = CppMangle_Itanium; version (CppRuntime_Microsoft) version = CppMangle_MSVC; version (CppRuntime_Sun) version = CppMangle_Itanium; diff --git a/gcc/testsuite/gdc.test/compilable/cppmangle3.d b/gcc/testsuite/gdc.test/compilable/cppmangle3.d index 82c68f7a3a57..92c858854f0c 100644 --- a/gcc/testsuite/gdc.test/compilable/cppmangle3.d +++ b/gcc/testsuite/gdc.test/compilable/cppmangle3.d @@ -4,7 +4,6 @@ module cppmangle3; version (CppRuntime_Clang) version = CppMangle_Itanium; -version (CppRuntime_DigitalMars) version = CppMangle_MSVC; version (CppRuntime_Gcc) version = CppMangle_Itanium; version (CppRuntime_Microsoft) version = CppMangle_MSVC; version (CppRuntime_Sun) version = CppMangle_Itanium; diff --git a/gcc/testsuite/gdc.test/compilable/d_ident_c99.d b/gcc/testsuite/gdc.test/compilable/d_ident_c99.d new file mode 100644 index 000000000000..2cff082fff93 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/d_ident_c99.d @@ -0,0 +1,5 @@ +// REQUIRED_ARGS: -identifiers=c99 + +// verify that the C99 identifier set is applied. + +int ªideµnt; diff --git a/gcc/testsuite/gdc.test/compilable/deprecationlimit.d b/gcc/testsuite/gdc.test/compilable/deprecationlimit.d new file mode 100644 index 000000000000..dcdc9e118ca5 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/deprecationlimit.d @@ -0,0 +1,22 @@ +/* +REQUIRED_ARGS: -verrors=3 +TEST_OUTPUT: +--- +compilable/deprecationlimit.d(18): Deprecation: function `deprecationlimit.f` is deprecated +compilable/deprecationlimit.d(19): Deprecation: function `deprecationlimit.f` is deprecated +compilable/deprecationlimit.d(20): Deprecation: function `deprecationlimit.f` is deprecated +1 deprecation warning omitted, use `-verrors=0` to show all +--- +*/ + +deprecated void f() +{ +} + +void main() +{ + f(); + f(); + f(); + f(); +} diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_21217.d b/gcc/testsuite/gdc.test/compilable/dtoh_21217.d index 3e535d24a06c..439ff3612d50 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_21217.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_21217.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - struct Foo final { int32_t a; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_AliasDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_AliasDeclaration.d index 64198f91a217..43bbe975e2ec 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_AliasDeclaration.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_AliasDeclaration.d @@ -14,33 +14,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - class C; extern void importFunc(); diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_AliasDeclaration_98.d b/gcc/testsuite/gdc.test/compilable/dtoh_AliasDeclaration_98.d index 12edbd239231..b285e6f9e6d8 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_AliasDeclaration_98.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_AliasDeclaration_98.d @@ -11,33 +11,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - template struct TS final { diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_AnonDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_AnonDeclaration.d index a4c6ce4ce2ca..3c5bde32dbe2 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_AnonDeclaration.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_AnonDeclaration.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - struct S final { union diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_CPPNamespaceDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_CPPNamespaceDeclaration.d index 04363711bd3d..2310bfade7ec 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_CPPNamespaceDeclaration.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_CPPNamespaceDeclaration.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - namespace nameSpace { extern void fn(); diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d index 169b7b153640..cca4646814a5 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_ClassDeclaration.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - class ForwardClass; class BaseClass diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_TemplateDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_TemplateDeclaration.d index 6fefcceeb976..45b5530831aa 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_TemplateDeclaration.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_TemplateDeclaration.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - struct Outer final { int32_t a; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_UnionDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_UnionDeclaration.d index 48fcf72c0611..e0648d7c1765 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_UnionDeclaration.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_UnionDeclaration.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - union U1 { int32_t a; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_enum.d b/gcc/testsuite/gdc.test/compilable/dtoh_enum.d index 8b3e5aa3873d..e8b4a5546905 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_enum.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_enum.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - enum : int32_t { Anon = 10 }; enum : bool { Anon2 = true }; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_enum_cpp98.d b/gcc/testsuite/gdc.test/compilable/dtoh_enum_cpp98.d index 6a266d9be77e..1314f64b0edb 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_enum_cpp98.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_enum_cpp98.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - static int32_t const Anon = 10; static bool const Anon2 = true; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_expressions.d b/gcc/testsuite/gdc.test/compilable/dtoh_expressions.d index b93c47e08137..7af10256c55b 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_expressions.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_expressions.d @@ -11,33 +11,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - extern int32_t foo(); extern int32_t* somePtr; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_forwarding.d b/gcc/testsuite/gdc.test/compilable/dtoh_forwarding.d index c9d5bbc796eb..beb779db32e4 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_forwarding.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_forwarding.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - struct Child; class Struct; enum class Enum; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_functions.d b/gcc/testsuite/gdc.test/compilable/dtoh_functions.d index 90223cca81e5..f5777bc8d213 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_functions.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_functions.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - struct S final { int32_t i; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_invalid_identifiers.d b/gcc/testsuite/gdc.test/compilable/dtoh_invalid_identifiers.d index a8f5b9904137..28c79088a266 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_invalid_identifiers.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_invalid_identifiers.d @@ -21,33 +21,6 @@ compilable/dtoh_invalid_identifiers.d(145): Warning: function `__attribute__` is #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - extern void register(int32_t* ptr); namespace const_cast diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_mangling.d b/gcc/testsuite/gdc.test/compilable/dtoh_mangling.d index fda9efa5d343..203f424ae0b4 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_mangling.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_mangling.d @@ -11,33 +11,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - extern "C" int32_t freeC(); // Ignored function dtoh_mangling.bar because C++ doesn't support explicit mangling diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_names.d b/gcc/testsuite/gdc.test/compilable/dtoh_names.d index a4b055e4097e..c6def03ad8f4 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_names.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_names.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - struct Outer final { static Outer* outerPtr; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_protection.d b/gcc/testsuite/gdc.test/compilable/dtoh_protection.d index dc07c7b8f8b7..458b2d7cc28f 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_protection.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_protection.d @@ -13,33 +13,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - struct S1 final { int32_t a; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_required_symbols.d b/gcc/testsuite/gdc.test/compilable/dtoh_required_symbols.d index ab5376424f98..77aee6e2f2a4 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_required_symbols.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_required_symbols.d @@ -11,33 +11,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - class ExternDClass; struct ExternDStruct2; struct ExternDStruct3; diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_special_enum.d b/gcc/testsuite/gdc.test/compilable/dtoh_special_enum.d index ee86a5e71218..a2982ac9eaa6 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_special_enum.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_special_enum.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - enum class __c_not_special; extern "C" void fn_long(long __param_0_); diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_unittest_block.d b/gcc/testsuite/gdc.test/compilable/dtoh_unittest_block.d index 7b2943c5fc50..c7aa6b7a7e60 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_unittest_block.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_unittest_block.d @@ -12,33 +12,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - --- */ diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_verbose.d b/gcc/testsuite/gdc.test/compilable/dtoh_verbose.d index 891ff0ebd483..e4b268b8a69a 100644 --- a/gcc/testsuite/gdc.test/compilable/dtoh_verbose.d +++ b/gcc/testsuite/gdc.test/compilable/dtoh_verbose.d @@ -14,33 +14,6 @@ TEST_OUTPUT: #include #include -#ifdef CUSTOM_D_ARRAY_TYPE -#define _d_dynamicArray CUSTOM_D_ARRAY_TYPE -#else -/// Represents a D [] array -template -struct _d_dynamicArray final -{ - size_t length; - T *ptr; - - _d_dynamicArray() : length(0), ptr(NULL) { } - - _d_dynamicArray(size_t length_in, T *ptr_in) - : length(length_in), ptr(ptr_in) { } - - T& operator[](const size_t idx) { - assert(idx < length); - return ptr[idx]; - } - - const T& operator[](const size_t idx) const { - assert(idx < length); - return ptr[idx]; - } -}; -#endif - extern void importFunc(); // Ignored function dtoh_verbose.foo because of linkage diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_windows.d b/gcc/testsuite/gdc.test/compilable/dtoh_windows.d new file mode 100644 index 000000000000..1cbe3248ce1e --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/dtoh_windows.d @@ -0,0 +1,36 @@ +/++ +REQUIRED_ARGS: -HC -o- +TEST_OUTPUT: +--- +// Automatically generated by Digital Mars D Compiler + +#pragma once + +#include +#include +#include +#include + +#ifndef _WIN32 +#define EXTERN_SYSTEM_AFTER __stdcall +#define EXTERN_SYSTEM_BEFORE +#else +#define EXTERN_SYSTEM_AFTER +#define EXTERN_SYSTEM_BEFORE extern "C" +#endif + +EXTERN_SYSTEM_BEFORE int32_t EXTERN_SYSTEM_AFTER exSystem(int32_t x); + +int32_t __stdcall exWindows(int32_t y); +--- +++/ + +extern(System) int exSystem(int x) +{ + return x; +} + +extern(Windows) int exWindows(int y) +{ + return y; +} diff --git a/gcc/testsuite/gdc.test/compilable/future.d b/gcc/testsuite/gdc.test/compilable/future.d deleted file mode 100644 index 30439847ef4a..000000000000 --- a/gcc/testsuite/gdc.test/compilable/future.d +++ /dev/null @@ -1,47 +0,0 @@ -/* PERMUTE_ARGS: - * TEST_OUTPUT: ---- -compilable/future.d(15): Deprecation: `@__future` base class method `future.A.msg` is being overridden by `future.B.msg`; rename the latter ---- - */ - -class A -{ - @__future char msg() { return 'a'; } -} - -class B : A -{ - char msg() { return 'b'; } -} - -class C : B -{ - override char msg() { return 'c'; } -} - -class D : A -{ - override char msg() { return 'd'; } -} - -int main() -{ - auto a = new A(); - assert(a.msg() == 'a'); - auto b = new B(); - assert(b.msg() == 'b'); - auto c = new C(); - assert(c.msg() == 'c'); - auto d = new D(); - assert(d.msg() == 'd'); - - assert(b.A.msg() == 'a'); - - auto ba = cast(A)b; - assert(ba.msg() == 'a'); - - auto da = cast(A)d; - assert(da.msg() == 'd'); - return 0; -} diff --git a/gcc/testsuite/gdc.test/compilable/ident_UAX31.d b/gcc/testsuite/gdc.test/compilable/ident_UAX31.d new file mode 100644 index 000000000000..c8d579a30e02 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/ident_UAX31.d @@ -0,0 +1,5 @@ +// REQUIRED_ARGS: -identifiers=UAX31 + +// verify that the UAX31 identifier set is applied. + +int øideùnt; diff --git a/gcc/testsuite/gdc.test/compilable/ident_all.d b/gcc/testsuite/gdc.test/compilable/ident_all.d new file mode 100644 index 000000000000..2dd93167b69c --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/ident_all.d @@ -0,0 +1,10 @@ +// REQUIRED_ARGS: -identifiers=all + +// verify that the UAX31 identifier set is applied. + +int øideùnt; +int ªideµnt; +int ¨ide¯nt; + +// just to play it safe, do we support one unicode then another at start? +int øùident; diff --git a/gcc/testsuite/gdc.test/compilable/ident_c11.d b/gcc/testsuite/gdc.test/compilable/ident_c11.d new file mode 100644 index 000000000000..8504a36059f2 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/ident_c11.d @@ -0,0 +1,5 @@ +// REQUIRED_ARGS: -identifiers=c11 + +// verify that the C11 identifier set is applied. + +int ¨ide¯nt; diff --git a/gcc/testsuite/gdc.test/compilable/ob1.d b/gcc/testsuite/gdc.test/compilable/ob1.d index 720c765eda32..bbc862e0f14a 100644 --- a/gcc/testsuite/gdc.test/compilable/ob1.d +++ b/gcc/testsuite/gdc.test/compilable/ob1.d @@ -147,3 +147,19 @@ struct S { int i; int* p; } S* s = cast(S*)malloc(); free(s.p); // consumes s } + +/******************************* + * https://issues.dlang.org/show_bug.cgi?id=21854 + */ + +@live void test21854() +{ + foreach(int tmp; 0..10) { } + + int key = 0; + int limit = 10; + for (; key < limit; key += 1) + { + int tmp = key; + } +} diff --git a/gcc/testsuite/gdc.test/compilable/returnscope_without_safe.d b/gcc/testsuite/gdc.test/compilable/returnscope_without_safe.d new file mode 100644 index 000000000000..7a84e65b67c6 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/returnscope_without_safe.d @@ -0,0 +1,16 @@ +// Stack pointers are being escaped here, but without +// @safe and dip1000, it should still be allowed +// because return scope could have been inferred incorrectly, +// and it breaks existing code: +// https://issues.dlang.org/show_bug.cgi?id=23657 + +int* identity(return scope int* x); + +auto identityAuto(int* x) => x; + +int* f() +{ + int x; + return identity(&x); + return identityAuto(&x); +} diff --git a/gcc/testsuite/gdc.test/compilable/sw_transition_complex.d b/gcc/testsuite/gdc.test/compilable/sw_transition_complex.d index b6dbc8a34607..3b2735603327 100644 --- a/gcc/testsuite/gdc.test/compilable/sw_transition_complex.d +++ b/gcc/testsuite/gdc.test/compilable/sw_transition_complex.d @@ -1,5 +1,5 @@ // PERMUTE_ARGS: -// REQUIRED_ARGS: -unittest +// REQUIRED_ARGS: -unittest -verrors=0 /* TEST_OUTPUT: diff --git a/gcc/testsuite/gdc.test/compilable/test11559upgradeoptlink.d b/gcc/testsuite/gdc.test/compilable/test11559upgradeoptlink.d index b61ffc81d276..774176e4545b 100644 --- a/gcc/testsuite/gdc.test/compilable/test11559upgradeoptlink.d +++ b/gcc/testsuite/gdc.test/compilable/test11559upgradeoptlink.d @@ -1,7 +1,5 @@ // REQUIRED_ARGS: -g -// If this is failing, you need optlink 8.00.14 or higher - string gen() { string m; diff --git a/gcc/testsuite/gdc.test/compilable/test24479.d b/gcc/testsuite/gdc.test/compilable/test24479.d new file mode 100644 index 000000000000..7865c1b60741 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test24479.d @@ -0,0 +1,35 @@ +// https://issues.dlang.org/show_bug.cgi?id=24479 + +/* +TEST_OUTPUT: +--- +1 +2 +--- +*/ + +struct S +{ + @1 + S opBinary(string op: "-")(S rhs) const pure nothrow @nogc + { + return rhs; + } + @2 + S opBinary(string op: "*")(S dur) const pure nothrow @nogc + { + return dur; + } +} + +private enum hasExternalUDA(alias A) = is(A == External) || is(typeof(A) == External); + +void foo() +{ + static foreach (t; __traits(getOverloads, S, "opBinary", true)) + static foreach(attr; __traits(getAttributes, t)) + pragma(msg, attr); + + static assert(__traits(getOverloads, S, "opBinary", true).length == 2); + alias A = __traits(getAttributes, __traits(getOverloads, S, "opBinary", true)[1]); +} diff --git a/gcc/testsuite/gdc.test/compilable/test24560.d b/gcc/testsuite/gdc.test/compilable/test24560.d new file mode 100644 index 000000000000..a4a4926622bd --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test24560.d @@ -0,0 +1,12 @@ +// https://issues.dlang.org/show_bug.cgi?id=24560 + +class C { } +struct S +{ + static void fun(C heur = new C) { } +} + +void main() +{ + S.fun(); +} diff --git a/gcc/testsuite/gdc.test/compilable/test__ctfeWrite.d b/gcc/testsuite/gdc.test/compilable/test__ctfeWrite.d new file mode 100644 index 000000000000..0f1e55ff0fc8 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test__ctfeWrite.d @@ -0,0 +1,58 @@ +/* +TEST_OUTPUT: +--- +Hello +World +from +CTFE +Hello[1 .. 3] = el +S.str +abcdefghij[2 .. 6] = cdef +--- +*/ + +struct S +{ + string str = "S.str"; + alias str this; +} + +int greeting(scope const char[][] values) pure nothrow @safe @nogc +{ + const string newline = "\n"; + + foreach (const val; values) + { + __ctfeWrite(val); + __ctfeWrite(newline); + } + + // Test slices + const val = values[0]; + __ctfeWrite(val[]); + __ctfeWrite(['[','1',' ','.','.',' ','3',']',' ','=',' ']); + __ctfeWrite(val[1 .. 3]); + __ctfeWrite(newline); + + S s; + __ctfeWrite(s); + __ctfeWrite(newline); + + // Test mutable slices + char[10] buffer; + fill(buffer); // Avoid potential shortcuts for literals + __ctfeWrite(buffer[0 .. $]); + __ctfeWrite("[2 .. 6] = "); + __ctfeWrite(buffer[2 .. 6]); + __ctfeWrite(newline); + + return 0; +} + +void fill(ref char[10] buffer) pure nothrow @safe @nogc +{ + foreach (const idx, ref ch; buffer) + ch = cast(char)('a' + idx); +} + +enum forceCTFE = greeting(["Hello", "World", "from", "CTFE"]); diff --git a/gcc/testsuite/gdc.test/compilable/zerosize.d b/gcc/testsuite/gdc.test/compilable/zerosize.d index 6e26deb5490c..7986c92c7f80 100644 --- a/gcc/testsuite/gdc.test/compilable/zerosize.d +++ b/gcc/testsuite/gdc.test/compilable/zerosize.d @@ -6,10 +6,7 @@ version (CRuntime_Microsoft) else static assert(S.sizeof == 0); -version (CRuntime_DigitalMars) - static assert(S.alignof == 0); -else - static assert(S.alignof == 1); +static assert(S.alignof == 1); extern (C++) struct T { } diff --git a/gcc/testsuite/gdc.test/fail_compilation/alias_instance_member.d b/gcc/testsuite/gdc.test/fail_compilation/alias_instance_member.d new file mode 100644 index 000000000000..9f3729ed23f1 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/alias_instance_member.d @@ -0,0 +1,28 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/alias_instance_member.d(18): Error: cannot alias member of variable `that` +fail_compilation/alias_instance_member.d(18): Use `typeof(that)` instead to preserve behaviour +--- +*/ + +@__edition_latest_do_not_use +module aim; + +struct Foo +{ + int v; + void test(Foo that) const + { + alias a = this.v; // OK + alias b = that.v; + assert(&a is &b); + } +} + +void main() +{ + Foo a = Foo(1); + Foo b = Foo(2); + a.test(b); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/alias_instance_member2.d b/gcc/testsuite/gdc.test/fail_compilation/alias_instance_member2.d new file mode 100644 index 000000000000..752ef140e548 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/alias_instance_member2.d @@ -0,0 +1,21 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/alias_instance_member2.d(20): Error: cannot alias member of variable `f` +fail_compilation/alias_instance_member2.d(20): Use `typeof(f)` instead to preserve behaviour +--- +*/ + +@__edition_latest_do_not_use +module aim; + +struct Foo +{ + int v; +} + +struct Bar +{ + Foo f; + alias v = f.v; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/bitintro.d b/gcc/testsuite/gdc.test/fail_compilation/bitintro.d new file mode 100644 index 000000000000..d58c3ea56ff0 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/bitintro.d @@ -0,0 +1,38 @@ +/* REQUIRED_ARGS: -preview=bitfields + */ + +struct S +{ + int a; + int b:5, c:6; +} + +static if (0) +{ + pragma(msg, __traits(isBitfield, S.a)); + pragma(msg, __traits(isBitfield, S.b)); + pragma(msg, S.b.bitoffsetof); + pragma(msg, S.b.bitwidth); + pragma(msg, S.c.bitoffsetof); + pragma(msg, S.c.bitwidth); + pragma(msg, S.a.bitoffsetof); + pragma(msg, S.a.bitwidth); +} + +static assert(__traits(isBitfield, S.a) == false); +static assert(__traits(isBitfield, S.b) == true); +static assert(S.b.bitoffsetof == 0); +static assert(S.b.bitwidth == 5); +static assert(S.c.bitoffsetof == 5); +static assert(S.c.bitwidth == 6); + +/* TEST_OUTPUT: +--- +fail_compilation/bitintro.d(6): Error: `a` is not a bitfield, cannot apply `bitoffsetof` +fail_compilation/bitintro.d(37): while evaluating: `static assert(a.bitoffsetof)` +fail_compilation/bitintro.d(6): Error: `a` is not a bitfield, cannot apply `bitwidth` +fail_compilation/bitintro.d(38): while evaluating: `static assert(a.bitwidth)` +--- +*/ +static assert(S.a.bitoffsetof); +static assert(S.a.bitwidth); diff --git a/gcc/testsuite/gdc.test/fail_compilation/cast_qual.d b/gcc/testsuite/gdc.test/fail_compilation/cast_qual.d new file mode 100644 index 000000000000..19932f811653 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/cast_qual.d @@ -0,0 +1,19 @@ +/* +REQUIRED_ARGS: -preview=dip1000 -de +TEST_OUTPUT: +--- +fail_compilation/cast_qual.d(15): Deprecation: cast from `const(int)` to `int` cannot be used as an lvalue in @safe code +fail_compilation/cast_qual.d(17): Deprecation: cast from `const(int)` to `int` cannot be used as an lvalue in @safe code +--- +*/ + +@safe: + +void main() { + const int i = 3; + int j = cast() i; // OK + int* p = &cast() i; // this should not compile in @safe code + *p = 4; // oops + cast() i = 5; // NG + auto q = &cast(const) j; // OK, int* to const int* +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/deprecate1553.d b/gcc/testsuite/gdc.test/fail_compilation/deprecate1553.d index 18a7152001af..867616ccac13 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/deprecate1553.d +++ b/gcc/testsuite/gdc.test/fail_compilation/deprecate1553.d @@ -1,9 +1,7 @@ -// REQUIRED_ARGS: -de - /* TEST_OUTPUT: --- -fail_compilation/deprecate1553.d(18): Deprecation: cannot use `foreach_reverse` with a delegate +fail_compilation/deprecate1553.d(16): Error: cannot use `foreach_reverse` with a delegate --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/editions.d b/gcc/testsuite/gdc.test/fail_compilation/editions.d new file mode 100644 index 000000000000..869ee22c11cb --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/editions.d @@ -0,0 +1,16 @@ +/** +Test language editions (currently experimental) + +TEST_OUTPUT: +--- +fail_compilation/editions.d(15): Error: scope parameter `x` may not be returned +--- +*/ +@__edition_latest_do_not_use +module editions; + +@safe: +int* f(scope int* x) +{ + return x; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/empty_statement.d b/gcc/testsuite/gdc.test/fail_compilation/empty_statement.d new file mode 100644 index 000000000000..34070d5f48ca --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/empty_statement.d @@ -0,0 +1,14 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/empty_statement.d(11): Error: use `{ }` for an empty statement, not `;` +fail_compilation/empty_statement.d(12): Error: use `{ }` for an empty statement, not `;` +fail_compilation/empty_statement.d(13): Error: use `{ }` for an empty statement, not `;` +--- +*/ +void main() +{ + for (;;); + if (0); + while (0); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail125.d b/gcc/testsuite/gdc.test/fail_compilation/fail125.d index 93d176dd4e23..8a4be29fbfb6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail125.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail125.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail125.d(15): Error: array index `[2]` is outside array bounds `[0 .. 2]` +fail_compilation/fail125.d(15): Error: sequence index `[2]` is outside bounds `[0 .. 2]` fail_compilation/fail125.d(18): Error: template instance `fail125.main.recMove!(1, a, b)` error instantiating fail_compilation/fail125.d(25): instantiated from here: `recMove!(0, a, b)` --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17612.d b/gcc/testsuite/gdc.test/fail_compilation/fail17612.d index d39dd51cb6e1..a14e85935a63 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail17612.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail17612.d @@ -1,7 +1,9 @@ /* TEST_OUTPUT: --- -fail_compilation/fail17612.d(14): Error: undefined identifier `string` -fail_compilation/fail17612.d(17): Error: class `object.TypeInfo` missing or corrupt object.d +fail_compilation/fail17612.d(16): Error: undefined identifier `string` +fail_compilation/fail17612.d(19): Error: `TypeInfo` not found. object.d may be incorrectly installed or corrupt. +fail_compilation/fail17612.d(19): dmd might not be correctly installed. Run 'dmd -man' for installation instructions. +fail_compilation/fail17612.d(19): config file: not found --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail24485.d b/gcc/testsuite/gdc.test/fail_compilation/fail24485.d new file mode 100644 index 000000000000..15547cdcca72 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail24485.d @@ -0,0 +1,32 @@ +// https://issues.dlang.org/show_bug.cgi?id=24485 +/* +TEST_OUTPUT: +--- +fail_compilation/fail24485.d(25): Error: cannot implicitly convert expression `*a` of type `A` to `B` +fail_compilation/fail24485.d(31): Error: cannot implicitly convert expression `this.a` of type `A` to `B` + +--- +*/ + +struct A +{ + int i = 43; + this(ref A rhs) {} +} + +struct B +{ + int i = 42; +} + +ref B foo() +{ + auto a = new A; + return *a; +} + +struct C +{ + A a; + @property ref B b() { return a; } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/foreach_index_overflow.d b/gcc/testsuite/gdc.test/fail_compilation/foreach_index_overflow.d new file mode 100644 index 000000000000..aa6baa1274b9 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/foreach_index_overflow.d @@ -0,0 +1,28 @@ +/* +REQUIRED_ARGS: -de -m64 +TEST_OUTPUT: +--- +fail_compilation/foreach_index_overflow.d(19): Deprecation: foreach: loop index implicitly converted from `size_t` to `int` +fail_compilation/foreach_index_overflow.d(21): Deprecation: foreach: loop index implicitly converted from `size_t` to `ushort` +fail_compilation/foreach_index_overflow.d(24): Deprecation: foreach: loop index implicitly converted from `size_t` to `ubyte` +fail_compilation/foreach_index_overflow.d(26): Deprecation: foreach: loop index implicitly converted from `size_t` to `byte` +--- +*/ + +void main() +{ + enum { red, green, blue } + foreach (int i, color; [red, green, blue]) {} // OK + + int[] arr; + foreach (int index, element; arr[0 .. 0x8000_0000]) {} // OK + foreach (int index, element; arr[0 .. 0x8000_0001]) {} // error + foreach (ushort index, element; arr[0 .. 0x1_0000]) {} // OK + foreach (ushort index, element; arr[0 .. 0x1_0001]) {} // error + + int[257] data; + foreach (ubyte i, x; data[]) {} // error + foreach (ubyte i, x; data[0..256]) {} // OK + foreach (byte i, x; data[0..0x81]) {} // error + foreach (byte i, x; data[0..0x80]) {} // OK +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice12539.d b/gcc/testsuite/gdc.test/fail_compilation/ice12539.d index 8fab042266c9..ad68f23ec25d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice12539.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice12539.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/ice12539.d(15): Error: array index `[0]` is outside array bounds `[0 .. 0]` +fail_compilation/ice12539.d(15): Error: sequence index `[0]` is outside bounds `[0 .. 0]` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue24534.d b/gcc/testsuite/gdc.test/fail_compilation/issue24534.d new file mode 100644 index 000000000000..1689b6c5d1b2 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/issue24534.d @@ -0,0 +1,25 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/issue24534.d(12): Error: `goto` skips declaration of variable `issue24534.f1.y1` +fail_compilation/issue24534.d(13): declared here +fail_compilation/issue24534.d(20): Error: `goto` skips declaration of variable `issue24534.f2.y2` +fail_compilation/issue24534.d(22): declared here +--- +*/ +void f1(){ //always failed with error about skipping a declaration + int x1; + goto Label1; + int y1; + Label1: + int z1; +} + +void f2(){ //compiled fine before this bug was fixed + int x2; + goto Label2; + Dummy2: + int y2; + Label2: + int z2; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/lexer23465.d b/gcc/testsuite/gdc.test/fail_compilation/lexer23465.d index 526b7704c88a..4ea41a58af14 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/lexer23465.d +++ b/gcc/testsuite/gdc.test/fail_compilation/lexer23465.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/lexer23465.d(19): Error: char 0x1f37a not allowed in identifier +fail_compilation/lexer23465.d(19): Error: character 0x1f37a is not allowed as a continue character in an identifier fail_compilation/lexer23465.d(19): Error: character 0x1f37a is not a valid token fail_compilation/lexer23465.d(20): Error: character '\' is not a valid token fail_compilation/lexer23465.d(21): Error: unterminated /+ +/ comment diff --git a/gcc/testsuite/gdc.test/fail_compilation/ob1.d b/gcc/testsuite/gdc.test/fail_compilation/ob1.d new file mode 100644 index 000000000000..a3428f13f6d0 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/ob1.d @@ -0,0 +1,28 @@ +/* REQUIRED_ARGS: -preview=dip1021 +TEST_OUTPUT: +--- +fail_compilation/ob1.d(23): Error: variable `ob1.mars.t` has undefined state and cannot be read +--- + https://issues.dlang.org/show_bug.cgi?id=21923 +*/ + +@live: + +struct Handle +{ + private void* _handle; + + this(int n); + ~this(); + scope void bar(); + static void fido(ref Handle); +} + +void mars() +{ + auto t = Handle(10); + t.bar(); + Handle.fido(t); // moves t to fido(), then destructor runs, causing error + + scope u = Handle(10); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/obsolete_body.d b/gcc/testsuite/gdc.test/fail_compilation/obsolete_body.d new file mode 100644 index 000000000000..86d8bbc5d329 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/obsolete_body.d @@ -0,0 +1,11 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/obsolete_body.d(11): Error: usage of identifer `body` as a keyword is obsolete. Use `do` instead. +--- +*/ +@__edition_latest_do_not_use +module m; + +void test() +in { } body { } diff --git a/gcc/testsuite/gdc.test/fail_compilation/onemember_overloads.d b/gcc/testsuite/gdc.test/fail_compilation/onemember_overloads.d new file mode 100644 index 000000000000..40d23b3f01e5 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/onemember_overloads.d @@ -0,0 +1,38 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/onemember_overloads.d(29): Error: none of the overloads of `skipOver` are callable using argument types `()` +fail_compilation/onemember_overloads.d(25): Candidates are: `onemember_overloads.skipOver(string)` +fail_compilation/onemember_overloads.d(18): `skipOver(alias pred = (a, b) => a == b)` +fail_compilation/onemember_overloads.d(20): - Containing: `skipOver(Haystack, Needles...)(ref Haystack haystack, Needles needles)` +fail_compilation/onemember_overloads.d(21): - Containing: `skipOver(R)(ref R r1)` +fail_compilation/onemember_overloads.d(22): - Containing: `skipOver(R, Es...)(ref R r, Es es)` +fail_compilation/onemember_overloads.d(30): Error: template `t2` is not callable using argument types `!()()` +fail_compilation/onemember_overloads.d(33): Candidate is: `t2(T)` +fail_compilation/onemember_overloads.d(35): - Containing: `t2(string)` +fail_compilation/onemember_overloads.d(36): - Containing: `t2(int[])` +fail_compilation/onemember_overloads.d(37): - Containing: `t2(R)(R)` +--- +*/ + +template skipOver(alias pred = (a, b) => a == b) +{ + bool skipOver(Haystack, Needles...)(ref Haystack haystack, Needles needles) => true; + bool skipOver(R)(ref R r1) => true; + bool skipOver(R, Es...)(ref R r, Es es) => true; +} + +void skipOver(string); + +void main() +{ + skipOver(); + t2(); +} + +template t2(T) +{ + bool t2(string); + bool t2(int[]); + bool t2(R)(R); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/systemvariables_bool_union.d b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_bool_union.d new file mode 100644 index 000000000000..ca6e620a51a3 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_bool_union.d @@ -0,0 +1,22 @@ +/* +REQUIRED_ARGS: -de +TEST_OUTPUT: +--- +fail_compilation/systemvariables_bool_union.d(21): Deprecation: cannot access overlapped field `Box.b` with unsafe bit patterns in `@safe` code +--- +*/ + +// https://issues.dlang.org/show_bug.cgi?id=24477 + +bool schrodingersCat() @safe +{ + union Box + { + bool b; + ubyte y; + } + + Box u; + u.y = 2; + return u.b; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/systemvariables_void_init.d b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_void_init.d index 6f44093a8afd..ea0e55daff3d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/systemvariables_void_init.d +++ b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_void_init.d @@ -2,9 +2,13 @@ REQUIRED_ARGS: -preview=systemVariables TEST_OUTPUT: --- -fail_compilation/systemvariables_void_init.d(29): Error: `void` initializers for `@system` variables not allowed in safe functions -fail_compilation/systemvariables_void_init.d(30): Error: `void` initializers for `@system` variables not allowed in safe functions -fail_compilation/systemvariables_void_init.d(31): Error: `void` initializers for `@system` variables not allowed in safe functions +fail_compilation/systemvariables_void_init.d(48): Error: `void` initializers for types with unsafe bit patterns are not allowed in safe functions +fail_compilation/systemvariables_void_init.d(49): Error: `void` initializers for types with unsafe bit patterns are not allowed in safe functions +fail_compilation/systemvariables_void_init.d(50): Error: `void` initializers for types with unsafe bit patterns are not allowed in safe functions +fail_compilation/systemvariables_void_init.d(51): Error: a `bool` must be 0 or 1, so void intializing it is not allowed in safe functions +fail_compilation/systemvariables_void_init.d(52): Error: a `bool` must be 0 or 1, so void intializing it is not allowed in safe functions +fail_compilation/systemvariables_void_init.d(53): Error: `void` initializers for types with unsafe bit patterns are not allowed in safe functions +fail_compilation/systemvariables_void_init.d(54): Error: `void` initializers for types with unsafe bit patterns are not allowed in safe functions --- */ @@ -24,9 +28,50 @@ enum E : C x = C.init, } +enum B : bool +{ + x, +} + +struct SB +{ + bool x; +} + +struct SSB +{ + SB sb; +} + void main() @safe { S s = void; C c = void; E e = void; + const bool b = void; + B bb = void; + SB sb = void; + SSB ssb = void; +} + +// The following test is reduced from Phobos. The compiler generates this `opAssign`: +// (CopyPreventer __swap2 = void;) , __swap2 = this , (this = p , __swap2.~this()); +// The compiler would give an error about void initialization a struct with a bool, +// but it can be trusted in this case because it's a compiler generated temporary. +auto staticArray(T)(T a) @safe +{ + T c; + c = a; +} + +void assignmentTest() @safe +{ + static struct CopyPreventer + { + bool on; + this(this) @safe {} + ~this() { } + } + + staticArray(CopyPreventer()); } diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22977.d b/gcc/testsuite/gdc.test/fail_compilation/test22977.d new file mode 100644 index 000000000000..87bb19cc711c --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test22977.d @@ -0,0 +1,56 @@ +/* +REQUIRED_ARGS: -preview=dip1000 +TEST_OUTPUT: +--- +fail_compilation/test22977.d(16): Error: escaping local variable through nested function `scfunc` +fail_compilation/test22977.d(22): Error: escaping reference to stack allocated value returned by `scfunc2()` +--- +*/ + +// Issue 22977 - [dip1000] can escape scope pointer returned by nested function +// https://issues.dlang.org/show_bug.cgi?id=22977 + +auto p0(scope string s) @safe +{ + string scfunc() { return s; } + return scfunc(); +} + +auto p1(scope string s) @safe +{ + ref string scfunc2() { return s; } + return scfunc2(); +} + +// Reduced from Mir +struct Tuple(T...) +{ + T expand; +} + +auto autoExpandAndForward(alias value)() +{ + return value.expand[0]; +} + +struct MapIterator +{ + int* p; + int* foo() scope + { + auto t = Tuple!(int*)(p); + return autoExpandAndForward!t; + } +} + +// Reduced from Phobos +float partial(alias fun)() +{ + return fun(); +} + +auto partialFunction() @safe +{ + int function() f = () => 0; + return &partial!(f); +} diff --git a/gcc/testsuite/gdc.test/runnable/funclit.d b/gcc/testsuite/gdc.test/runnable/funclit.d index c4b70dcb5098..253df8feec11 100644 --- a/gcc/testsuite/gdc.test/runnable/funclit.d +++ b/gcc/testsuite/gdc.test/runnable/funclit.d @@ -1302,6 +1302,17 @@ void test16271() T!().auf() = 2; assert(T!().x == 2); } +// https://issues.dlang.org/show_bug.cgi?id=24525 +void test24525() +{ + int a; + auto ref () {return a;}() = 1; + assert(a == 1); + + ref () {return a;}() = 2; + assert(a == 2); +} + /***************************************************/ int main() @@ -1361,6 +1372,7 @@ int main() test14745(); test15794(); test16271(); + test24525(); printf("Success\n"); return 0; diff --git a/gcc/testsuite/gdc.test/runnable/future.d b/gcc/testsuite/gdc.test/runnable/future.d index 1a91d305357e..e0ef46639540 100644 --- a/gcc/testsuite/gdc.test/runnable/future.d +++ b/gcc/testsuite/gdc.test/runnable/future.d @@ -1,7 +1,8 @@ /* PERMUTE_ARGS: TEST_OUTPUT: --- -runnable/future.d(15): Deprecation: `@__future` base class method `future.A.msg` is being overridden by `future.B.msg`; rename the latter +runnable/future.d(16): Deprecation: method `future.B.msg` implicitly overrides `@__future` base class method; rename the former +runnable/future.d(11): base method `future.A.msg` defined here --- */ diff --git a/gcc/testsuite/gdc.test/runnable/imports/issue18919b.d b/gcc/testsuite/gdc.test/runnable/imports/issue18919b.d index 4278f7f5cdee..b009298e66f4 100644 --- a/gcc/testsuite/gdc.test/runnable/imports/issue18919b.d +++ b/gcc/testsuite/gdc.test/runnable/imports/issue18919b.d @@ -248,3 +248,9 @@ void func12(const(char)*[] args = [baseName(__FILE__.ptr), printf(" %s", arg); printf("\n"); } + +// https://issues.dlang.org/show_bug.cgi?id=24519 +void func13(string file = __FILE__[]) +{ + printf("%s: %s\n", __FUNCTION__.ptr, file.ptr); +} diff --git a/gcc/testsuite/gdc.test/runnable/issue18919.d b/gcc/testsuite/gdc.test/runnable/issue18919.d index 815e018d649c..9f3df62a7be3 100644 --- a/gcc/testsuite/gdc.test/runnable/issue18919.d +++ b/gcc/testsuite/gdc.test/runnable/issue18919.d @@ -20,10 +20,13 @@ imports.issue18919b.func9.fp: issue18919b.d:216 imports.issue18919b imports.issue18919b.func10: expr1=imports.issue18919b, expr2=imports.issue18919b imports.issue18919b.func11: issue18919b.d:233 imports.issue18919b imports.issue18919b.func12: issue18919.d issue18919.main void issue18919.main() issue18919 +imports.issue18919b.func13: runnable/issue18919.d --- */ import imports.issue18919b; +#line 26 + void main() { func1(); @@ -44,4 +47,5 @@ void main() func10(); func11(); func12(); + func13(); } diff --git a/gcc/testsuite/gdc.test/runnable/test15.d b/gcc/testsuite/gdc.test/runnable/test15.d index b4acc235289f..bb9fc875f7b2 100644 --- a/gcc/testsuite/gdc.test/runnable/test15.d +++ b/gcc/testsuite/gdc.test/runnable/test15.d @@ -1420,7 +1420,7 @@ void test19758() /************************************/ // https://issues.dlang.org/show_bug.cgi?id=19968 -@safe void test19968() +void test19968() { int[2] array = [16, 678]; union U { int i; bool b; } diff --git a/gcc/testsuite/gdc.test/runnable/test17338.d b/gcc/testsuite/gdc.test/runnable/test17338.d index 1c937be77e60..746a1df3c6b3 100644 --- a/gcc/testsuite/gdc.test/runnable/test17338.d +++ b/gcc/testsuite/gdc.test/runnable/test17338.d @@ -3,9 +3,6 @@ // COMDAT folding increases runtime by > 80x // REQUIRED_ARGS(windows): -L/OPT:NOICF -// Apparently omf or optlink does not support more than 32767 symbols. -// DISABLED: win32 - // Generate \sum_{i=0}^{14} 2^i = 32767 template instantiations // (each with 3 sections) to use more than 64Ki sections in total. diff --git a/gcc/testsuite/gdc.test/runnable/test24029.c b/gcc/testsuite/gdc.test/runnable/test24029.c deleted file mode 100644 index 145f2c28725a..000000000000 --- a/gcc/testsuite/gdc.test/runnable/test24029.c +++ /dev/null @@ -1,23 +0,0 @@ -// https://issues.dlang.org/show_bug.cgi?id=24029 - -int x = 0; -int y = 0; - -void a() -{ - (__extension__ ({ x += 2; })); // test.a.__dgliteral1 -} - -void b() -{ - (__extension__ ({ y += 1; })); // test.b.__dgliteral1 -} - -int main(void) -{ - a(); - b(); - __check(x == 2); - __check(y == 1); - return 0; -} diff --git a/gcc/testsuite/gdc.test/runnable/test24498.d b/gcc/testsuite/gdc.test/runnable/test24498.d new file mode 100644 index 000000000000..6c48e269f171 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test24498.d @@ -0,0 +1,21 @@ +import core.memory; + +void main() +{ + { + int[][] a = new int[][](2, 2); + assert(!(GC.getAttr(a.ptr) & GC.BlkAttr.NO_SCAN)); + assert(GC.getAttr(a[0].ptr) & GC.BlkAttr.NO_SCAN); + } + { + void*[][] a = new void*[][](2, 2); + assert(!(GC.getAttr(a.ptr) & GC.BlkAttr.NO_SCAN)); + assert(!(GC.getAttr(a[0].ptr) & GC.BlkAttr.NO_SCAN)); + } + { + int[][][] a = new int[][][](2, 2); + assert(!(GC.getAttr(a.ptr) & GC.BlkAttr.NO_SCAN)); + assert(!(GC.getAttr(a[0].ptr) & GC.BlkAttr.NO_SCAN)); + assert(a[0][0].ptr is null); + } +} diff --git a/gcc/testsuite/gdc.test/runnable/testthread.d b/gcc/testsuite/gdc.test/runnable/testthread.d index 139a891072cd..811b6c222201 100644 --- a/gcc/testsuite/gdc.test/runnable/testthread.d +++ b/gcc/testsuite/gdc.test/runnable/testthread.d @@ -3,15 +3,6 @@ import core.stdc.stdio; import core.thread; -version (CRuntime_DigitalMars) -{ - extern (C) - { - extern int _tlsstart; - extern int _tlsend; - } -} - int tlsx; class Foo @@ -25,8 +16,6 @@ class Foo tlsx = 5; Thread t = Thread.getThis(); - version (CRuntime_DigitalMars) - printf("thread ptr=%p, %p &tlsx = %p %p\n", t, &_tlsstart, &tlsx, &_tlsend); x = 3; printf("-bar()\n"); } diff --git a/gcc/testsuite/gdc.test/runnable_cxx/cpp_abi_tests.d b/gcc/testsuite/gdc.test/runnable_cxx/cpp_abi_tests.d index c0f4e6dd7806..5d4bc99c1bd4 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/cpp_abi_tests.d +++ b/gcc/testsuite/gdc.test/runnable_cxx/cpp_abi_tests.d @@ -272,7 +272,6 @@ void main() foreach(byte val; values!byte()) check(val); foreach(ubyte val; values!ubyte()) check(val); foreach(char val; values!char()) check(val); -version(CppRuntime_DigitalMars){} else version(CppRuntime_Microsoft) { // TODO: figure out how to detect VS2013 which doesn't support char16_t/char32_t diff --git a/gcc/testsuite/gdc.test/runnable_cxx/cppa.d b/gcc/testsuite/gdc.test/runnable_cxx/cppa.d index cb268af06223..34c295590e39 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/cppa.d +++ b/gcc/testsuite/gdc.test/runnable_cxx/cppa.d @@ -8,9 +8,6 @@ // N.B MSVC doesn't have a C++11 switch, but it defaults to the latest fully-supported standard -// Broken for unknown reasons since the OMF => MsCOFF switch -// DISABLED: win32omf - import core.stdc.stdio; import core.stdc.stdarg; import core.stdc.config; @@ -908,9 +905,7 @@ void fuzz2() } //////// -version(CppRuntime_DigitalMars) - enum UNICODE = false; -else version(CppRuntime_Microsoft) +version(CppRuntime_Microsoft) enum UNICODE = false; //VS2013 doesn't support them else enum UNICODE = true; diff --git a/gcc/testsuite/gdc.test/runnable_cxx/externmangle.d b/gcc/testsuite/gdc.test/runnable_cxx/externmangle.d index ef132dcca72d..266cad9f6c12 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/externmangle.d +++ b/gcc/testsuite/gdc.test/runnable_cxx/externmangle.d @@ -239,39 +239,31 @@ void test39() extern(C++, "foo", "bar", "baz") int doStuff(int); -version(CppRuntime_DigitalMars) // DMC doesn't support c++11 -{ - void test40() {} - void test41() {} -} -else -{ - void test40(); +void test40(); - void foovargs(T...)(T args) +void foovargs(T...)(T args) +{ + static if (is(T[0] == char*)) { - static if (is(T[0] == char*)) - { - assert(*args[0] == 'a'); - } - else - { - float ret = args[0] + args[1]; - assert(ret == 3.0f); - } + assert(*args[0] == 'a'); } - - alias FooVargs = foovargs!(int, float); - alias FooVargs2 = foovargs!(char*); - - void test41(); - void make_shared_poc(T, Args...)(ref Args args) + else { - assert(args[0] + args[1] == 3); + float ret = args[0] + args[1]; + assert(ret == 3.0f); } - alias Make_Shared_Poc = make_shared_poc!(int, int, int); } +alias FooVargs = foovargs!(int, float); +alias FooVargs2 = foovargs!(char*); + +void test41(); +void make_shared_poc(T, Args...)(ref Args args) +{ + assert(args[0] + args[1] == 3); +} +alias Make_Shared_Poc = make_shared_poc!(int, int, int); + void main() { test1(Foo!int()); diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp7925.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp7925.cpp index f3a9a8552a94..282faec797aa 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp7925.cpp +++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp7925.cpp @@ -90,14 +90,10 @@ void runCPPTests() int (C2::*fp1)(int) = &C2::f1; int (C2::*fp2)(int, int) = &C2::f2; int (C2::*fp3)(int, int) = &C2::f3; -#ifndef __DMC__ int (C2::*fp4)(int, ...) = &C2::f4; -#endif assert((c2->*(fp0))() == 100); assert((c2->*(fp1))(1) == 101); assert((c2->*(fp2))(20, 3) == 123); assert((c2->*(fp3))(20, 3) == 123); -#ifndef __DMC__ assert((c2->*(fp4))(20, 3, 0) == 123); -#endif } diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp_abi_tests.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp_abi_tests.cpp index e1dcc28b8b1d..cbde23378f2b 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp_abi_tests.cpp +++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp_abi_tests.cpp @@ -10,9 +10,7 @@ namespace std struct test19248 {int a;}; }; -#ifdef __DMC__ -// DMC doesn't support c++11 -#elif defined (_MSC_VER) && _MSC_VER <= 1800 +#if defined (_MSC_VER) && _MSC_VER <= 1800 // MSVC2013 doesn't support char16_t/char32_t #else #define TEST_UNICODE @@ -26,11 +24,7 @@ struct S18784 S18784::S18784(int n) : i(n) {} -#ifdef __DMC__ // DMC doesn't support c++11 -template -#else template -#endif struct SPack { int i; diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp index 83667cbddc78..f91dfe8fb33f 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp +++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp @@ -374,9 +374,7 @@ wchar_t f13289_cpp_wchar_t(wchar_t ch) return ch; } } -#ifdef __DMC__ -// DMC doesn't support c++11 -#elif defined (_MSC_VER) //&& _MSC_VER <= 1800 +#if defined (_MSC_VER) //&& _MSC_VER <= 1800 // MSVC2013 doesn't support char16_t/char32_t #else #define TEST_UNICODE diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/externmangle.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/externmangle.cpp index 37c98ea8fdd3..df10a9cd88c5 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/externmangle.cpp +++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/externmangle.cpp @@ -426,7 +426,6 @@ namespace foo } } -#ifndef __DMC__ // DMC doesn't support c++11 template void foovargs(T... args); void test40() @@ -446,4 +445,3 @@ void test41() make_shared_poc(a, b); } -#endif diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/test20652.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/test20652.cpp index 91ab66aaf191..b35b3f51b150 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/test20652.cpp +++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/test20652.cpp @@ -1,6 +1,3 @@ -#if defined(__DMC__) // DMC doesn't support immintrin.h -#else - #include // Inline the typedef of __m128 instead of including immintrin.h. @@ -30,5 +27,3 @@ void test20652(const __m128& a) assert(b.array[2] == 1); assert(b.array[3] == 1); } - -#endif diff --git a/gcc/testsuite/gdc.test/runnable_cxx/test20652.d b/gcc/testsuite/gdc.test/runnable_cxx/test20652.d index 68bb0a711e43..a4962f664e7c 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/test20652.d +++ b/gcc/testsuite/gdc.test/runnable_cxx/test20652.d @@ -3,11 +3,7 @@ import core.simd; -version (CRuntime_DigitalMars) // DMC doesn't support immintrin.h -{ - void main() {} -} -else static if (!__traits(compiles, float4)) // No __vector support +static if (!__traits(compiles, float4)) // No __vector support { void main() {} } diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 46d435ef8dba..77e8562abcc3 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -c11e1d1708646c9ac81ac2aafb57fa1ef5d289ad +07bc5b9b3c81cc0d4314e0040de981124b363ea5 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/libphobos/libdruntime/core/attribute.d b/libphobos/libdruntime/core/attribute.d index 79ad25ab358b..95a67ea219d6 100644 --- a/libphobos/libdruntime/core/attribute.d +++ b/libphobos/libdruntime/core/attribute.d @@ -2,6 +2,21 @@ * This module contains UDA's (User Defined Attributes) either used in * the runtime or special UDA's recognized by compiler. * + * $(SCRIPT inhibitQuickIndex = 1;) + * $(BOOKTABLE Cheat Sheet, + * $(THEAD Attribute Name, Linkage, Description) + * $(TROW $(LREF gnuAbiTag), C++, + * Declares an ABI tag on a C++ symbol.) + * $(TROW $(LREF mustuse),, + * Ensures that values of a struct or union type are not discarded.) + * $(TROW $(LREF optional), Objective-C, + * Makes an Objective-C interface method optional.) + * $(TROW $(LREF selector), Objective-C, + * Attaches an Objective-C selector to a method.) + * $(TROW $(LREF weak),, + * Specifies that a global symbol should be emitted with weak linkage.) + * ) + * * Copyright: Copyright Jacob Carlborg 2015. * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Authors: Jacob Carlborg diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d index 272ee1e1ba4b..4405dec26398 100644 --- a/libphobos/libdruntime/core/demangle.d +++ b/libphobos/libdruntime/core/demangle.d @@ -2867,56 +2867,6 @@ unittest assert(demangle(aggr.mangleof) == "pure nothrow @nogc @safe void " ~ parent ~ "().aggr(" ~ parent ~ "().S!(noreturn).S)"); } -/* - * Expand an OMF, DMD-generated compressed identifier into its full form - * - * This function only has a visible effect for OMF binaries (Win32), - * as compression is otherwise not used. - * - * See_Also: `compiler/src/dmd/backend/compress.d` - */ -string decodeDmdString( const(char)[] ln, ref size_t p ) nothrow pure @safe -{ - string s; - uint zlen, zpos; - - // decompress symbol - while ( p < ln.length ) - { - int ch = cast(ubyte) ln[p++]; - if ( (ch & 0xc0) == 0xc0 ) - { - zlen = (ch & 0x7) + 1; - zpos = ((ch >> 3) & 7) + 1; // + zlen; - if ( zpos > s.length ) - break; - s ~= s[$ - zpos .. $ - zpos + zlen]; - } - else if ( ch >= 0x80 ) - { - if ( p >= ln.length ) - break; - int ch2 = cast(ubyte) ln[p++]; - zlen = (ch2 & 0x7f) | ((ch & 0x38) << 4); - if ( p >= ln.length ) - break; - int ch3 = cast(ubyte) ln[p++]; - zpos = (ch3 & 0x7f) | ((ch & 7) << 7); - if ( zpos > s.length ) - break; - s ~= s[$ - zpos .. $ - zpos + zlen]; - } - else if ( Demangle!().isAlpha(cast(char)ch) || Demangle!().isDigit(cast(char)ch) || ch == '_' ) - s ~= cast(char) ch; - else - { - p--; - break; - } - } - return s; -} - // locally purified for internal use here only extern (C) private { diff --git a/libphobos/libdruntime/core/internal/parseoptions.d b/libphobos/libdruntime/core/internal/parseoptions.d index ac0eb826b355..2bf1da2fbfa5 100644 --- a/libphobos/libdruntime/core/internal/parseoptions.d +++ b/libphobos/libdruntime/core/internal/parseoptions.d @@ -290,32 +290,8 @@ do assert(n > 4 && n < fmt.length); int nscanned; - version (CRuntime_DigitalMars) - { - /* Older sscanf's in snn.lib can write to its first argument, causing a crash - * if the string is in readonly memory. Recent updates to DMD - * https://github.com/dlang/dmd/pull/6546 - * put string literals in readonly memory. - * Although sscanf has been fixed, - * http://ftp.digitalmars.com/snn.lib - * this workaround is here so it still works with the older snn.lib. - */ - // Create mutable copy of str - const length = str.length; - char* mptr = cast(char*)malloc(length + 1); - assert(mptr); - memcpy(mptr, str.ptr, length); - mptr[length] = 0; - const result = sscanf(mptr, fmt.ptr, &res, &nscanned); - free(mptr); - if (result < 1) - return parseError("a float", optname, str, errName); - } - else - { - if (sscanf(str.ptr, fmt.ptr, &res, &nscanned) < 1) - return parseError("a float", optname, str, errName); - } + if (sscanf(str.ptr, fmt.ptr, &res, &nscanned) < 1) + return parseError("a float", optname, str, errName); str = str[nscanned .. $]; return true; } diff --git a/libphobos/libdruntime/core/stdc/assert_.d b/libphobos/libdruntime/core/stdc/assert_.d index c6d9d9f6cc27..ac237d9c8975 100644 --- a/libphobos/libdruntime/core/stdc/assert_.d +++ b/libphobos/libdruntime/core/stdc/assert_.d @@ -30,14 +30,7 @@ extern (C): nothrow: @nogc: -version (CRuntime_DigitalMars) -{ - /*** - * Assert failure function in the Digital Mars C library. - */ - noreturn _assert(const(void)* exp, const(void)* file, uint line); -} -else version (CRuntime_Microsoft) +version (CRuntime_Microsoft) { /*** * Assert failure function in the Microsoft C library. diff --git a/libphobos/libdruntime/core/stdc/errno.d b/libphobos/libdruntime/core/stdc/errno.d index ddec70f7af3c..0430e6b33e99 100644 --- a/libphobos/libdruntime/core/stdc/errno.d +++ b/libphobos/libdruntime/core/stdc/errno.d @@ -43,15 +43,7 @@ version (X86_64) version = X86_Any; nothrow: @nogc: -version (CRuntime_DigitalMars) -{ - extern (C) - { - ref int _errno(); - alias errno = _errno; - } -} -else version (CRuntime_Microsoft) +version (CRuntime_Microsoft) { extern (C) { @@ -172,93 +164,7 @@ else extern (C): -version (CRuntime_DigitalMars) -{ - enum EPERM = 1; /// Operation not permitted - enum ENOENT = 2; /// No such file or directory - enum ESRCH = 3; /// No such process - enum EINTR = 4; /// Interrupted system call - enum EIO = 5; /// I/O error - enum ENXIO = 6; /// No such device or address - enum E2BIG = 7; /// Argument list too long - enum ENOEXEC = 8; /// Exec format error - enum EBADF = 9; /// Bad file number - enum ECHILD = 10; /// No child processes - enum EAGAIN = 11; /// Try again - enum ENOMEM = 12; /// Out of memory - enum EACCES = 13; /// Permission denied - enum EFAULT = 14; /// Bad address - enum EBUSY = 16; /// Device or resource busy - enum EEXIST = 17; /// File exists - enum EXDEV = 18; /// Cross-device link - enum ENODEV = 19; /// No such device - enum ENOTDIR = 20; /// Not a directory - enum EISDIR = 21; /// Is a directory - enum EINVAL = 22; /// Invalid argument - enum ENFILE = 23; /// File table overflow - enum EMFILE = 24; /// Too many open files - enum ENOTTY = 25; /// Not a typewriter - enum EFBIG = 27; /// File too large - enum ENOSPC = 28; /// No space left on device - enum ESPIPE = 29; /// Illegal seek - enum EROFS = 30; /// Read-only file system - enum EMLINK = 31; /// Too many links - enum EPIPE = 32; /// Broken pipe - enum EDOM = 33; /// Math argument out of domain of func - enum ERANGE = 34; /// Math result not representable - enum EDEADLK = 36; /// Resource deadlock would occur - enum ENAMETOOLONG = 38; /// File name too long - enum ENOLCK = 39; /// No record locks available - enum ENOSYS = 40; /// Function not implemented - enum ENOTEMPTY = 41; /// Directory not empty - enum EILSEQ = 42; /// Illegal byte sequence - enum EDEADLOCK = EDEADLK; /// Resource deadlock would occur - - // POSIX compatibility - // See_Also: https://docs.microsoft.com/en-us/cpp/c-runtime-library/errno-constants - enum EADDRINUSE = 100; - enum EADDRNOTAVAIL = 101; - enum EAFNOSUPPORT = 102; - enum EALREADY = 103; - enum EBADMSG = 104; - enum ECANCELED = 105; - enum ECONNABORTED = 106; - enum ECONNREFUSED = 107; - enum ECONNRESET = 108; - enum EDESTADDRREQ = 109; - enum EHOSTUNREACH = 110; - enum EIDRM = 111; - enum EINPROGRESS = 112; - enum EISCONN = 113; - enum ELOOP = 114; - enum EMSGSIZE = 115; - enum ENETDOWN = 116; - enum ENETRESET = 117; - enum ENETUNREACH = 118; - enum ENOBUFS = 119; - enum ENODATA = 120; - enum ENOLINK = 121; - enum ENOMSG = 122; - enum ENOPROTOOPT = 123; - enum ENOSR = 124; - enum ENOSTR = 125; - enum ENOTCONN = 126; - enum ENOTRECOVERABLE = 127; - enum ENOTSOCK = 128; - enum ENOTSUP = 129; - enum EOPNOTSUPP = 130; - enum EOTHER = 131; - enum EOVERFLOW = 132; - enum EOWNERDEAD = 133; - enum EPROTO = 134; - enum EPROTONOSUPPORT = 135; - enum EPROTOTYPE = 136; - enum ETIME = 137; - enum ETIMEDOUT = 138; - enum ETXTBSY = 139; - enum EWOULDBLOCK = 140; -} -else version (CRuntime_Microsoft) +version (CRuntime_Microsoft) { enum EPERM = 1; /// Operation not permitted enum ENOENT = 2; /// No such file or directory diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d index a7364c0a211a..6cd75f3a791e 100644 --- a/libphobos/libdruntime/core/stdc/fenv.d +++ b/libphobos/libdruntime/core/stdc/fenv.d @@ -180,17 +180,6 @@ version (GNUFP) static assert(0, "Unimplemented architecture"); } } -else version (CRuntime_DigitalMars) -{ - struct fenv_t - { - ushort status; - ushort control; - ushort round; - ushort[2] reserved; - } - alias fexcept_t = int; -} else version (CRuntime_Microsoft) { struct fenv_t @@ -872,12 +861,6 @@ version (GNUFP) /// enum FE_DFL_ENV = cast(fenv_t*)(-1); } -else version (CRuntime_DigitalMars) -{ - private extern __gshared fenv_t _FE_DFL_ENV; - /// - enum fenv_t* FE_DFL_ENV = &_FE_DFL_ENV; -} else version (CRuntime_Microsoft) { private extern __gshared fenv_t _Fenv0; diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d index c5eaf79a8273..e54d5813995d 100644 --- a/libphobos/libdruntime/core/stdc/math.d +++ b/libphobos/libdruntime/core/stdc/math.d @@ -284,102 +284,7 @@ version (none) pure int isunordered(real x, real y); } -version (CRuntime_DigitalMars) -{ - enum - { - /// - FP_NANS = 0, - /// - FP_NANQ = 1, - /// - FP_INFINITE = 2, - /// - FP_NORMAL = 3, - /// - FP_SUBNORMAL = 4, - /// - FP_ZERO = 5, - /// - FP_NAN = FP_NANQ, - /// - FP_EMPTY = 6, - /// - FP_UNSUPPORTED = 7, - } - - enum - { - /// - FP_FAST_FMA = 0, - /// - FP_FAST_FMAF = 0, - /// - FP_FAST_FMAL = 0, - } - - pure uint __fpclassify_f(float x); - pure uint __fpclassify_d(double x); - pure uint __fpclassify_ld(real x); - - //int fpclassify(real-floating x); - /// - pragma(mangle, "__fpclassify_f") pure int fpclassify(float x); - /// - pragma(mangle, "__fpclassify_d") pure int fpclassify(double x); - /// - pragma(mangle, real.sizeof == double.sizeof ? "__fpclassify_d" : "__fpclassify_ld") - pure int fpclassify(real x); - - extern (D) - { - //int isfinite(real-floating x); - /// - pure int isfinite(float x) { return fpclassify(x) >= FP_NORMAL; } - /// - pure int isfinite(double x) { return fpclassify(x) >= FP_NORMAL; } - /// - pure int isfinite(real x) { return fpclassify(x) >= FP_NORMAL; } - - //int isinf(real-floating x); - /// - pure int isinf(float x) { return fpclassify(x) == FP_INFINITE; } - /// - pure int isinf(double x) { return fpclassify(x) == FP_INFINITE; } - /// - pure int isinf(real x) { return fpclassify(x) == FP_INFINITE; } - - //int isnan(real-floating x); - /// - pure int isnan(float x) { return fpclassify(x) <= FP_NANQ; } - /// - pure int isnan(double x) { return fpclassify(x) <= FP_NANQ; } - /// - pure int isnan(real x) { return fpclassify(x) <= FP_NANQ; } - - //int isnormal(real-floating x); - /// - pure int isnormal(float x) { return fpclassify(x) == FP_NORMAL; } - /// - pure int isnormal(double x) { return fpclassify(x) == FP_NORMAL; } - /// - pure int isnormal(real x) { return fpclassify(x) == FP_NORMAL; } - - //int signbit(real-floating x); - /// - pure int signbit(float x) { return (cast(short*)&(x))[1] & 0x8000; } - /// - pure int signbit(double x) { return (cast(short*)&(x))[3] & 0x8000; } - /// - pure int signbit(real x) - { - return (real.sizeof == double.sizeof) - ? (cast(short*)&(x))[3] & 0x8000 - : (cast(short*)&(x))[4] & 0x8000; - } - } -} -else version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) only +version (CRuntime_Microsoft) // fully supported since MSVCRT 12 (VS 2013) only { version (all) // legacy stuff to be removed in the future { diff --git a/libphobos/libdruntime/core/stdc/stdint.d b/libphobos/libdruntime/core/stdc/stdint.d index 476c42f08ee4..1776269378f8 100644 --- a/libphobos/libdruntime/core/stdc/stdint.d +++ b/libphobos/libdruntime/core/stdc/stdint.d @@ -49,16 +49,8 @@ version (Windows) alias int16_t = short; /// alias uint8_t = ubyte; /// alias uint16_t = ushort; /// - version (CRuntime_DigitalMars) - { - alias int32_t = cpp_long; /// - alias uint32_t = cpp_ulong; /// - } - else - { - alias int32_t = int; /// - alias uint32_t = uint; /// - } + alias int32_t = int; /// + alias uint32_t = uint; /// alias int64_t = long; /// alias uint64_t = ulong; /// diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d index 1fc046163ee7..8afb68f85851 100644 --- a/libphobos/libdruntime/core/stdc/stdio.d +++ b/libphobos/libdruntime/core/stdc/stdio.d @@ -52,34 +52,7 @@ extern (C): nothrow: @nogc: -version (CRuntime_DigitalMars) -{ - enum - { - /// - BUFSIZ = 0x4000, - /// - EOF = -1, - /// - FOPEN_MAX = 20, - /// - FILENAME_MAX = 256, // 255 plus NULL - /// - TMP_MAX = 32767, - /// - SYS_OPEN = 20, // non-standard - } - - /// - enum int _NFILE = 60; // non-standard - /// - enum string _P_tmpdir = "\\"; // non-standard - /// - enum wstring _wP_tmpdir = "\\"; // non-standard - /// - enum int L_tmpnam = _P_tmpdir.length + 12; -} -else version (CRuntime_Microsoft) +version (CRuntime_Microsoft) { enum { @@ -403,28 +376,7 @@ enum SEEK_END } -version (CRuntime_DigitalMars) -{ - /// - alias c_long fpos_t; - - /// - struct _iobuf - { - char* _ptr; - int _cnt; - char* _base; - int _flag; - int _file; - int _charbuf; - int _bufsiz; - char* __tmpnum; - } - - /// - alias shared(_iobuf) FILE; -} -else version (CRuntime_Microsoft) +version (CRuntime_Microsoft) { /// alias long fpos_t; @@ -926,52 +878,7 @@ enum _F_TERM = 0x0200, // non-standard } -version (CRuntime_DigitalMars) -{ - enum - { - /// - _IOFBF = 0, - /// - _IOLBF = 0x40, - /// - _IONBF = 4, - /// - _IOREAD = 1, // non-standard - /// - _IOWRT = 2, // non-standard - /// - _IOMYBUF = 8, // non-standard - /// - _IOEOF = 0x10, // non-standard - /// - _IOERR = 0x20, // non-standard - /// - _IOSTRG = 0x40, // non-standard - /// - _IORW = 0x80, // non-standard - /// - _IOTRAN = 0x100, // non-standard - /// - _IOAPP = 0x200, // non-standard - } - - extern shared void function() _fcloseallp; - - private extern shared FILE[_NFILE] _iob; - - /// - enum stdin = &_iob[0]; - /// - enum stdout = &_iob[1]; - /// - enum stderr = &_iob[2]; - /// - enum stdaux = &_iob[3]; - /// - enum stdprn = &_iob[4]; -} -else version (CRuntime_Microsoft) +version (CRuntime_Microsoft) { enum { @@ -1539,55 +1446,7 @@ size_t fwrite(scope const void* ptr, size_t size, size_t nmemb, FILE* stream); c_long ftell(FILE* stream); } -version (CRuntime_DigitalMars) -{ - // No unsafe pointer manipulation. - extern (D) @trusted - { - /// - void rewind()(FILE* stream) { fseek(stream,0L,SEEK_SET); stream._flag= stream._flag & ~_IOERR; } - /// - pure void clearerr()(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); } - /// - pure int feof()(FILE* stream) { return stream._flag&_IOEOF; } - /// - pure int ferror()(FILE* stream) { return stream._flag&_IOERR; } - /// - pure int fileno()(FILE* stream) { return stream._file; } - } - /// - pragma(printf) - int _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...); - /// - alias _snprintf snprintf; - - /// - pragma(printf) - int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); - /// - alias _vsnprintf vsnprintf; - - // - // Digital Mars under-the-hood C I/O functions. Uses _iobuf* for the - // unshared version of FILE*, usable when the FILE is locked. - // - - /// - int _fputc_nlock(int c, _iobuf* fp); - /// - int _fputwc_nlock(int c, _iobuf* fp); - /// - int _fgetc_nlock(_iobuf* fp); - /// - int _fgetwc_nlock(_iobuf* fp); - /// - int __fp_lock(FILE* fp); - /// - void __fp_unlock(FILE* fp); - /// - int setmode(int fd, int mode); -} -else version (CRuntime_Microsoft) +version (CRuntime_Microsoft) { // No unsafe pointer manipulation. @trusted @@ -2073,130 +1932,7 @@ else /// void perror(scope const char* s); -version (CRuntime_DigitalMars) -{ - version (none) - import core.sys.windows.windows : HANDLE, _WaitSemaphore, _ReleaseSemaphore; - else - { - // too slow to import windows - private alias void* HANDLE; - private void _WaitSemaphore(int iSemaphore); - private void _ReleaseSemaphore(int iSemaphore); - } - - enum - { - /// - FHND_APPEND = 0x04, - /// - FHND_DEVICE = 0x08, - /// - FHND_TEXT = 0x10, - /// - FHND_BYTE = 0x20, - /// - FHND_WCHAR = 0x40, - } - - private enum _MAX_SEMAPHORES = 10 + _NFILE; - private enum _semIO = 3; - - private extern __gshared short[_MAX_SEMAPHORES] _iSemLockCtrs; - private extern __gshared int[_MAX_SEMAPHORES] _iSemThreadIds; - private extern __gshared int[_MAX_SEMAPHORES] _iSemNestCount; - private extern __gshared HANDLE[_NFILE] _osfhnd; - extern shared ubyte[_NFILE] __fhnd_info; - - // this is copied from semlock.h in DMC's runtime. - private void LockSemaphore()(uint num) - { - asm nothrow @nogc - { - mov EDX, num; - lock; - inc _iSemLockCtrs[EDX * 2]; - jz lsDone; - push EDX; - call _WaitSemaphore; - add ESP, 4; - } - - lsDone: {} - } - - // this is copied from semlock.h in DMC's runtime. - private void UnlockSemaphore()(uint num) - { - asm nothrow @nogc - { - mov EDX, num; - lock; - dec _iSemLockCtrs[EDX * 2]; - js usDone; - push EDX; - call _ReleaseSemaphore; - add ESP, 4; - } - - usDone: {} - } - - // This converts a HANDLE to a file descriptor in DMC's runtime - /// - int _handleToFD()(HANDLE h, int flags) - { - LockSemaphore(_semIO); - scope(exit) UnlockSemaphore(_semIO); - - foreach (fd; 0 .. _NFILE) - { - if (!_osfhnd[fd]) - { - _osfhnd[fd] = h; - __fhnd_info[fd] = cast(ubyte)flags; - return fd; - } - } - - return -1; - } - - /// - HANDLE _fdToHandle()(int fd) - { - // no semaphore is required, once inserted, a file descriptor - // doesn't change. - if (fd < 0 || fd >= _NFILE) - return null; - - return _osfhnd[fd]; - } - - enum - { - /// - STDIN_FILENO = 0, - /// - STDOUT_FILENO = 1, - /// - STDERR_FILENO = 2, - } - - int open(scope const(char)* filename, int flags, ...); /// - alias _open = open; /// - int _wopen(scope const wchar* filename, int oflag, ...); /// - int sopen(scope const char* filename, int oflag, int shflag, ...); /// - alias _sopen = sopen; /// - int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); /// - int close(int fd); /// - alias _close = close; /// - FILE *fdopen(int fd, scope const(char)* flags); /// - alias _fdopen = fdopen; /// - FILE *_wfdopen(int fd, scope const(wchar)* flags); /// - -} -else version (CRuntime_Microsoft) +version (CRuntime_Microsoft) { int _open(scope const char* filename, int oflag, ...); /// int _wopen(scope const wchar* filename, int oflag, ...); /// diff --git a/libphobos/libdruntime/core/stdcpp/array.d b/libphobos/libdruntime/core/stdcpp/array.d index eb63d4ccaab2..4cb0c56ec5ff 100644 --- a/libphobos/libdruntime/core/stdcpp/array.d +++ b/libphobos/libdruntime/core/stdcpp/array.d @@ -13,17 +13,6 @@ module core.stdcpp.array; import core.stdcpp.xutility : StdNamespace; -// hacks to support DMD on Win32 -version (CppRuntime_Microsoft) -{ - version = CppRuntime_Windows; // use the MS runtime ABI for win32 -} -else version (CppRuntime_DigitalMars) -{ - version = CppRuntime_Windows; // use the MS runtime ABI for win32 - pragma(msg, "std::array not supported by DMC"); -} - extern(C++, (StdNamespace)): /** @@ -73,7 +62,7 @@ pure nothrow @nogc: /// ref inout(T) back() inout @safe { static if (N > 0) { return this[N-1]; } else { return as_array()[][0]; /* HACK: force OOB */ } } - version (CppRuntime_Windows) + version (CppRuntime_Microsoft) { /// inout(T)* data() inout @safe { return &_Elems[0]; } diff --git a/libphobos/libdruntime/core/stdcpp/exception.d b/libphobos/libdruntime/core/stdcpp/exception.d index d5339964e367..4774b98615bf 100644 --- a/libphobos/libdruntime/core/stdcpp/exception.d +++ b/libphobos/libdruntime/core/stdcpp/exception.d @@ -80,24 +80,6 @@ version (GenericBaseException) extern(D) this(const(char)*, int = 1) nothrow { this(); } // compat with MS derived classes } } -else version (CppRuntime_DigitalMars) -{ - /// - class exception - { - @nogc: - /// - extern(D) this() nothrow {} - //virtual ~this(); - void dtor() { } // reserve slot in vtbl[] - - /// - const(char)* what() const nothrow; - - protected: - this(const(char)*, int = 1) nothrow { this(); } // compat with MS derived classes - } -} else version (CppRuntime_Microsoft) { /// diff --git a/libphobos/libdruntime/core/stdcpp/string_view.d b/libphobos/libdruntime/core/stdcpp/string_view.d index 172c170444bf..47f58b014ef1 100644 --- a/libphobos/libdruntime/core/stdcpp/string_view.d +++ b/libphobos/libdruntime/core/stdcpp/string_view.d @@ -14,17 +14,6 @@ module core.stdcpp.string_view; import core.stdc.stddef : wchar_t; import core.stdcpp.xutility : StdNamespace; -// hacks to support DMD on Win32 -version (CppRuntime_Microsoft) -{ - version = CppRuntime_Windows; // use the MS runtime ABI for win32 -} -else version (CppRuntime_DigitalMars) -{ - version = CppRuntime_Windows; // use the MS runtime ABI for win32 - pragma(msg, "std::basic_string_view not supported by DMC"); -} - extern(C++, (StdNamespace)): @nogc: @@ -102,7 +91,7 @@ pure nothrow @nogc: private: // use the proper field names from C++ so debugging doesn't get weird - version (CppRuntime_Windows) + version (CppRuntime_Microsoft) { const_pointer _Mydata; size_type _Mysize; diff --git a/libphobos/libdruntime/core/stdcpp/typeinfo.d b/libphobos/libdruntime/core/stdcpp/typeinfo.d index 24f2938ccab8..b8478b39414a 100644 --- a/libphobos/libdruntime/core/stdcpp/typeinfo.d +++ b/libphobos/libdruntime/core/stdcpp/typeinfo.d @@ -13,53 +13,7 @@ module core.stdcpp.typeinfo; import core.attribute : weak; -version (CppRuntime_DigitalMars) -{ - import core.stdcpp.exception; - - extern (C++, "std"): - - class type_info - { - @nogc: - void* pdata; - - public: - //virtual ~this(); - void dtor() { } // reserve slot in vtbl[] - - //bool operator==(const type_info rhs) const; - //bool operator!=(const type_info rhs) const; - final bool before(const type_info rhs) const nothrow; - final const(char)* name() const nothrow; - protected: - //type_info(); - private: - //this(const type_info rhs); - //type_info operator=(const type_info rhs); - } - - class bad_cast : exception - { - @nogc: - extern(D) this() nothrow { } - extern(D) this(const bad_cast) nothrow { } - //bad_cast operator=(const bad_cast) nothrow { return this; } - //virtual ~this() nothrow; - override const(char)* what() const nothrow; - } - - class bad_typeid : exception - { - @nogc: - extern(D) this() nothrow { } - extern(D) this(const bad_typeid) nothrow { } - //bad_typeid operator=(const bad_typeid) nothrow { return this; } - //virtual ~this() nothrow; - override const (char)* what() const nothrow; - } -} -else version (CppRuntime_Microsoft) +version (CppRuntime_Microsoft) { import core.stdcpp.exception; diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d index 77141d5deb32..6a003b5c633a 100644 --- a/libphobos/libdruntime/core/sys/windows/dll.d +++ b/libphobos/libdruntime/core/sys/windows/dll.d @@ -32,13 +32,7 @@ extern (C) { version (Win32) { - version (CRuntime_DigitalMars) - { - extern __gshared byte _tlsstart; - extern __gshared byte _tlsend; - extern __gshared void* _tls_callbacks_a; - } - else version (CRuntime_Microsoft) + version (CRuntime_Microsoft) { extern __gshared byte _tls_start; extern __gshared byte _tls_end; diff --git a/libphobos/libdruntime/core/sys/windows/stacktrace.d b/libphobos/libdruntime/core/sys/windows/stacktrace.d index a73fc9ce4d28..29ffc1b07854 100644 --- a/libphobos/libdruntime/core/sys/windows/stacktrace.d +++ b/libphobos/libdruntime/core/sys/windows/stacktrace.d @@ -309,13 +309,6 @@ private: auto res = formatStackFrame(pc); res ~= " in "; const(char)[] tempSymName = symName[0 .. strlen(symName)]; - // Deal with dmd mangling of long names for OMF 32 bits builds - // Note that `target.d` only defines `CRuntime_DigitalMars` for OMF builds - version (CRuntime_DigitalMars) - { - size_t decodeIndex = 0; - tempSymName = decodeDmdString(tempSymName, decodeIndex); - } res ~= demangle(tempSymName, demangleBuf); return res; } @@ -339,34 +332,6 @@ private: } -// Workaround OPTLINK bug (Bugzilla 8263) -extern(Windows) BOOL FixupDebugHeader(HANDLE hProcess, ULONG ActionCode, - ulong CallbackContext, ulong UserContext) -{ - if (ActionCode == CBA_READ_MEMORY) - { - auto p = cast(IMAGEHLP_CBA_READ_MEMORY*)CallbackContext; - if (!(p.addr & 0xFF) && p.bytes == 0x1C && - // IMAGE_DEBUG_DIRECTORY.PointerToRawData - (*cast(DWORD*)(p.addr + 24) & 0xFF) == 0x20) - { - immutable base = DbgHelp.get().SymGetModuleBase64(hProcess, p.addr); - // IMAGE_DEBUG_DIRECTORY.AddressOfRawData - if (base + *cast(DWORD*)(p.addr + 20) == p.addr + 0x1C && - *cast(DWORD*)(p.addr + 0x1C) == 0 && - *cast(DWORD*)(p.addr + 0x20) == ('N'|'B'<<8|'0'<<16|'9'<<24)) - { - debug(PRINTF) printf("fixup IMAGE_DEBUG_DIRECTORY.AddressOfRawData\n"); - memcpy(p.buf, cast(void*)p.addr, 0x1C); - *cast(DWORD*)(p.buf + 20) = cast(DWORD)(p.addr - base) + 0x20; - *p.bytesread = 0x1C; - return TRUE; - } - } - } - return FALSE; -} - private string generateSearchPath() { __gshared string[3] defaultPathList = ["_NT_SYMBOL_PATH", @@ -427,8 +392,6 @@ shared static this() if (!dbghelp.SymInitialize(hProcess, generateSearchPath().ptr, TRUE)) return; - dbghelp.SymRegisterCallback64(hProcess, &FixupDebugHeader, 0); - InitializeCriticalSection(&mutex); initialized = true; } diff --git a/libphobos/libdruntime/core/sys/windows/stat.d b/libphobos/libdruntime/core/sys/windows/stat.d index c87c74988730..85ed24f93d8c 100644 --- a/libphobos/libdruntime/core/sys/windows/stat.d +++ b/libphobos/libdruntime/core/sys/windows/stat.d @@ -31,29 +31,7 @@ int S_ISDIR(int m) { return (m & S_IFMT) == S_IFDIR; } int S_ISCHR(int m) { return (m & S_IFMT) == S_IFCHR; } } -version (CRuntime_DigitalMars) -{ - struct struct_stat - { - short st_dev; - ushort st_ino; - ushort st_mode; - short st_nlink; - ushort st_uid; - ushort st_gid; - short st_rdev; - short dummy; - int st_size; - time_t st_atime; - time_t st_mtime; - time_t st_ctime; - } - - int stat(const(char)*, struct_stat *); - int fstat(int, struct_stat *) @trusted; - int _wstat(const(wchar)*, struct_stat *); -} -else version (CRuntime_Microsoft) +version (CRuntime_Microsoft) { struct struct_stat { diff --git a/libphobos/libdruntime/rt/monitor_.d b/libphobos/libdruntime/rt/monitor_.d index c1f3f3cb9a70..cbe2a4844023 100644 --- a/libphobos/libdruntime/rt/monitor_.d +++ b/libphobos/libdruntime/rt/monitor_.d @@ -173,10 +173,6 @@ alias DEvent = void delegate(Object); version (Windows) { - version (CRuntime_DigitalMars) - { - pragma(lib, "snn.lib"); - } import core.sys.windows.winbase /+: CRITICAL_SECTION, DeleteCriticalSection, EnterCriticalSection, InitializeCriticalSection, LeaveCriticalSection+/; diff --git a/libphobos/libdruntime/rt/sections.d b/libphobos/libdruntime/rt/sections.d index 65f57892ee7e..6a1555203404 100644 --- a/libphobos/libdruntime/rt/sections.d +++ b/libphobos/libdruntime/rt/sections.d @@ -54,8 +54,6 @@ else version (Darwin) else static assert(0, "unimplemented"); } -else version (CRuntime_DigitalMars) - public import rt.sections_win32; else version (CRuntime_Microsoft) public import rt.sections_win64; else version (CRuntime_Bionic) diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index b71e3dd4efae..a431ca1e43e6 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -303b9c9f7c6457a4f31e7444d5ff0315ba97c704 +de1dea109f40fe4a551578369c474e48845daec1 The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/algorithm/searching.d b/libphobos/src/std/algorithm/searching.d index 2d89dea3f1ca..42a9df518c94 100644 --- a/libphobos/src/std/algorithm/searching.d +++ b/libphobos/src/std/algorithm/searching.d @@ -3873,6 +3873,21 @@ if (isInputRange!Range && !isInfinite!Range && assert([BigInt(2), BigInt(3)].maxElement == BigInt(3)); } +// https://issues.dlang.org/show_bug.cgi?id=24596 +@safe unittest +{ + static class A { + int i; + int getI() @safe => i; + this(int i) @safe { this.i = i; } + } + auto arr = [new A(2), new A(3)]; + + arr.maxElement!(a => a.getI); + + assert(arr[0].getI == 2); +} + // minPos /** Computes a subrange of `range` starting at the first occurrence of `range`'s diff --git a/libphobos/src/std/bitmanip.d b/libphobos/src/std/bitmanip.d index de2ff318f4e3..639b8214c8c9 100644 --- a/libphobos/src/std/bitmanip.d +++ b/libphobos/src/std/bitmanip.d @@ -805,6 +805,7 @@ private struct FloatingPointRepresentation(T) Allows manipulating the fraction, exponent, and sign parts of a `float` separately. The definition is: +$(RUNNABLE_EXAMPLE ---- struct FloatRep { @@ -819,6 +820,7 @@ struct FloatRep enum uint bias = 127, fractionBits = 23, exponentBits = 8, signBits = 1; } ---- +) */ alias FloatRep = FloatingPointRepresentation!float; @@ -874,6 +876,7 @@ alias FloatRep = FloatingPointRepresentation!float; Allows manipulating the fraction, exponent, and sign parts of a `double` separately. The definition is: +$(RUNNABLE_EXAMPLE ---- struct DoubleRep { @@ -888,6 +891,7 @@ struct DoubleRep enum uint bias = 1023, signBits = 1, fractionBits = 52, exponentBits = 11; } ---- +) */ alias DoubleRep = FloatingPointRepresentation!double; @@ -1050,6 +1054,8 @@ public: of a type different than `size_t`, firstly because its length should be a multiple of `size_t.sizeof`, and secondly because how the bits are mapped: + + $(RUNNABLE_EXAMPLE --- size_t[] source = [1, 2, 3, 3424234, 724398, 230947, 389492]; enum sbits = size_t.sizeof * 8; @@ -1060,6 +1066,7 @@ public: assert(ba[n] == nth_bit); } --- + ) The least significant bit in any `size_t` unit is the starting bit of this unit, and the most significant bit is the last bit of this unit. Therefore, passing e.g. an array of `int`s may result in a different `BitArray` diff --git a/libphobos/src/std/experimental/allocator/mallocator.d b/libphobos/src/std/experimental/allocator/mallocator.d index 02d5cf8b6d38..3d4dc9a2c524 100644 --- a/libphobos/src/std/experimental/allocator/mallocator.d +++ b/libphobos/src/std/experimental/allocator/mallocator.d @@ -116,93 +116,11 @@ struct Mallocator test!Mallocator(); } -version (Windows) +version (CRuntime_Microsoft) { - // DMD Win 32 bit, DigitalMars C standard library misses the _aligned_xxx - // functions family (snn.lib) - version (CRuntime_DigitalMars) - { - // Helper to cast the infos written before the aligned pointer - // this header keeps track of the size (required to realloc) and of - // the base ptr (required to free). - private struct AlignInfo - { - void* basePtr; - size_t size; - - @nogc nothrow - static AlignInfo* opCall(void* ptr) - { - return cast(AlignInfo*) (ptr - AlignInfo.sizeof); - } - } - - @nogc nothrow - private void* _aligned_malloc(size_t size, size_t alignment) - { - import core.stdc.stdlib : malloc; - size_t offset = alignment + size_t.sizeof * 2 - 1; - - // unaligned chunk - void* basePtr = malloc(size + offset); - if (!basePtr) return null; - - // get aligned location within the chunk - void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset) - & ~(alignment - 1)); - - // write the header before the aligned pointer - AlignInfo* head = AlignInfo(alignedPtr); - head.basePtr = basePtr; - head.size = size; - - return alignedPtr; - } - - @nogc nothrow - private void* _aligned_realloc(void* ptr, size_t size, size_t alignment) - { - import core.stdc.stdlib : free; - import core.stdc.string : memcpy; - - if (!ptr) return _aligned_malloc(size, alignment); - - // gets the header from the exising pointer - AlignInfo* head = AlignInfo(ptr); - - // gets a new aligned pointer - void* alignedPtr = _aligned_malloc(size, alignment); - if (!alignedPtr) - { - //to https://msdn.microsoft.com/en-us/library/ms235462.aspx - //see Return value: in this case the original block is unchanged - return null; - } - - // copy exising data - memcpy(alignedPtr, ptr, head.size); - free(head.basePtr); - - return alignedPtr; - } - - @nogc nothrow - private void _aligned_free(void *ptr) - { - import core.stdc.stdlib : free; - if (!ptr) return; - AlignInfo* head = AlignInfo(ptr); - free(head.basePtr); - } - - } - // DMD Win 64 bit, uses microsoft standard C library which implements them - else - { - @nogc nothrow private extern(C) void* _aligned_malloc(size_t, size_t); - @nogc nothrow private extern(C) void _aligned_free(void *memblock); - @nogc nothrow private extern(C) void* _aligned_realloc(void *, size_t, size_t); - } + @nogc nothrow private extern(C) void* _aligned_malloc(size_t, size_t); + @nogc nothrow private extern(C) void _aligned_free(void *memblock); + @nogc nothrow private extern(C) void* _aligned_realloc(void *, size_t, size_t); } /** @@ -399,50 +317,3 @@ version (Posix) assert(!AlignedMallocator.instance.alignedReallocate(c, size_t.max, 4096)); AlignedMallocator.instance.deallocate(c); } - -version (CRuntime_DigitalMars) -@nogc @system nothrow unittest -{ - void* m; - - size_t m_addr() { return cast(size_t) m; } - - m = _aligned_malloc(16, 0x10); - if (m) - { - assert((m_addr & 0xF) == 0); - _aligned_free(m); - } - - m = _aligned_malloc(16, 0x100); - if (m) - { - assert((m_addr & 0xFF) == 0); - _aligned_free(m); - } - - m = _aligned_malloc(16, 0x1000); - if (m) - { - assert((m_addr & 0xFFF) == 0); - _aligned_free(m); - } - - m = _aligned_malloc(16, 0x10); - if (m) - { - assert((cast(size_t) m & 0xF) == 0); - m = _aligned_realloc(m, 32, 0x10000); - if (m) assert((m_addr & 0xFFFF) == 0); - _aligned_free(m); - } - - m = _aligned_malloc(8, 0x10); - if (m) - { - *cast(ulong*) m = 0X01234567_89ABCDEF; - m = _aligned_realloc(m, 0x800, 0x1000); - if (m) assert(*cast(ulong*) m == 0X01234567_89ABCDEF); - _aligned_free(m); - } -} diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d index 1db779bdf8e5..2a0d1392c088 100644 --- a/libphobos/src/std/file.d +++ b/libphobos/src/std/file.d @@ -4053,12 +4053,10 @@ else version (Posix) +/ void _ensureStatDone() @trusted scope { - import std.exception : enforce; - if (_didStat) return; - enforce(stat(_name.tempCString(), &_statBuf) == 0, + cenforce(stat(_name.tempCString(), &_statBuf) == 0, "Failed to stat file `" ~ _name ~ "'"); _didStat = true; @@ -4095,13 +4093,11 @@ else version (Posix) +/ void _ensureLStatDone() @trusted scope { - import std.exception : enforce; - if (_didLStat) return; stat_t statbuf = void; - enforce(lstat(_name.tempCString(), &statbuf) == 0, + cenforce(lstat(_name.tempCString(), &statbuf) == 0, "Failed to stat file `" ~ _name ~ "'"); _lstatMode = statbuf.st_mode; @@ -4183,12 +4179,12 @@ else version (Posix) assert(!de.isFile); assert(!de.isDir); assert(de.isSymlink); - assertThrown(de.size); - assertThrown(de.timeStatusChanged); - assertThrown(de.timeLastAccessed); - assertThrown(de.timeLastModified); - assertThrown(de.attributes); - assertThrown(de.statBuf); + assertThrown!FileException(de.size); + assertThrown!FileException(de.timeStatusChanged); + assertThrown!FileException(de.timeLastAccessed); + assertThrown!FileException(de.timeLastModified); + assertThrown!FileException(de.attributes); + assertThrown!FileException(de.statBuf); assert(symfile.exists); symfile.remove(); } diff --git a/libphobos/src/std/math/hardware.d b/libphobos/src/std/math/hardware.d index dec8fdd50f2d..03e5463b5b5c 100644 --- a/libphobos/src/std/math/hardware.d +++ b/libphobos/src/std/math/hardware.d @@ -222,7 +222,7 @@ private: uint result = void; asm pure nothrow @nogc { - "movfcsr2gr %0,$r2" : "=r" (result); + "movfcsr2gr %0, $fcsr2" : "=r" (result); } return result & EXCEPTIONS_MASK; } @@ -1047,7 +1047,7 @@ private: ControlState cont; asm pure nothrow @nogc { - "movfcsr2gr %0,$r0" : "=r" (cont); + "movfcsr2gr %0, $fcsr0" : "=r" (cont); } cont &= (roundingMask | allExceptions); return cont; diff --git a/libphobos/src/std/math/rounding.d b/libphobos/src/std/math/rounding.d index f6654fc115a1..a65e393f95bf 100644 --- a/libphobos/src/std/math/rounding.d +++ b/libphobos/src/std/math/rounding.d @@ -776,27 +776,18 @@ version (Posix) * * If the fractional part of x is exactly 0.5, the return value is rounded * away from zero. - * - * $(BLUE This function is not implemented for Digital Mars C runtime.) */ long lround(real x) @trusted nothrow @nogc { - version (CRuntime_DigitalMars) - assert(0, "lround not implemented"); - else - return core.stdc.math.llroundl(x); + return core.stdc.math.llroundl(x); } /// @safe nothrow @nogc unittest { - version (CRuntime_DigitalMars) {} - else - { - assert(lround(0.49) == 0); - assert(lround(0.5) == 1); - assert(lround(1.5) == 2); - } + assert(lround(0.49) == 0); + assert(lround(0.5) == 1); + assert(lround(1.5) == 2); } /** diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d index 325689ba51df..d1783742e5eb 100644 --- a/libphobos/src/std/process.d +++ b/libphobos/src/std/process.d @@ -127,26 +127,19 @@ else version (WatchOS) version = iOSDerived; } -// When the DMC runtime is used, we have to use some custom functions -// to convert between Windows file handles and FILE*s. -version (Win32) version (CRuntime_DigitalMars) version = DMC_RUNTIME; - // Some of the following should be moved to druntime. private { // Microsoft Visual C Runtime (MSVCRT) declarations. - version (Windows) + version (CRuntime_Microsoft) { - version (DMC_RUNTIME) { } else + import core.stdc.stdint; + enum { - import core.stdc.stdint; - enum - { - STDIN_FILENO = 0, - STDOUT_FILENO = 1, - STDERR_FILENO = 2, - } + STDIN_FILENO = 0, + STDOUT_FILENO = 1, + STDERR_FILENO = 2, } } @@ -350,6 +343,8 @@ static: */ bool opBinaryRight(string op : "in")(scope const(char)[] name) @trusted { + if (name is null) + return false; version (Posix) return core.sys.posix.stdlib.getenv(name.tempCString()) !is null; else version (Windows) @@ -451,6 +446,10 @@ private: // doesn't exist. void getImpl(scope const(char)[] name, scope void delegate(const(OSChar)[]) @safe sink) @trusted { + // fix issue https://issues.dlang.org/show_bug.cgi?id=24549 + if (name is null) + return sink(null); + version (Windows) { // first we ask windows how long the environment variable is, @@ -600,6 +599,15 @@ private: assert("std_process" !in environment); } +// https://issues.dlang.org/show_bug.cgi?id=24549 +@safe unittest +{ + import std.exception : assertThrown; + assert(environment.get(null) is null); + assertThrown(environment[null]); + assert(!(null in environment)); +} + // ============================================================================= // Functions and classes for process management. // ============================================================================= diff --git a/libphobos/src/std/regex/internal/ir.d b/libphobos/src/std/regex/internal/ir.d index 04b902fc39df..25566d6bea61 100644 --- a/libphobos/src/std/regex/internal/ir.d +++ b/libphobos/src/std/regex/internal/ir.d @@ -318,7 +318,7 @@ struct Bytecode @property bool backreference() const { assert(code == IR.GroupStart || code == IR.GroupEnd); - return cast(bool)(raw & 1 << 23); + return (raw & 1 << 23) != 0; } //mark as local reference (for backrefs in lookarounds) @@ -332,7 +332,7 @@ struct Bytecode @property bool localRef() const { assert(code == IR.Backref); - return cast(bool)(raw & 1 << 23); + return (raw & 1 << 23) != 0; } //human readable name of instruction diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d index 40dc85420fef..8caa9b367187 100644 --- a/libphobos/src/std/stdio.d +++ b/libphobos/src/std/stdio.d @@ -123,9 +123,6 @@ alias KeepTerminator = Flag!"keepTerminator"; version (CRuntime_Microsoft) { } -else version (CRuntime_DigitalMars) -{ -} else version (CRuntime_Glibc) { } @@ -215,54 +212,7 @@ version (Posix) static import core.sys.posix.stdio; // getdelim, flockfile } -version (CRuntime_DigitalMars) -{ - private alias _FPUTC = _fputc_nlock; - private alias _FPUTWC = _fputwc_nlock; - private alias _FGETC = _fgetc_nlock; - private alias _FGETWC = _fgetwc_nlock; - private alias _FLOCK = __fp_lock; - private alias _FUNLOCK = __fp_unlock; - - // Alias for CRuntime_Microsoft compatibility. - // @@@DEPRECATED_2.107@@@ - // Rename this back to _setmode once the deprecation phase has ended. - private alias __setmode = setmode; - - // @@@DEPRECATED_2.107@@@ - deprecated("internal alias FPUTC was unintentionally available from " - ~ "std.stdio and will be removed afer 2.107") - alias FPUTC = _fputc_nlock; - // @@@DEPRECATED_2.107@@@ - deprecated("internal alias FPUTWC was unintentionally available from " - ~ "std.stdio and will be removed afer 2.107") - alias FPUTWC = _fputwc_nlock; - // @@@DEPRECATED_2.107@@@ - deprecated("internal alias FGETC was unintentionally available from " - ~ "std.stdio and will be removed afer 2.107") - alias FGETC = _fgetc_nlock; - // @@@DEPRECATED_2.107@@@ - deprecated("internal alias FGETWC was unintentionally available from " - ~ "std.stdio and will be removed afer 2.107") - alias FGETWC = _fgetwc_nlock; - // @@@DEPRECATED_2.107@@@ - deprecated("internal alias FLOCK was unintentionally available from " - ~ "std.stdio and will be removed afer 2.107") - alias FLOCK = __fp_lock; - // @@@DEPRECATED_2.107@@@ - deprecated("internal alias FUNLOCK was unintentionally available from " - ~ "std.stdio and will be removed afer 2.107") - alias FUNLOCK = __fp_unlock; - // @@@DEPRECATED_2.107@@@ - deprecated("internal alias _setmode was unintentionally available from " - ~ "std.stdio and will be removed afer 2.107") - alias _setmode = setmode; - // @@@DEPRECATED_2.107@@@ - deprecated("internal function _fileno was unintentionally available from " - ~ "std.stdio and will be removed afer 2.107") - fileno_t _fileno(FILE* f) { return f._file; } -} -else version (CRuntime_Microsoft) +version (CRuntime_Microsoft) { private alias _FPUTC = _fputc_nolock; private alias _FPUTWC = _fputwc_nolock; @@ -271,10 +221,6 @@ else version (CRuntime_Microsoft) private alias _FLOCK = _lock_file; private alias _FUNLOCK = _unlock_file; - // @@@DEPRECATED_2.107@@@ - // Remove this once the deprecation phase for CRuntime_DigitalMars has ended. - private alias __setmode = _setmode; - // @@@DEPRECATED_2.107@@@ deprecated("internal alias FPUTC was unintentionally available from " ~ "std.stdio and will be removed afer 2.107") @@ -413,11 +359,7 @@ else private extern (C) @nogc nothrow { pragma(mangle, _FPUTC.mangleof) int trustedFPUTC(int ch, _iobuf* h) @trusted; - - version (CRuntime_DigitalMars) - pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(int ch, _iobuf* h) @trusted; - else - pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(wchar_t ch, _iobuf* h) @trusted; + pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(wchar_t ch, _iobuf* h) @trusted; } //------------------------------------------------------------------------------ @@ -829,7 +771,6 @@ Throws: `ErrnoException` in case of error. f.close(); } - version (CRuntime_DigitalMars) {} else // Not implemented version (CRuntime_Microsoft) {} else // Not implemented @safe unittest // Test changing mode { @@ -889,22 +830,7 @@ Params: auto modez = stdioOpenmode.tempCString(); detach(); - version (CRuntime_DigitalMars) - { - // This is a re-implementation of DMC's fdopen, but without the - // mucking with the file descriptor. POSIX standard requires the - // new fdopen'd file to retain the given file descriptor's - // position. - auto fp = fopen("NUL", modez); - errnoEnforce(fp, "Cannot open placeholder NUL stream"); - _FLOCK(fp); - auto iob = cast(_iobuf*) fp; - .close(iob._file); - iob._file = fd; - iob._flag &= ~_IOTRAN; - _FUNLOCK(fp); - } - else version (CRuntime_Microsoft) + version (CRuntime_Microsoft) { auto fp = _fdopen(fd, modez); errnoEnforce(fp); @@ -943,26 +869,21 @@ Throws: `ErrnoException` in case of error. import std.format : format; // Create file descriptors from the handles - version (CRuntime_DigitalMars) - auto fd = _handleToFD(handle, FHND_DEVICE); - else // MSVCRT - { - int mode; - modeLoop: - foreach (c; stdioOpenmode) - switch (c) - { - case 'r': mode |= _O_RDONLY; break; - case '+': mode &=~_O_RDONLY; break; - case 'a': mode |= _O_APPEND; break; - case 'b': mode |= _O_BINARY; break; - case 't': mode |= _O_TEXT; break; - case ',': break modeLoop; - default: break; - } + int mode; + modeLoop: + foreach (c; stdioOpenmode) + switch (c) + { + case 'r': mode |= _O_RDONLY; break; + case '+': mode &=~_O_RDONLY; break; + case 'a': mode |= _O_APPEND; break; + case 'b': mode |= _O_BINARY; break; + case 't': mode |= _O_TEXT; break; + case ',': break modeLoop; + default: break; + } - auto fd = _open_osfhandle(cast(intptr_t) handle, mode); - } + auto fd = _open_osfhandle(cast(intptr_t) handle, mode); errnoEnforce(fd >= 0, "Cannot open Windows HANDLE"); fdopen(fd, stdioOpenmode, "HANDLE(%s)".format(handle)); @@ -1186,17 +1107,8 @@ Throws: `ErrnoException` if the file is not opened or the call to `fread` fails. version (Windows) { immutable fileno_t fd = .fileno(_p.handle); - immutable mode = .__setmode(fd, _O_BINARY); - scope(exit) .__setmode(fd, mode); - version (CRuntime_DigitalMars) - { - import core.atomic : atomicOp; - - // https://issues.dlang.org/show_bug.cgi?id=4243 - immutable info = __fhnd_info[fd]; - atomicOp!"&="(__fhnd_info[fd], ~FHND_TEXT); - scope(exit) __fhnd_info[fd] = info; - } + immutable mode = ._setmode(fd, _O_BINARY); + scope(exit) ._setmode(fd, mode); } immutable freadResult = trustedFread(_p.handle, buffer); assert(freadResult <= buffer.length); // fread return guarantee @@ -1276,24 +1188,14 @@ Throws: `ErrnoException` if the file is not opened or if the call to `fwrite` fa version (Windows) { immutable fileno_t fd = .fileno(_p.handle); - immutable oldMode = .__setmode(fd, _O_BINARY); + immutable oldMode = ._setmode(fd, _O_BINARY); if (oldMode != _O_BINARY) { // need to flush the data that was written with the original mode - .__setmode(fd, oldMode); - flush(); // before changing translation mode .__setmode(fd, _O_BINARY); - .__setmode(fd, _O_BINARY); - } - - version (CRuntime_DigitalMars) - { - import core.atomic : atomicOp; - - // https://issues.dlang.org/show_bug.cgi?id=4243 - immutable info = __fhnd_info[fd]; - atomicOp!"&="(__fhnd_info[fd], ~FHND_TEXT); - scope (exit) __fhnd_info[fd] = info; + ._setmode(fd, oldMode); + flush(); // before changing translation mode ._setmode(fd, _O_BINARY); + ._setmode(fd, _O_BINARY); } scope (exit) @@ -1301,7 +1203,7 @@ Throws: `ErrnoException` if the file is not opened or if the call to `fwrite` fa if (oldMode != _O_BINARY) { flush(); - .__setmode(fd, oldMode); + ._setmode(fd, oldMode); } } } @@ -1394,9 +1296,6 @@ Throws: `Exception` if the file is not opened. f.seek(7); assert(f.readln() == "hijklmnopqrstuvwxyz"); - version (CRuntime_DigitalMars) - auto bigOffset = int.max - 100; - else version (CRuntime_Bionic) auto bigOffset = int.max - 100; else @@ -2349,10 +2248,7 @@ Returns the underlying operating system `HANDLE` (Windows only). version (Windows) @property HANDLE windowsHandle() { - version (CRuntime_DigitalMars) - return _fdToHandle(fileno); - else - return cast(HANDLE)_get_osfhandle(fileno); + return cast(HANDLE)_get_osfhandle(fileno); } @@ -3151,11 +3047,11 @@ is empty, throws an `Exception`. In case of an I/O error throws // concept of ANSI/UNICODE mode. fputc doesn't work in UNICODE // mode; fputwc has to be used. So that essentially means // "wide-oriented" for us. - immutable int mode = __setmode(f.fileno, _O_TEXT); + immutable int mode = _setmode(f.fileno, _O_TEXT); // Set some arbitrary mode to obtain the previous one. - if (mode != -1) // __setmode() succeeded + if (mode != -1) // _setmode() succeeded { - __setmode(f.fileno, mode); // Restore previous mode. + _setmode(f.fileno, mode); // Restore previous mode. if (mode & (_O_WTEXT | _O_U16TEXT | _O_U8TEXT)) { orientation_ = 1; // wide @@ -3386,8 +3282,6 @@ is empty, throws an `Exception`. In case of an I/O error throws { fileno_t fd; int oldMode; - version (CRuntime_DigitalMars) - ubyte oldInfo; } public: @@ -3407,15 +3301,7 @@ is empty, throws an `Exception`. In case of an I/O error throws { .fflush(fps); // before changing translation mode fd = .fileno(fps); - oldMode = .__setmode(fd, _O_BINARY); - version (CRuntime_DigitalMars) - { - import core.atomic : atomicOp; - - // https://issues.dlang.org/show_bug.cgi?id=4243 - oldInfo = __fhnd_info[fd]; - atomicOp!"&="(__fhnd_info[fd], ~FHND_TEXT); - } + oldMode = ._setmode(fd, _O_BINARY); } } @@ -3429,12 +3315,7 @@ is empty, throws an `Exception`. In case of an I/O error throws version (Windows) { .fflush(fps); // before restoring translation mode - version (CRuntime_DigitalMars) - { - // https://issues.dlang.org/show_bug.cgi?id=4243 - __fhnd_info[fd] = oldInfo; - } - .__setmode(fd, oldMode); + ._setmode(fd, oldMode); } _FUNLOCK(fps); @@ -3887,19 +3768,12 @@ void main() return setlocale(LC_CTYPE, loc.ptr).fromStringz.endsWith(loc); }); scope(exit) () @trusted { setlocale(LC_CTYPE, oldCt); } (); - version (CRuntime_DigitalMars) // DM can't handle Unicode above U+07FF. - { - alias strs = AliasSeq!("xä\u07FE", "yö\u07FF"w); - } - else - { - alias strs = AliasSeq!("xä\U0001F607", "yö\U0001F608"w); - } + alias strs = AliasSeq!("xä\U0001F607", "yö\U0001F608"w); { auto f = File(deleteme, "w"); version (CRuntime_Microsoft) { - () @trusted { __setmode(fileno(f.getFP()), _O_U8TEXT); } (); + () @trusted { _setmode(fileno(f.getFP()), _O_U8TEXT); } (); } else { @@ -5537,120 +5411,7 @@ private struct LockedFile // Private implementation of readln private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation) @safe { - version (CRuntime_DigitalMars) - return () @trusted { - auto lf = LockedFile(fps); - ReadlnAppender app; - app.initialize(buf); - - if (__fhnd_info[lf.fp._file] & FHND_WCHAR) - { /* Stream is in wide characters. - * Read them and convert to chars. - */ - static assert(wchar_t.sizeof == 2); - for (int c = void; (c = lf.fgetwc()) != -1; ) - { - if ((c & ~0x7F) == 0) - { - app.putchar(cast(char) c); - if (c == terminator) - break; - } - else - { - if (c >= 0xD800 && c <= 0xDBFF) - { - int c2 = void; - if ((c2 = lf.fgetwc()) != -1 || - c2 < 0xDC00 && c2 > 0xDFFF) - { - StdioException("unpaired UTF-16 surrogate"); - } - c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00); - } - app.putdchar(cast(dchar) c); - } - } - if (ferror(fps)) - StdioException(); - } - else if (lf.fp._flag & _IONBF) - { - /* Use this for unbuffered I/O, when running - * across buffer boundaries, or for any but the common - * cases. - */ - L1: - int c; - while ((c = lf.fgetc()) != -1) - { - app.putchar(cast(char) c); - if (c == terminator) - { - buf = app.data; - return buf.length; - } - - } - - if (ferror(fps)) - StdioException(); - } - else - { - int u = lf.fp._cnt; - char* p = lf.fp._ptr; - int i; - if (lf.fp._flag & _IOTRAN) - { /* Translated mode ignores \r and treats ^Z as end-of-file - */ - char c; - while (1) - { - if (i == u) // if end of buffer - goto L1; // give up - c = p[i]; - i++; - if (c != '\r') - { - if (c == terminator) - break; - if (c != 0x1A) - continue; - goto L1; - } - else - { if (i != u && p[i] == terminator) - break; - goto L1; - } - } - app.putonly(p[0 .. i]); - app.buf[i - 1] = cast(char) terminator; - if (terminator == '\n' && c == '\r') - i++; - } - else - { - while (1) - { - if (i == u) // if end of buffer - goto L1; // give up - auto c = p[i]; - i++; - if (c == terminator) - break; - } - app.putonly(p[0 .. i]); - } - lf.fp._cnt -= i; - lf.fp._ptr += i; - } - - buf = app.data; - return buf.length; - }(); - else version (CRuntime_Microsoft) + version (CRuntime_Microsoft) { auto lf = LockedFile(fps); diff --git a/libphobos/src/std/string.d b/libphobos/src/std/string.d index ca14c23747e0..b350d6b7134c 100644 --- a/libphobos/src/std/string.d +++ b/libphobos/src/std/string.d @@ -5942,36 +5942,36 @@ C1[] tr(C1, C2, C3, C4 = immutable char) n = 0; // consider it 'found' at position 0 Lfound: - - // Find the nth character in to[] - dchar nextt; - for (size_t i = 0; i < to.length; ) - { - immutable t = decode(to, i); - if (t == '-' && lastt != dchar.init && i < to.length) + { // create a new scope so that gotos don't skip of declaration of nextt + // Find the nth character in to[] + dchar nextt; + for (size_t i = 0; i < to.length; ) { - nextt = decode(to, i); - n -= nextt - lastt; - if (n < 0) + immutable t = decode(to, i); + if (t == '-' && lastt != dchar.init && i < to.length) { - newc = nextt + n + 1; + nextt = decode(to, i); + n -= nextt - lastt; + if (n < 0) + { + newc = nextt + n + 1; + goto Lnewc; + } + lastt = dchar.init; + continue; + } + if (n == 0) + { newc = t; goto Lnewc; } - lastt = dchar.init; - continue; - } - if (n == 0) - { newc = t; - goto Lnewc; + lastt = t; + nextt = t; + n--; } - lastt = t; - nextt = t; - n--; + if (mod_d) + continue; + newc = nextt; } - if (mod_d) - continue; - newc = nextt; - Lnewc: if (mod_s && modified && newc == lastc) continue; diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index f5b48468a804..3c425c7d7de0 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -3125,7 +3125,10 @@ private: } // call possible struct destructors - .destroy!(No.initialize)(*cast(T*) &this.data); + static if (is(T == struct)) + { + .destroy!(No.initialize)(*cast(T*) &this.data); + } } }