https://gcc.gnu.org/g:c8894b681143041205d41e02ede112cef082bf2f
commit r15-6899-gc8894b681143041205d41e02ede112cef082bf2f Author: Iain Buclaw <ibuc...@gdcproject.org> Date: Tue Jan 14 20:51:45 2025 +0100 d: Merge upstream dmd, druntime d6f693b46a, phobos 336bed6d8. D front-end changes: - Import latest fixes from dmd v2.110.0-rc.1. D runtime changes: - Import latest fixes from druntime v2.110.0-rc.1. Phobos changes: - Import latest fixes from phobos v2.110.0-rc.1. Included in the merge are fixes for the following PRs: PR d/118438 PR d/118448 PR d/118449 gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd d6f693b46a. * d-incpath.cc (add_import_paths): Update for new front-end interface. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime d6f693b46a. * src/MERGE: Merge upstream phobos 336bed6d8. * testsuite/libphobos.init_fini/custom_gc.d: Adjust test. Diff: --- gcc/d/d-incpath.cc | 4 +- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/clone.d | 201 ++++++++++++--------- gcc/d/dmd/ctfeexpr.d | 48 +++-- gcc/d/dmd/dcast.d | 18 +- gcc/d/dmd/dimport.d | 9 +- gcc/d/dmd/dmodule.d | 29 ++- gcc/d/dmd/doc.d | 6 +- gcc/d/dmd/dstruct.d | 4 +- gcc/d/dmd/dsymbolsem.d | 34 +++- gcc/d/dmd/dtemplate.d | 11 +- gcc/d/dmd/dtoh.d | 2 +- gcc/d/dmd/errors.d | 20 +- gcc/d/dmd/expression.d | 13 +- gcc/d/dmd/expressionsem.d | 16 +- gcc/d/dmd/file_manager.d | 29 ++- gcc/d/dmd/func.d | 4 +- gcc/d/dmd/funcsem.d | 13 +- gcc/d/dmd/globals.d | 9 +- gcc/d/dmd/globals.h | 15 +- gcc/d/dmd/hdrgen.d | 4 +- gcc/d/dmd/json.d | 2 +- gcc/d/dmd/lexer.d | 2 +- gcc/d/dmd/mtype.d | 2 +- gcc/d/dmd/parse.d | 6 +- gcc/d/dmd/pragmasem.d | 13 +- gcc/d/dmd/semantic3.d | 2 +- gcc/d/dmd/templateparamsem.d | 9 +- gcc/d/dmd/traits.d | 3 +- gcc/d/dmd/typesem.d | 4 +- gcc/d/dmd/typinf.d | 1 - gcc/testsuite/gdc.test/compilable/copyCtor2.d | 14 ++ gcc/testsuite/gdc.test/compilable/cppmangle.d | 6 + gcc/testsuite/gdc.test/compilable/testInference.d | 20 +- .../gdc.test/fail_compilation/failCopyCtor2.d | 19 -- .../gdc.test/fail_compilation/retscope2.d | 2 +- .../gdc.test/fail_compilation/retscope3.d | 4 +- .../gdc.test/fail_compilation/retscope6.d | 2 +- .../gdc.test/fail_compilation/test18282.d | 16 +- gcc/testsuite/gdc.test/runnable/rvalue1.d | 51 ++++++ libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/core/builtins.d | 21 ++- libphobos/libdruntime/core/demangle.d | 11 +- libphobos/libdruntime/core/internal/gc/os.d | 4 +- libphobos/libdruntime/core/sys/posix/sys/socket.d | 9 + libphobos/src/MERGE | 2 +- libphobos/src/std/functional.d | 6 +- libphobos/src/std/socket.d | 2 +- libphobos/src/std/typecons.d | 2 +- .../testsuite/libphobos.init_fini/custom_gc.d | 10 + 50 files changed, 471 insertions(+), 267 deletions(-) diff --git a/gcc/d/d-incpath.cc b/gcc/d/d-incpath.cc index 3f62f437cb98..155dc99c5550 100644 --- a/gcc/d/d-incpath.cc +++ b/gcc/d/d-incpath.cc @@ -133,7 +133,7 @@ add_import_paths (const char *iprefix, const char *imultilib, bool stdinc) bool found = false; for (size_t i = 0; i < global.params.imppath.length; i++) { - if (strcmp (path, global.params.imppath[i]) == 0) + if (strcmp (path, global.params.imppath[i].path) == 0) { found = true; break; @@ -160,7 +160,7 @@ add_import_paths (const char *iprefix, const char *imultilib, bool stdinc) /* Add import search paths. */ for (size_t i = 0; i < global.params.imppath.length; i++) { - const char *path = global.params.imppath[i]; + const char *path = global.params.imppath[i].path; if (path) { Strings array; diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index b145d1bd6593..33bb398c00d4 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -c7902293d7df9d02546562cb09fc8439004a70d1 +d6f693b46a1565172cac7a1438905141783a164f 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/clone.d b/gcc/d/dmd/clone.d index 1b838603c7e8..d7658c68ec25 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -269,7 +269,7 @@ FuncDeclaration buildOpAssign(StructDeclaration sd, Scope* sc) return null; //printf("StructDeclaration::buildOpAssign() %s\n", sd.toChars()); - StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc; + StorageClass stc = STC.safe; Loc declLoc = sd.loc; Loc loc; // internal code should have no loc to prevent coverage @@ -1278,7 +1278,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) const hasUserDefinedPosblit = sd.postblits.length && !sd.postblits[0].isDisabled ? true : false; // by default, the storage class of the created postblit - StorageClass stc = STC.safe | STC.nothrow_ | STC.pure_ | STC.nogc; + StorageClass stc = STC.safe; Loc declLoc = sd.postblits.length ? sd.postblits[0].loc : sd.loc; Loc loc; // internal code should have no loc to prevent coverage @@ -1380,6 +1380,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) // perform semantic on the member postblit in order to // be able to aggregate it later on with the rest of the // postblits + sdv.postblit.isGenerated = true; functionSemantic(sdv.postblit); stc = mergeFuncAttrs(stc, sdv.postblit); @@ -1445,6 +1446,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) */ if (sdv.dtor) { + sdv.dtor.isGenerated = true; functionSemantic(sdv.dtor); // keep a list of fields that need to be destroyed in case @@ -1545,25 +1547,27 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) } /** - * Generates a copy constructor declaration with the specified storage + * Generates a copy or move constructor declaration with the specified storage * class for the parameter and the function. * * Params: - * sd = the `struct` that contains the copy constructor - * paramStc = the storage class of the copy constructor parameter - * funcStc = the storage class for the copy constructor declaration + * sd = the `struct` that contains the constructor + * paramStc = the storage class of the constructor parameter + * funcStc = the storage class for the constructor declaration + * move = true for move constructor, false for copy constructor * * Returns: * The copy constructor declaration for struct `sd`. */ -private CtorDeclaration generateCopyCtorDeclaration(StructDeclaration sd, const StorageClass paramStc, const StorageClass funcStc) +private CtorDeclaration generateCtorDeclaration(StructDeclaration sd, const StorageClass paramStc, const StorageClass funcStc, bool move) { auto fparams = new Parameters(); auto structType = sd.type; - fparams.push(new Parameter(Loc.initial, paramStc | STC.ref_ | STC.return_ | STC.scope_, structType, Id.p, null, null)); + StorageClass stc = move ? 0 : STC.ref_; // the only difference between copy or move + fparams.push(new Parameter(Loc.initial, paramStc | stc, structType, Id.p, null, null)); ParameterList pList = ParameterList(fparams); auto tf = new TypeFunction(pList, structType, LINK.d, STC.ref_); - auto ccd = new CtorDeclaration(sd.loc, Loc.initial, STC.ref_, tf, true); + auto ccd = new CtorDeclaration(sd.loc, Loc.initial, STC.ref_, tf); ccd.storage_class |= funcStc; ccd.storage_class |= STC.inference; ccd.isGenerated = true; @@ -1571,28 +1575,37 @@ private CtorDeclaration generateCopyCtorDeclaration(StructDeclaration sd, const } /** - * Generates a trivial copy constructor body that simply does memberwise - * initialization: + * Generates a trivial copy or move constructor body that simply does memberwise + * initialization. * + * for copy construction: * this.field1 = rhs.field1; * this.field2 = rhs.field2; * ... + * for move construction: + * this.field1 = __rvalue(rhs.field1); + * this.field2 = __rvalue(rhs.field2); + * ... * * Params: - * sd = the `struct` declaration that contains the copy constructor + * sd = the `struct` declaration that contains the constructor + * move = true for move constructor, false for copy constructor * * Returns: - * A `CompoundStatement` containing the body of the copy constructor. + * A `CompoundStatement` containing the body of the constructor. */ -private Statement generateCopyCtorBody(StructDeclaration sd) +private Statement generateCtorBody(StructDeclaration sd, bool move) { Loc loc; Expression e; foreach (v; sd.fields) { + Expression rhs = new DotVarExp(loc, new IdentifierExp(loc, Id.p), v); + if (move) + rhs.rvalue = true; auto ec = new AssignExp(loc, new DotVarExp(loc, new ThisExp(loc), v), - new DotVarExp(loc, new IdentifierExp(loc, Id.p), v)); + rhs); e = Expression.combine(e, ec); //printf("e.toChars = %s\n", e.toChars()); } @@ -1600,29 +1613,18 @@ private Statement generateCopyCtorBody(StructDeclaration sd) return new CompoundStatement(loc, s1); } -/** - * Determine if a copy constructor is needed for struct sd, - * if the following conditions are met: - * - * 1. sd does not define a copy constructor - * 2. at least one field of sd defines a copy constructor - * +/****************************************** + * Find root `this` constructor for struct sd. + * (root is starting position for overloaded constructors) * Params: - * sd = the `struct` for which the copy constructor is generated - * hasCpCtor = set to true if a copy constructor is already present - * hasMoveCtor = set to true if a move constructor is already present - * - * Returns: - * `true` if one needs to be generated - * `false` otherwise + * sd = the `struct` to be searched + * ctor = `this` if found, otherwise null + * Result: + * false means `this` found in overload set */ -bool needCopyCtor(StructDeclaration sd, out bool hasCpCtor, out bool hasMoveCtor) +private bool findStructConstructorRoot(StructDeclaration sd, out Dsymbol ctor) { - //printf("needCopyCtor() %s\n", sd.toChars()); - if (global.errors) - return false; - - auto ctor = sd.search(sd.loc, Id.ctor); + ctor = sd.search(sd.loc, Id.ctor); // Aggregate.searchCtor() ? if (ctor) { if (ctor.isOverloadSet()) @@ -1630,13 +1632,18 @@ bool needCopyCtor(StructDeclaration sd, out bool hasCpCtor, out bool hasMoveCtor if (auto td = ctor.isTemplateDeclaration()) ctor = td.funcroot; } + return true; +} - CtorDeclaration cpCtor; - CtorDeclaration rvalueCtor; - - if (!ctor) - goto LcheckFields; - +/*********************************************** + * Find move and copy constructors (if any) starting at `ctor` + * Params: + * ctor = `this` constructor root + * copyCtor = set to first copy constructor found, or null + * moveCtor = set to first move constructor found, or null + */ +private void findMoveAndCopyConstructors(Dsymbol ctor, out CtorDeclaration copyCtor, out CtorDeclaration moveCtor) +{ overloadApply(ctor, (Dsymbol s) { if (s.isTemplateDeclaration()) @@ -1645,33 +1652,63 @@ bool needCopyCtor(StructDeclaration sd, out bool hasCpCtor, out bool hasMoveCtor assert(ctorDecl); if (ctorDecl.isCpCtor) { - if (!cpCtor) - cpCtor = ctorDecl; - return 0; + if (!copyCtor) + copyCtor = ctorDecl; + } + else if (ctorDecl.isMoveCtor) + { + if (!moveCtor) + moveCtor = ctorDecl; } - - if (ctorDecl.isMoveCtor) - rvalueCtor = ctorDecl; return 0; }); +} + +/** + * Determine if a copy constructor is needed for struct sd, + * if the following conditions are met: + * + * 1. sd does not define a copy constructor + * 2. at least one field of sd defines a copy constructor + * + * Params: + * sd = the `struct` for which the copy constructor is generated + * hasCopyCtor = set to true if a copy constructor is already present + * hasMoveCtor = set to true if a move constructor is already present + * needCopyCtor = set to true if a copy constructor is not present, but needed + * needMoveCtor = set to true if a move constructor is not present, but needed + * + * Returns: + * `true` if one needs to be generated + * `false` otherwise + */ +void needCopyOrMoveCtor(StructDeclaration sd, out bool hasCopyCtor, out bool hasMoveCtor, out bool needCopyCtor, out bool needMoveCtor) +{ + //printf("needCopyOrMoveCtor() %s\n", sd.toChars()); + if (global.errors) + return; + + Dsymbol ctor; + if (!findStructConstructorRoot(sd, ctor)) + return; + + CtorDeclaration copyCtor; + CtorDeclaration moveCtor; + + if (ctor) + findMoveAndCopyConstructors(ctor, copyCtor, moveCtor); - if (rvalueCtor) + if (moveCtor) hasMoveCtor = true; - if (cpCtor) - { - if (0 && rvalueCtor) - { - .error(sd.loc, "`struct %s` may not define both a rvalue constructor and a copy constructor", sd.toChars()); - errorSupplemental(rvalueCtor.loc,"rvalue constructor defined here"); - errorSupplemental(cpCtor.loc, "copy constructor defined here"); - } - hasCpCtor = true; - return false; - } + if (copyCtor) + hasCopyCtor = true; + + if (hasMoveCtor && hasCopyCtor) + return; -LcheckFields: VarDeclaration fieldWithCpCtor; + VarDeclaration fieldWithMoveCtor; // see if any struct members define a copy constructor foreach (v; sd.fields) { @@ -1686,20 +1723,25 @@ LcheckFields: if (ts.sym.hasCopyCtor) { fieldWithCpCtor = v; - break; + } + if (ts.sym.hasMoveCtor) + { + fieldWithMoveCtor = v; } } - if (fieldWithCpCtor && rvalueCtor) + if (0 && fieldWithCpCtor && moveCtor) { .error(sd.loc, "`struct %s` may not define a rvalue constructor and have fields with copy constructors", sd.toChars()); - errorSupplemental(rvalueCtor.loc,"rvalue constructor defined here"); + errorSupplemental(moveCtor.loc,"rvalue constructor defined here"); errorSupplemental(fieldWithCpCtor.loc, "field with copy constructor defined here"); - return false; + return; } - else if (!fieldWithCpCtor) - return false; - return true; + + if (fieldWithCpCtor && !hasCopyCtor) + needCopyCtor = true; + if (fieldWithMoveCtor && !hasMoveCtor) + needMoveCtor = true; } /** @@ -1713,28 +1755,20 @@ LcheckFields: * } * * Params: - * sd = the `struct` for which the copy constructor is generated - * sc = the scope where the copy constructor is generated - * hasMoveCtor = set to true when a move constructor is also detected - * - * Returns: - * `true` if `struct` sd defines a copy constructor (explicitly or generated), - * `false` otherwise. + * sd = the `struct` for which the constructor is generated + * sc = the scope where the constructor is generated + * move = true means generate the move constructor, otherwise copy constructor * References: * https://dlang.org/spec/struct.html#struct-copy-constructor */ -bool buildCopyCtor(StructDeclaration sd, Scope* sc, out bool hasMoveCtor) +void buildCopyOrMoveCtor(StructDeclaration sd, Scope* sc, bool move) { - bool hasCpCtor; - if (!needCopyCtor(sd, hasCpCtor, hasMoveCtor)) - return hasCpCtor; - - //printf("generating copy constructor for %s\n", sd.toChars()); + //printf("buildCopyOrMoveCtor() generating %s constructor for %s\n", move ? "move".ptr : "copy".ptr, sd.toChars()); const MOD paramMod = MODFlags.wild; const MOD funcMod = MODFlags.wild; - auto ccd = generateCopyCtorDeclaration(sd, ModToStc(paramMod), ModToStc(funcMod)); - auto copyCtorBody = generateCopyCtorBody(sd); - ccd.fbody = copyCtorBody; + auto ccd = generateCtorDeclaration(sd, ModToStc(paramMod), ModToStc(funcMod), move); + auto ctorBody = generateCtorBody(sd, move); + ccd.fbody = ctorBody; sd.members.push(ccd); ccd.addMember(sc, sd); const errors = global.startGagging(); @@ -1751,5 +1785,4 @@ bool buildCopyCtor(StructDeclaration sd, Scope* sc, out bool hasMoveCtor) ccd.storage_class |= STC.disable; ccd.fbody = null; } - return true; } diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d index 156c5f8c7e05..a6cfe6e9eafe 100644 --- a/gcc/d/dmd/ctfeexpr.d +++ b/gcc/d/dmd/ctfeexpr.d @@ -1226,10 +1226,7 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide { return 1; // they are not equal } - else - { - return (r1 != r2); - } + return (r1 != r2); } else if (e1.type.isComplex()) { @@ -1242,33 +1239,30 @@ private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool ide // For structs, we only need to return 0 or 1 (< and > aren't legal). if (es1.sd != es2.sd) return 1; - else if ((!es1.elements || !es1.elements.length) && (!es2.elements || !es2.elements.length)) + if ((!es1.elements || !es1.elements.length) && (!es2.elements || !es2.elements.length)) return 0; // both arrays are empty - else if (!es1.elements || !es2.elements) + if (!es1.elements || !es2.elements) return 1; - else if (es1.elements.length != es2.elements.length) + if (es1.elements.length != es2.elements.length) return 1; - else + foreach (size_t i; 0 .. es1.elements.length) { - foreach (size_t i; 0 .. es1.elements.length) - { - Expression ee1 = (*es1.elements)[i]; - Expression ee2 = (*es2.elements)[i]; + Expression ee1 = (*es1.elements)[i]; + Expression ee2 = (*es2.elements)[i]; - // https://issues.dlang.org/show_bug.cgi?id=16284 - if (ee1.op == EXP.void_ && ee2.op == EXP.void_) // if both are VoidInitExp - continue; + // https://issues.dlang.org/show_bug.cgi?id=16284 + if (ee1.op == EXP.void_ && ee2.op == EXP.void_) // if both are VoidInitExp + continue; - if (ee1 == ee2) - continue; - if (!ee1 || !ee2) - return 1; - const int cmp = ctfeRawCmp(loc, ee1, ee2, identity); - if (cmp) - return 1; - } - return 0; // All elements are equal + if (ee1 == ee2) + continue; + if (!ee1 || !ee2) + return 1; + const int cmp = ctfeRawCmp(loc, ee1, ee2, identity); + if (cmp) + return 1; } + return 0; // All elements are equal } if (e1.op == EXP.assocArrayLiteral && e2.op == EXP.assocArrayLiteral) { @@ -1361,11 +1355,11 @@ bool ctfeCmp(const ref Loc loc, EXP op, Expression e1, Expression e2) if (t1.isString() && t2.isString()) return specificCmp(op, ctfeRawCmp(loc, e1, e2)); - else if (t1.isReal()) + if (t1.isReal()) return realCmp(op, e1.toReal(), e2.toReal()); - else if (t1.isImaginary()) + if (t1.isImaginary()) return realCmp(op, e1.toImaginary(), e2.toImaginary()); - else if (t1.isUnsigned() || t2.isUnsigned()) + if (t1.isUnsigned() || t2.isUnsigned()) return intUnsignedCmp(op, e1.toInteger(), e2.toInteger()); else return intSignedCmp(op, e1.toInteger(), e2.toInteger()); diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index 7c675eba67c2..0c4b469de5d4 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -474,7 +474,7 @@ MATCH implicitConvTo(Expression e, Type t) case Tint8: if (ty == Tuns64 && value & ~0x7FU) return MATCH.nomatch; - else if (cast(byte)value != value) + if (cast(byte)value != value) return MATCH.nomatch; break; @@ -1499,12 +1499,11 @@ MATCH implicitConvTo(Type from, Type to) { if (from.mod == to.mod) return MATCH.exact; - else if (MODimplicitConv(from.mod, to.mod)) + if (MODimplicitConv(from.mod, to.mod)) return MATCH.constant; - else if (!((from.mod ^ to.mod) & MODFlags.shared_)) // for wild matching + if (!((from.mod ^ to.mod) & MODFlags.shared_)) // for wild matching return MATCH.constant; - else - return MATCH.convert; + return MATCH.convert; } if (from.ty == Tvoid || to.ty == Tvoid) @@ -4150,9 +4149,9 @@ Expression typeCombine(BinExp be, Scope* sc) // struct+struct, and class+class are errors if (t1.ty == Tstruct && t2.ty == Tstruct) return errorReturn(); - else if (t1.ty == Tclass && t2.ty == Tclass) + if (t1.ty == Tclass && t2.ty == Tclass) return errorReturn(); - else if (t1.ty == Taarray && t2.ty == Taarray) + if (t1.ty == Taarray && t2.ty == Taarray) return errorReturn(); } @@ -4399,10 +4398,9 @@ IntRange getIntRange(Expression e) VarDeclaration vd = e.var.isVarDeclaration(); if (vd && vd.range) return vd.range._cast(e.type); - else if (vd && vd._init && !vd.type.isMutable() && (ie = vd.getConstInitializer()) !is null) + if (vd && vd._init && !vd.type.isMutable() && (ie = vd.getConstInitializer()) !is null) return getIntRange(ie); - else - return visit(e); + return visit(e); } IntRange visitComma(CommaExp e) diff --git a/gcc/d/dmd/dimport.d b/gcc/d/dmd/dimport.d index 96e821aea6af..ec7abb558e52 100644 --- a/gcc/d/dmd/dimport.d +++ b/gcc/d/dmd/dimport.d @@ -50,16 +50,13 @@ extern (C++) final class Import : Dsymbol // import [aliasId] = std.stdio; return aliasId; } - else if (packages.length > 0) + if (packages.length > 0) { // import [std].stdio; return packages[0]; } - else - { - // import [id]; - return id; - } + // import [id]; + return id; } super(loc, selectIdent()); diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index 7996d3441934..f26c5812ddf9 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -310,8 +310,9 @@ extern (C++) class Package : ScopeDsymbol packages ~= s.ident; reverse(packages); - if (Module.find(getFilename(packages, ident))) - Module.load(Loc.initial, packages, this.ident); + ImportPathInfo pathThatFoundThis; + if (Module.find(getFilename(packages, ident), pathThatFoundThis)) + Module.load(Loc.initial, packages, this.ident, pathThatFoundThis); else isPkgMod = PKG.package_; } @@ -499,12 +500,18 @@ extern (C++) final class Module : Package static const(char)* find(const(char)* filename) { - return find(filename.toDString).ptr; + ImportPathInfo pathThatFoundThis; // is this needed? In fact is this function needed still??? + return find(filename.toDString, pathThatFoundThis).ptr; } - extern (D) static const(char)[] find(const(char)[] filename) + extern (D) static const(char)[] find(const(char)[] filename, out ImportPathInfo pathThatFoundThis) { - return global.fileManager.lookForSourceFile(filename, global.path[]); + ptrdiff_t whichPathFoundThis; + const(char)[] ret = global.fileManager.lookForSourceFile(filename, global.path[], whichPathFoundThis); + + if (whichPathFoundThis >= 0) + pathThatFoundThis = global.path[whichPathFoundThis]; + return ret; } extern (C++) static Module load(const ref Loc loc, Identifiers* packages, Identifier ident) @@ -512,7 +519,7 @@ extern (C++) final class Module : Package return load(loc, packages ? (*packages)[] : null, ident); } - extern (D) static Module load(const ref Loc loc, Identifier[] packages, Identifier ident) + extern (D) static Module load(const ref Loc loc, Identifier[] packages, Identifier ident, ImportPathInfo pathInfo = ImportPathInfo.init) { //printf("Module::load(ident = '%s')\n", ident.toChars()); // Build module filename by turning: @@ -521,11 +528,17 @@ extern (C++) final class Module : Package // foo\bar\baz const(char)[] filename = getFilename(packages, ident); // Look for the source file - if (const result = find(filename)) + ImportPathInfo importPathThatFindUs; + if (const result = find(filename, importPathThatFindUs)) + { filename = result; // leaks + pathInfo = importPathThatFindUs; + } auto m = new Module(loc, filename, ident, 0, 0); + // TODO: apply import path information (pathInfo) on to module + if (!m.read(loc)) return null; if (global.params.v.verbose) @@ -662,7 +675,7 @@ extern (C++) final class Module : Package if (global.path.length) { foreach (i, p; global.path[]) - fprintf(stderr, "import path[%llu] = %s\n", cast(ulong)i, p); + fprintf(stderr, "import path[%llu] = %s\n", cast(ulong)i, p.path); } else { diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d index 21391dc18388..eba8dddaf988 100644 --- a/gcc/d/dmd/doc.d +++ b/gcc/d/dmd/doc.d @@ -477,7 +477,7 @@ void gendocfile(Module m, const char[] ddoctext, const char* datetime, ErrorSink auto p = slice.ptr; for (size_t j = 0; j < slice.length; j++) { - char c = p[j]; + const c = p[j]; if (c == 0xFF && j + 1 < slice.length) { j++; @@ -510,7 +510,7 @@ void escapeDdocString(ref OutBuffer buf, size_t start) { for (size_t u = start; u < buf.length; u++) { - char c = buf[u]; + const c = buf[u]; switch (c) { case '$': @@ -637,7 +637,7 @@ private void escapeStrayParenthesis(Loc loc, ref OutBuffer buf, size_t start, bo for (size_t u = buf.length; u > start;) { u--; - char c = buf[u]; + const c = buf[u]; switch (c) { case ')': diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d index abeffcb39d2d..9a9058f61dc8 100644 --- a/gcc/d/dmd/dstruct.d +++ b/gcc/d/dmd/dstruct.d @@ -323,7 +323,9 @@ extern (C++) class StructDeclaration : AggregateDeclaration bool hasCpCtorLocal; bool hasMoveCtorLocal; - needCopyCtor(this, hasCpCtorLocal, hasMoveCtorLocal); + bool needCopyCtor; + bool needMoveCtor; + needCopyOrMoveCtor(this, hasCpCtorLocal, hasMoveCtorLocal, needCopyCtor, needMoveCtor); if (enclosing || // is nested search(this, loc, Id.postblit) || // has postblit diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 1ab646f41382..0d87f6e26ecc 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -2513,10 +2513,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf()) { //printf("copy constructor %p\n", ctd); + assert(!ctd.isCpCtor && !ctd.isMoveCtor); if (param.storageClass & STC.ref_) ctd.isCpCtor = true; // copy constructor else ctd.isMoveCtor = true; // move constructor + assert(!(ctd.isCpCtor && ctd.isMoveCtor)); } } } @@ -3007,8 +3009,34 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor buildDtors(sd, sc2); + bool hasCopyCtor; bool hasMoveCtor; - sd.hasCopyCtor = buildCopyCtor(sd, sc2, hasMoveCtor); + bool needCopyCtor; + bool needMoveCtor; + needCopyOrMoveCtor(sd, hasCopyCtor, hasMoveCtor, needCopyCtor, needMoveCtor); + //printf("%s hasCopy %d hasMove %d needCopy %d needMove %d\n", sd.toChars(), hasCopyCtor, hasMoveCtor, needCopyCtor, needMoveCtor); + + /* When generating a move ctor, generate a copy ctor too, otherwise + * https://github.com/s-ludwig/taggedalgebraic/issues/75 + */ + if (0 && needMoveCtor && !hasCopyCtor) + { + needCopyCtor = true; + } + + if (needCopyCtor) + { + assert(hasCopyCtor == false); + buildCopyOrMoveCtor(sd, sc2, false); // build copy constructor + hasCopyCtor = true; + } + if (needMoveCtor) + { + assert(hasMoveCtor == false); + buildCopyOrMoveCtor(sd, sc2, true); // build move constructor + hasMoveCtor = true; + } + sd.hasCopyCtor = hasCopyCtor; sd.hasMoveCtor = hasMoveCtor; sd.postblit = buildPostBlit(sd, sc2); @@ -6601,7 +6629,7 @@ private extern(C++) class SearchVisitor : Visitor s = b.sym.search(loc, ident, flags); if (!s) continue; - else if (s == cd) // happens if s is nested in this and derives from this + if (s == cd) // happens if s is nested in this and derives from this s = null; else if (!(flags & SearchOpt.ignoreVisibility) && !(s.visible().kind == Visibility.Kind.protected_) && !symbolIsVisible(cd, s)) s = null; @@ -7265,7 +7293,7 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor fieldState.fieldSize = memsize; else { - auto size = (pastField + 7) / 8; + const size = (pastField + 7) / 8; fieldState.fieldSize = size; //printf(" offset: %d, size: %d\n", offset, size); if (isunion) diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index 5bb70495bb3d..7f7437cdb151 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -910,7 +910,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol */ extern (D) TemplateTupleParameter isVariadic() { - size_t dim = parameters.length; + const dim = parameters.length; if (dim == 0) return null; return (*parameters)[dim - 1].isTemplateTupleParameter(); @@ -6129,14 +6129,13 @@ MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, Templ if (auto ttp = tp.isTemplateTypeParameter()) return matchArgType(ttp); - else if (auto tvp = tp.isTemplateValueParameter()) + if (auto tvp = tp.isTemplateValueParameter()) return matchArgValue(tvp); - else if (auto tap = tp.isTemplateAliasParameter()) + if (auto tap = tp.isTemplateAliasParameter()) return matchArgAlias(tap); - else if (auto ttp = tp.isTemplateTupleParameter()) + if (auto ttp = tp.isTemplateTupleParameter()) return matchArgTuple(ttp); - else - assert(0); + assert(0); } diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d index 296e13c63d51..efd0a2f53e20 100644 --- a/gcc/d/dmd/dtoh.d +++ b/gcc/d/dmd/dtoh.d @@ -2796,7 +2796,7 @@ public: { if (vd._init && !vd._init.isVoidInitializer()) return AST.initializerToExpression(vd._init); - else if (auto ts = vd.type.isTypeStruct()) + if (auto ts = vd.type.isTypeStruct()) { if (!ts.sym.noDefaultCtor && !ts.sym.isUnionDeclaration()) { diff --git a/gcc/d/dmd/errors.d b/gcc/d/dmd/errors.d index 1babb18bcc6b..7faa536dea6f 100644 --- a/gcc/d/dmd/errors.d +++ b/gcc/d/dmd/errors.d @@ -197,6 +197,16 @@ else va_end(ap); } +/// Callback for when the backend wants to report an error +extern(C++) void errorBackend(const(char)* filename, uint linnum, uint charnum, const(char)* format, ...) +{ + const loc = Loc(filename, linnum, charnum); + va_list ap; + va_start(ap, format); + verrorReport(loc, format, ap, ErrorKind.error); + va_end(ap); +} + /** * Print additional details about an error message. * Doesn't increase the error count or print an additional error prefix. @@ -420,7 +430,10 @@ else * p1 = additional message prefix * p2 = additional message prefix */ -extern (C++) void verrorReport(const ref Loc loc, const(char)* format, va_list ap, ErrorKind kind, const(char)* p1 = null, const(char)* p2 = null); +private extern(C++) void verrorReport(const ref Loc loc, const(char)* format, va_list ap, ErrorKind kind, const(char)* p1 = null, const(char)* p2 = null); + +/// ditto +private extern(C++) void verrorReport(const SourceLoc loc, const(char)* format, va_list ap, ErrorKind kind, const(char)* p1 = null, const(char)* p2 = null); /** * Implements $(D errorSupplemental), $(D warningSupplemental), and @@ -433,7 +446,10 @@ extern (C++) void verrorReport(const ref Loc loc, const(char)* format, va_list a * ap = printf-style variadic arguments * kind = kind of error being printed */ -extern (C++) void verrorReportSupplemental(const ref Loc loc, const(char)* format, va_list ap, ErrorKind kind); +private extern(C++) void verrorReportSupplemental(const ref Loc loc, const(char)* format, va_list ap, ErrorKind kind); + +/// ditto +private extern(C++) void verrorReportSupplemental(const SourceLoc loc, const(char)* format, va_list ap, ErrorKind kind); /** * The type of the fatal error handler diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 355bdc42468e..2a828d85473f 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -2805,11 +2805,11 @@ extern (C++) final class FuncExp : Expression { if (td) return new FuncExp(loc, td.syntaxCopy(null)); - else if (fd.semanticRun == PASS.initial) + if (fd.semanticRun == PASS.initial) return new FuncExp(loc, fd.syntaxCopy(null)); - else // https://issues.dlang.org/show_bug.cgi?id=13481 - // Prevent multiple semantic analysis of lambda body. - return new FuncExp(loc, fd); + // https://issues.dlang.org/show_bug.cgi?id=13481 + // Prevent multiple semantic analysis of lambda body. + return new FuncExp(loc, fd); } override const(char)* toChars() const @@ -3573,10 +3573,9 @@ TypeFunction calledFunctionType(CallExp ce) t = t.toBasetype(); if (auto tf = t.isTypeFunction()) return tf; - else if (auto td = t.isTypeDelegate()) + if (auto td = t.isTypeDelegate()) return td.nextOf().isTypeFunction(); - else - return null; + return null; } FuncDeclaration isFuncAddress(Expression e, bool* hasOverloads = null) @safe diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 302038701aff..cd7548ea27cf 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -118,10 +118,9 @@ private bool isNeedThisScope(Scope* sc, Declaration d) { if (ad2 == ad) return false; - else if (ad2.isNested()) + if (ad2.isNested()) continue; - else - return true; + return true; } if (FuncDeclaration f = s.isFuncDeclaration()) { @@ -1521,7 +1520,7 @@ Expression resolvePropertiesOnly(Scope* sc, Expression e1) } else if (auto oe = e1.isOverExp()) return handleOverloadSet(oe.vars); - else if (auto dti = e1.isDotTemplateInstanceExp()) + if (auto dti = e1.isDotTemplateInstanceExp()) { if (dti.ti.tempdecl) if (auto td = dti.ti.tempdecl.isTemplateDeclaration()) @@ -1529,7 +1528,7 @@ Expression resolvePropertiesOnly(Scope* sc, Expression e1) } else if (auto dte = e1.isDotTemplateExp()) return handleTemplateDecl(dte.td); - else if (auto se = e1.isScopeExp()) + if (auto se = e1.isScopeExp()) { Dsymbol s = se.sds; TemplateInstance ti = s.isTemplateInstance(); @@ -1539,7 +1538,7 @@ Expression resolvePropertiesOnly(Scope* sc, Expression e1) } else if (auto et = e1.isTemplateExp()) return handleTemplateDecl(et.td); - else if (e1.isDotVarExp() && e1.type.isTypeFunction()) + if (e1.isDotVarExp() && e1.type.isTypeFunction()) { DotVarExp dve = e1.isDotVarExp(); return handleFuncDecl(dve.var.isFuncDeclaration()); @@ -6163,7 +6162,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (sd.ctor) { auto ctor = sd.ctor.isCtorDeclaration(); - if (ctor && ctor.isCpCtor && ctor.isGenerated()) + if (ctor && (ctor.isCpCtor || ctor.isMoveCtor) && ctor.isGenerated()) sd.ctor = null; } @@ -7262,7 +7261,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return no(); if (e.tok2 == TOK.package_ && p.isModule()) // Note that isModule() will return null for package modules because they're not actually instances of Module. return no(); - else if(e.tok2 == TOK.module_ && !(p.isModule() || p.isPackageMod())) + if (e.tok2 == TOK.module_ && !(p.isModule() || p.isPackageMod())) return no(); tded = e.targ; return yes(); @@ -17036,6 +17035,7 @@ bool checkDisabled(Declaration d, Loc loc, Scope* sc, bool isAliasedDeclaration if (auto ctor = d.isCtorDeclaration()) { + //printf("checkDisabled() %s %s\n", ctor.toPrettyChars(), toChars(ctor.type)); if (ctor.isCpCtor && ctor.isGenerated()) { .error(loc, "generating an `inout` copy constructor for `struct %s` failed, therefore instances of it are uncopyable", d.parent.toPrettyChars()); diff --git a/gcc/d/dmd/file_manager.d b/gcc/d/dmd/file_manager.d index 6ad3d621708d..7f39ec91f023 100644 --- a/gcc/d/dmd/file_manager.d +++ b/gcc/d/dmd/file_manager.d @@ -159,16 +159,20 @@ nothrow: * Does not open the file. * Params: * filename = as supplied by the user - * paths = paths to look for filename + * pathsInfo = pathsInfo to look for filename with metadata + * whichPathFoundThis = Which path from `path` was used in determining the output path, or -1 if unknown. * Returns: * the found file name or * `null` if it is not different from filename. */ - const(char)[] lookForSourceFile(const char[] filename, const char*[] paths) + const(char)[] lookForSourceFile(const char[] filename, const ImportPathInfo[] pathsInfo, out ptrdiff_t whichPathFoundThis) { //printf("lookForSourceFile(`%.*s`)\n", cast(int)filename.length, filename.ptr); - /* Search along paths[] for .di file, then .d file. + /* Search along pathsInfo[] for .di file, then .d file. */ + + whichPathFoundThis = -1; + // see if we should check for the module locally. bool checkLocal = pathCache.pathExists(filename); const sdi = FileName.forceExt(filename, hdr_ext); @@ -206,11 +210,11 @@ nothrow: if (FileName.absolute(filename)) return null; - if (!paths.length) + if (!pathsInfo.length) return null; - foreach (entry; paths) + foreach (pathIndex, entry; pathsInfo) { - const p = entry.toDString(); + const p = entry.path.toDString(); const(char)[] n = FileName.combine(p, sdi); @@ -225,6 +229,7 @@ nothrow: n = FileName.combine(p, sd); if (FileName.exists(n) == 1) { + whichPathFoundThis = pathIndex; return n; } FileName.free(n.ptr); @@ -236,11 +241,15 @@ nothrow: if (pathCache.isExistingPath(n)) { const n2i = FileName.combine(n, package_di); - if (FileName.exists(n2i) == 1) + if (FileName.exists(n2i) == 1) { + whichPathFoundThis = pathIndex; return n2i; + } + FileName.free(n2i.ptr); const n2 = FileName.combine(n, package_d); if (FileName.exists(n2) == 1) { + whichPathFoundThis = pathIndex; return n2; } FileName.free(n2.ptr); @@ -258,18 +267,20 @@ nothrow: if (FileName.exists(sc) == 1) return sc; scope(exit) FileName.free(sc.ptr); - foreach (entry; paths) + foreach (pathIndex, entry; pathsInfo) { - const p = entry.toDString(); + const p = entry.path.toDString(); const(char)[] n = FileName.combine(p, si); if (FileName.exists(n) == 1) { + whichPathFoundThis = pathIndex; return n; } FileName.free(n.ptr); n = FileName.combine(p, sc); if (FileName.exists(n) == 1) { + whichPathFoundThis = pathIndex; return n; } FileName.free(n.ptr); diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index 40d39aea0ea8..b42ac768b450 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -1373,11 +1373,9 @@ extern (C++) final class CtorDeclaration : FuncDeclaration { bool isCpCtor; // copy constructor bool isMoveCtor; // move constructor (aka rvalue constructor) - extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Type type, bool isCpCtor = false, bool isMoveCtor = false) + extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Type type) { super(loc, endloc, Id.ctor, stc, type); - this.isCpCtor = isCpCtor; - this.isMoveCtor = isMoveCtor; //printf("CtorDeclaration(loc = %s) %s %p\n", loc.toChars(), toChars(), this); } diff --git a/gcc/d/dmd/funcsem.d b/gcc/d/dmd/funcsem.d index 39da0256eebc..2bd593ed49b2 100644 --- a/gcc/d/dmd/funcsem.d +++ b/gcc/d/dmd/funcsem.d @@ -1103,7 +1103,7 @@ Ldone: { printedMain = true; auto name = mod.srcfile.toChars(); - auto path = FileName.searchPath(global.path, name, true); + auto path = FileName.searchPath(global.importPaths, name, true); message("entry %-10s\t%s", type, path ? path : name); } } @@ -1536,7 +1536,7 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s, version (none) { - printf("resolveFuncCall('%s')\n", s.toChars()); + printf("resolveFuncCall() %s)\n", s.toChars()); if (tthis) printf("\tthis: %s\n", tthis.toChars()); if (fargs) @@ -1548,7 +1548,6 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s, printf("\t%s: %s\n", arg.toChars(), arg.type.toChars()); } } - printf("\tfnames: %s\n", fnames ? fnames.toChars() : "null"); } if (tiargs && arrayObjectIsError(*tiargs)) @@ -2270,6 +2269,9 @@ int getLevelAndCheck(FuncDeclaration fd, const ref Loc loc, Scope* sc, FuncDecla /********************************** * Decide if attributes for this function can be inferred from examining * the function body. + * Params: + * fd = function to infer attributes for + * sc = context * Returns: * true if can */ @@ -2291,7 +2293,8 @@ bool canInferAttributes(FuncDeclaration fd, Scope* sc) (!fd.isMember() || sc.func.isSafeBypassingInference() && !fd.isInstantiated())) return true; if (fd.isFuncLiteralDeclaration() || // externs are not possible with literals - (fd.storage_class & STC.inference) || // do attribute inference + (fd.storage_class & STC.inference) || // do attribute inference + fd.isGenerated || // compiler generated function (fd.inferRetType && !fd.isCtorDeclaration())) return true; if (fd.isInstantiated()) @@ -2994,7 +2997,7 @@ extern (D) bool checkNRVO(FuncDeclaration fd) auto v = ve.var.isVarDeclaration(); if (!v || v.isReference()) return false; - else if (fd.nrvo_var is null) + if (fd.nrvo_var is null) { // Variables in the data segment (e.g. globals, TLS or not), // parameters and closure variables cannot be NRVOed. diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d index 77bb4986e724..4d3c1b9d1970 100644 --- a/gcc/d/dmd/globals.d +++ b/gcc/d/dmd/globals.d @@ -151,6 +151,10 @@ extern(C++) struct Verbose } } +extern (C++) struct ImportPathInfo { + const(char)* path; // char*'s of where to look for import modules +} + /// Put command line switches in here extern (C++) struct Param { @@ -223,7 +227,7 @@ extern (C++) struct Param const(char)[] argv0; // program name Array!(const(char)*) modFileAliasStrings; // array of char*'s of -I module filename alias strings - Array!(const(char)*) imppath; // array of char*'s of where to look for import modules + Array!(ImportPathInfo) imppath; // array of import path information of where to look for import modules Array!(const(char)*) fileImppath; // array of char*'s of where to look for file import modules const(char)[] objdir; // .obj/.lib file output directory const(char)[] objname; // .obj file output name @@ -291,7 +295,8 @@ extern (C++) struct Global string copyright = "Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved"; string written = "written by Walter Bright"; - Array!(const(char)*) path; /// Array of char*'s which form the import lookup path + Array!(ImportPathInfo) path; /// Array of path informations which form the import lookup path + Array!(const(char)*) importPaths; /// Array of char*'s which form the import lookup path without metadata Array!(const(char)*) filePath; /// Array of char*'s which form the file import lookup path private enum string _version = import("VERSION"); diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index 669f83e2101f..6dd4be4b0a01 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -155,6 +155,14 @@ struct Verbose unsigned errorSupplementCount(); }; +struct ImportPathInfo +{ + const char* path; + + ImportPathInfo() : path(NULL) { } + ImportPathInfo(const char* p) : path(p) { } +}; + // Put command line switches in here struct Param { @@ -227,7 +235,7 @@ struct Param DString argv0; // program name Array<const char *> modFileAliasStrings; // array of char*'s of -I module filename alias strings - Array<const char *> imppath; // array of char*'s of where to look for import modules + Array<ImportPathInfo> imppath; // array of import path information of where to look for import modules Array<const char *> fileImppath; // array of char*'s of where to look for file import modules DString objdir; // .obj/.lib file output directory DString objname; // .obj file output name @@ -315,8 +323,9 @@ struct Global const DString copyright; const DString written; - Array<const char *> path; // Array of char*'s which form the import lookup path - Array<const char *> filePath; // Array of char*'s which form the file import lookup path + Array<ImportPathInfo> path; // Array of path informations which form the import lookup path + Array<const char *> importPaths; // Array of char*'s which form the import lookup path without metadata + Array<const char *> filePath; // Array of char*'s which form the file import lookup path char datetime[26]; /// string returned by ctime() CompileEnv compileEnv; diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index a5e897d62466..d391bdb581ac 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -2881,9 +2881,9 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt default: if (auto be = e.isBinExp()) return visitBin(be); - else if (auto ue = e.isUnaExp()) + if (auto ue = e.isUnaExp()) return visitUna(ue); - else if (auto de = e.isDefaultInitExp()) + if (auto de = e.isDefaultInitExp()) return visitDefaultInit(e.isDefaultInitExp()); return visit(e); diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d index b1b5a4f6cb86..37f8cfdbeac9 100644 --- a/gcc/d/dmd/json.d +++ b/gcc/d/dmd/json.d @@ -906,7 +906,7 @@ public: arrayStart(); foreach (importPath; global.params.imppath[]) { - item(importPath.toDString); + item(importPath.path.toDString); } arrayEnd(); diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index d9f4b1c678f6..7bf32a9ddb8d 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -643,7 +643,7 @@ class Lexer if (isidchar(c)) continue; - else if (c & 0x80) + if (c & 0x80) { const s = p; const u = decodeUTF(); diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 4a4254fcbdd3..b6d44c7f136b 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -1294,7 +1294,7 @@ extern (C++) abstract class Type : ASTNode { if (isImmutable()) return MODFlags.immutable_; - else if (isWildConst()) + if (isWildConst()) { if (t.isWildConst()) return MODFlags.wild; diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index b408f8bffa4f..415d57824d14 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -2146,11 +2146,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer nextToken(); if (id == Id.Windows) return returnLinkage(LINK.windows); - else if (id == Id.D) + if (id == Id.D) return returnLinkage(LINK.d); - else if (id == Id.System) + if (id == Id.System) return returnLinkage(LINK.system); - else if (id == Id.Objective) // Looking for tokens "Objective-C" + if (id == Id.Objective) // Looking for tokens "Objective-C" { if (token.value != TOK.min) return invalidLinkage(); diff --git a/gcc/d/dmd/pragmasem.d b/gcc/d/dmd/pragmasem.d index f2f748500a63..c5d18ef40a5a 100644 --- a/gcc/d/dmd/pragmasem.d +++ b/gcc/d/dmd/pragmasem.d @@ -511,10 +511,9 @@ package PINLINE evalPragmaInline(Loc loc, Scope* sc, Expressions* args) const opt = e.toBool(); if (opt.isEmpty()) return PINLINE.default_; - else if (opt.get()) + if (opt.get()) return PINLINE.always; - else - return PINLINE.never; + return PINLINE.never; } /** @@ -566,11 +565,9 @@ private bool pragmaMsgSemantic(Loc loc, Scope* sc, Expressions* args) OutBuffer buf; if (expressionsToString(buf, sc, args, loc, "while evaluating `pragma(msg, %s)`", false)) return false; - else - { - buf.writestring("\n"); - fprintf(stderr, buf.extractChars); - } + + buf.writestring("\n"); + fprintf(stderr, buf.extractChars); return true; } diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index 92e00e8992b9..3553d3dbbf46 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -1333,7 +1333,7 @@ private extern(C++) final class Semantic3Visitor : Visitor // Don't allow D `immutable` and `shared` types to be interfaced with C++ if (type.isImmutable() || type.isShared()) return true; - else if (Type cpptype = target.cpp.parameterType(type)) + if (Type cpptype = target.cpp.parameterType(type)) type = cpptype; if (origType is null) diff --git a/gcc/d/dmd/templateparamsem.d b/gcc/d/dmd/templateparamsem.d index f2dc50ebb702..8a08e7165249 100644 --- a/gcc/d/dmd/templateparamsem.d +++ b/gcc/d/dmd/templateparamsem.d @@ -170,7 +170,7 @@ RootObject aliasParameterSemantic(Loc loc, Scope* sc, RootObject o, TemplatePara Dsymbol s = ta.toDsymbol(sc); if (s) return s; - else if (TypeInstance ti = ta.isTypeInstance()) + if (TypeInstance ti = ta.isTypeInstance()) { Type t; const errors = global.errors; @@ -183,14 +183,13 @@ RootObject aliasParameterSemantic(Loc loc, Scope* sc, RootObject o, TemplatePara // see https://issues.dlang.org/show_bug.cgi?id=16472 if (t) return t.typeSemantic(loc, sc); - else if (ea) + if (ea) { return eaCTFE(); } - else if (s) + if (s) return s; - else - assert(0); + assert(0); } else return ta.typeSemantic(loc, sc); diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index 34cdf816eb0f..42344c68fd0a 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -726,8 +726,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) if (ClassDeclaration cd = agg.isClassDeclaration()) return cd.com ? True() : False(); - else - return False(); + return False(); } if (e.ident == Id.identifier) { diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index c631e640815e..dc3f9da89410 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -1050,7 +1050,7 @@ private extern(D) MATCH argumentMatchParameter (FuncDeclaration fd, TypeFunction { if (cfd.isCpCtor && !arg.isLvalue()) return MATCH.nomatch; // copy constructor is only for lvalues - else if (cfd.isMoveCtor && arg.isLvalue()) + if (cfd.isMoveCtor && arg.isLvalue()) return MATCH.nomatch; // move constructor is only for rvalues } } @@ -7470,7 +7470,7 @@ bool isRecursiveAliasThis(ref Type att, Type t) auto tb = t.toBasetype(); if (att && tb.equivalent(att)) return true; - else if (!att && tb.checkAliasThisRec()) + if (!att && tb.checkAliasThisRec()) att = tb; return false; } diff --git a/gcc/d/dmd/typinf.d b/gcc/d/dmd/typinf.d index ceff41473e42..35d5ad40bebd 100644 --- a/gcc/d/dmd/typinf.d +++ b/gcc/d/dmd/typinf.d @@ -100,7 +100,6 @@ bool genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc) * loc = the location for reporting line nunbers in errors * t = the type to get the type of the `TypeInfo` object for * sc = the scope - * genObjCode = if true, object code will be generated for the obtained TypeInfo * Returns: * The type of the `TypeInfo` object associated with `t` */ diff --git a/gcc/testsuite/gdc.test/compilable/copyCtor2.d b/gcc/testsuite/gdc.test/compilable/copyCtor2.d new file mode 100644 index 000000000000..084ef3b3f25f --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/copyCtor2.d @@ -0,0 +1,14 @@ +/* This used to not be allowed + * https://github.com/dlang/dmd/pull/20634 + */ + +struct A +{ + this (ref shared A a) immutable {} +} + +struct B +{ + A a; + this(immutable B b) shared {} +} diff --git a/gcc/testsuite/gdc.test/compilable/cppmangle.d b/gcc/testsuite/gdc.test/compilable/cppmangle.d index 4b9046e81102..c6c921d7b0cb 100644 --- a/gcc/testsuite/gdc.test/compilable/cppmangle.d +++ b/gcc/testsuite/gdc.test/compilable/cppmangle.d @@ -666,6 +666,8 @@ extern (C++) class C18890_2 Agg s; } +void test18890() +{ version (CppMangle_Itanium) { static assert(C18890.__dtor.mangleof == "_ZN6C18890D1Ev"); @@ -690,6 +692,7 @@ version (CppMangle_MSVC) static assert(C18890_2.__xdtor.mangleof == "??_GC18890_2@@UEAAPEAXI@Z"); } } +} /**************************************/ // https://issues.dlang.org/show_bug.cgi?id=18891 @@ -704,6 +707,8 @@ extern (C++) class C18891 Agg s; } +void test18891() +{ version (CppMangle_Itanium) { static assert(C18891.__dtor.mangleof == "_ZN6C18891D1Ev"); @@ -722,6 +727,7 @@ version (CppMangle_MSVC) static assert(C18891.__xdtor.mangleof == "??_GC18891@@UEAAPEAXI@Z"); } } +} /**************************************/ // Test C++ operator mangling diff --git a/gcc/testsuite/gdc.test/compilable/testInference.d b/gcc/testsuite/gdc.test/compilable/testInference.d index bddbaf429465..5091b99896a1 100644 --- a/gcc/testsuite/gdc.test/compilable/testInference.d +++ b/gcc/testsuite/gdc.test/compilable/testInference.d @@ -817,4 +817,22 @@ void test13840() nothrow {} } -// Add more tests regarding inferences later. +/***************************************************/ +// https://github.com/dlang/dmd/pull/20685 + +struct T1 +{ + int a; + inout this(ref inout T1 t) @nogc nothrow pure { a = t.a; } +} + +struct S1 +{ + T1 t; // generate copy constructor, infer @nogc nothrow pure +} + +void test1() @nogc nothrow pure +{ + S1 s; + S1 t = s; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/failCopyCtor2.d b/gcc/testsuite/gdc.test/fail_compilation/failCopyCtor2.d deleted file mode 100644 index 5e8f8c40f7da..000000000000 --- a/gcc/testsuite/gdc.test/fail_compilation/failCopyCtor2.d +++ /dev/null @@ -1,19 +0,0 @@ -/* -TEST_OUTPUT: ---- -fail_compilation/failCopyCtor2.d(15): Error: `struct B` may not define a rvalue constructor and have fields with copy constructors -fail_compilation/failCopyCtor2.d(18): rvalue constructor defined here -fail_compilation/failCopyCtor2.d(17): field with copy constructor defined here ---- -*/ - -struct A -{ - this (ref shared A a) immutable {} -} - -struct B -{ - A a; - this(immutable B b) shared {} -} diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d index 8e10a7caae78..4638cdc139ab 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d @@ -296,7 +296,7 @@ fail_compilation/retscope2.d(1024): Error: assigning scope variable `p` to non-s fail_compilation/retscope2.d(1107): Error: returning scope variable `dg` is not allowed in a `@safe` function fail_compilation/retscope2.d(1216): Error: returning `s.foo()` escapes a reference to local variable `s` fail_compilation/retscope2.d(1233): Error: returning `t.foo()` escapes a reference to local variable `t` -fail_compilation/retscope2.d(1306): Error: escaping a reference to local variable `i by copying `& i` into allocated memory is not allowed in a `@safe` function +fail_compilation/retscope2.d(1306): Error: escaping a reference to local variable `i` by copying `& i` into allocated memory is not allowed in a `@safe` function --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope3.d b/gcc/testsuite/gdc.test/fail_compilation/retscope3.d index 59bf11b62683..819071f15d04 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope3.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope3.d @@ -51,8 +51,8 @@ void bar4() /* TEST_OUTPUT: --- -fail_compilation/retscope3.d(2008): Error: escaping a reference to local variable `i by copying `& i` into allocated memory is not allowed in a `@safe` function -fail_compilation/retscope3.d(2017): Error: escaping a reference to local variable `i by copying `S2000(& i)` into allocated memory is not allowed in a `@safe` function +fail_compilation/retscope3.d(2008): Error: escaping a reference to local variable `i` by copying `& i` into allocated memory is not allowed in a `@safe` function +fail_compilation/retscope3.d(2017): Error: escaping a reference to local variable `i` by copying `S2000(& i)` into allocated memory is not allowed in a `@safe` function fail_compilation/retscope3.d(4003): Error: escaping a reference to parameter `u` by copying `u[]` into allocated memory is not allowed in a `@safe` function fail_compilation/retscope3.d(4016): Error: storing reference to outer local variable `i` into allocated memory causes it to escape fail_compilation/retscope3.d(4025): Error: escaping reference to stack allocated value returned by `makeSA()` into allocated memory diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope6.d b/gcc/testsuite/gdc.test/fail_compilation/retscope6.d index 49751a4b339b..e3b734f03d40 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope6.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope6.d @@ -5,7 +5,7 @@ REQUIRED_ARGS: -preview=dip1000 /* TEST_OUTPUT: --- -fail_compilation/retscope6.d(6007): Error: escaping a reference to local variable `i by copying `& i` into allocated memory is not allowed in a `@safe` function +fail_compilation/retscope6.d(6007): Error: escaping a reference to local variable `i` by copying `& i` into allocated memory is not allowed in a `@safe` function --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test18282.d b/gcc/testsuite/gdc.test/fail_compilation/test18282.d index 97b2b2b13331..b5db07fd9385 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test18282.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test18282.d @@ -2,12 +2,12 @@ TEST_OUTPUT: --- fail_compilation/test18282.d(25): Error: returning scope variable `aa` is not allowed in a `@safe` function -fail_compilation/test18282.d(34): Error: escaping a reference to local variable `i by copying `& i` into allocated memory is not allowed in a `@safe` function -fail_compilation/test18282.d(35): Error: escaping a reference to local variable `i by copying `& i` into allocated memory is not allowed in a `@safe` function +fail_compilation/test18282.d(34): Error: escaping a reference to local variable `i` by copying `& i` into allocated memory is not allowed in a `@safe` function +fail_compilation/test18282.d(35): Error: escaping a reference to local variable `i` by copying `& i` into allocated memory is not allowed in a `@safe` function fail_compilation/test18282.d(36): Error: returning scope variable `staa` is not allowed in a `@safe` function -fail_compilation/test18282.d(44): Error: escaping a reference to local variable `i by copying `S2000(& i)` into allocated memory is not allowed in a `@safe` function -fail_compilation/test18282.d(53): Error: escaping a reference to local variable `i by copying `& i` into allocated memory is not allowed in a `@safe` function -fail_compilation/test18282.d(53): Error: escaping a reference to local variable `c by copying `& c` into allocated memory is not allowed in a `@safe` function +fail_compilation/test18282.d(44): Error: escaping a reference to local variable `i` by copying `S2000(& i)` into allocated memory is not allowed in a `@safe` function +fail_compilation/test18282.d(53): Error: escaping a reference to local variable `i` by copying `& i` into allocated memory is not allowed in a `@safe` function +fail_compilation/test18282.d(53): Error: escaping a reference to local variable `c` by copying `& c` into allocated memory is not allowed in a `@safe` function --- */ @@ -57,9 +57,9 @@ void bar3() /****************************** TEST_OUTPUT: --- -fail_compilation/test18282.d(1007): Error: escaping a reference to local variable `foo by copying `& foo` into allocated memory is not allowed in a `@safe` function -fail_compilation/test18282.d(1008): Error: escaping a reference to local variable `foo by copying `& foo` into allocated memory is not allowed in a `@safe` function -fail_compilation/test18282.d(1009): Error: escaping a reference to local variable `foo by copying `& foo` into allocated memory is not allowed in a `@safe` function +fail_compilation/test18282.d(1007): Error: escaping a reference to local variable `foo` by copying `& foo` into allocated memory is not allowed in a `@safe` function +fail_compilation/test18282.d(1008): Error: escaping a reference to local variable `foo` by copying `& foo` into allocated memory is not allowed in a `@safe` function +fail_compilation/test18282.d(1009): Error: escaping a reference to local variable `foo` by copying `& foo` into allocated memory is not allowed in a `@safe` function fail_compilation/test18282.d(1016): Error: escaping a reference to parameter `this` by copying `&this` into allocated memory is not allowed in a `@safe` function --- */ diff --git a/gcc/testsuite/gdc.test/runnable/rvalue1.d b/gcc/testsuite/gdc.test/runnable/rvalue1.d index f8134f718a9f..2592f2a9e95e 100644 --- a/gcc/testsuite/gdc.test/runnable/rvalue1.d +++ b/gcc/testsuite/gdc.test/runnable/rvalue1.d @@ -194,6 +194,56 @@ void test8() /********************************/ +struct T9 +{ + int i; + inout this(ref inout T9 t) { this.i = t.i - 1; printf("this(ref T9)\n"); } + inout this(inout T9 t) { this.i = t.i + 1; printf("this(T9)\n"); } +} + +struct S9 +{ + T9 t; + //inout this(return ref scope inout S9 t);// { this.i = t.i - 1; printf("this(ref T9)\n"); } + //@system inout this(return scope inout S9 t);// { this.i = t.i + 1; printf("this(T9)\n"); } +} + +void test9() +{ + S9 s; + s.t.i = 3; + S9 u = s; + printf("u.t.i = %d\n", u.t.i); + assert(u.t.i == 2); + + S9 v = __rvalue(u); + printf("v.t.i = %d\n", v.t.i); + assert(v.t.i == 3); +} + +/********************************/ +// https://github.com/s-ludwig/taggedalgebraic/issues/75 + +struct T10 +{ + string s; + this(T10) {} + this(string v) { s = v; } +} + +struct S10 +{ + T10 p; +} + +void test10() +{ + S10 s = S10(T10("hello")); + assert(s.p.s == "hello"); +} + +/********************************/ + int main() { test1(); @@ -204,6 +254,7 @@ int main() test6(); test7(); test8(); + test9(); return 0; } diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index b145d1bd6593..33bb398c00d4 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -c7902293d7df9d02546562cb09fc8439004a70d1 +d6f693b46a1565172cac7a1438905141783a164f 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/builtins.d b/libphobos/libdruntime/core/builtins.d index bc12759e9a18..4e0c6d4d622e 100644 --- a/libphobos/libdruntime/core/builtins.d +++ b/libphobos/libdruntime/core/builtins.d @@ -94,6 +94,23 @@ else version (DigitalMars) /// Provide static branch and value hints for the LDC/GDC compilers. /// DMD ignores these hints. -pragma(inline, true) bool likely(bool b) { return !!expect(b, true); } +pragma(inline, true) bool likely()(bool b) { return !!expect(b, true); } /// ditto -pragma(inline, true) bool unlikely(bool b) { return !!expect(b, false); } +pragma(inline, true) bool unlikely()(bool b) { return !!expect(b, false); } + +/// +@nogc nothrow pure @safe unittest +{ + int x = 12; + + expect(x, 12); + + if (likely(x > 0)) + { + // ... + } + else if (unlikely(x == int.min)) + { + // ... + } +} diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d index c9bde27da69e..e7efc8c3ec9a 100644 --- a/libphobos/libdruntime/core/demangle.d +++ b/libphobos/libdruntime/core/demangle.d @@ -1758,13 +1758,10 @@ pure @safe: if (parseMangledNameArg()) continue; - else - { - dst.len = l; - pos = p; - brp = b; - debug(trace) printf( "not a mangled name arg\n" ); - } + dst.len = l; + pos = p; + brp = b; + debug(trace) printf( "not a mangled name arg\n" ); } if ( isDigit( front ) && isDigit( peek( 1 ) ) ) { diff --git a/libphobos/libdruntime/core/internal/gc/os.d b/libphobos/libdruntime/core/internal/gc/os.d index bde90e952280..9142708a4a4f 100644 --- a/libphobos/libdruntime/core/internal/gc/os.d +++ b/libphobos/libdruntime/core/internal/gc/os.d @@ -67,9 +67,9 @@ else version (Posix) while (waited_pid == -1 && errno == EINTR); if (waited_pid == 0) return ChildStatus.running; - else if (errno == ECHILD) + if (errno == ECHILD) return ChildStatus.done; // someone called posix.syswait - else if (waited_pid != pid || status != 0) + if (waited_pid != pid || status != 0) onForkError(); return ChildStatus.done; } diff --git a/libphobos/libdruntime/core/sys/posix/sys/socket.d b/libphobos/libdruntime/core/sys/posix/sys/socket.d index 7c6fab6315a4..12824373d586 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/socket.d +++ b/libphobos/libdruntime/core/sys/posix/sys/socket.d @@ -30,6 +30,7 @@ else version (WatchOS) version (ARM) version = ARM_Any; version (AArch64) version = ARM_Any; version (HPPA) version = HPPA_Any; +version (HPPA64) version = HPPA_Any; version (MIPS32) version = MIPS_Any; version (MIPS64) version = MIPS_Any; version (PPC) version = PPC_Any; @@ -317,6 +318,7 @@ version (linux) SO_RCVLOWAT = 0x1004, SO_RCVTIMEO = 0x1006, SO_REUSEADDR = 0x0004, + SO_REUSEPORT = 0x0200, SO_SNDBUF = 0x1001, SO_SNDLOWAT = 0x1003, SO_SNDTIMEO = 0x1005, @@ -351,6 +353,7 @@ version (linux) SO_RCVLOWAT = 0x1004, SO_RCVTIMEO = 0x1006, SO_REUSEADDR = 0x0004, + SO_REUSEPORT = 0x0200, SO_SNDBUF = 0x1001, SO_SNDLOWAT = 0x1003, SO_SNDTIMEO = 0x1005, @@ -385,6 +388,7 @@ version (linux) SO_RCVLOWAT = 16, SO_RCVTIMEO = 18, SO_REUSEADDR = 2, + SO_REUSEPORT = 15, SO_SNDBUF = 7, SO_SNDLOWAT = 17, SO_SNDTIMEO = 19, @@ -454,6 +458,7 @@ version (linux) SO_RCVLOWAT = 18, SO_RCVTIMEO = 20, SO_REUSEADDR = 2, + SO_REUSEPORT = 15, SO_SNDBUF = 7, SO_SNDLOWAT = 19, SO_SNDTIMEO = 21, @@ -488,6 +493,7 @@ version (linux) SO_RCVLOWAT = 18, SO_RCVTIMEO = 20, SO_REUSEADDR = 2, + SO_REUSEPORT = 0x0200, //FIXME: the rest appear to be wrong SO_SNDBUF = 7, SO_SNDLOWAT = 19, SO_SNDTIMEO = 21, @@ -522,6 +528,7 @@ version (linux) SO_RCVLOWAT = 18, SO_RCVTIMEO = 20, SO_REUSEADDR = 2, + SO_REUSEPORT = 15, SO_SNDBUF = 7, SO_SNDLOWAT = 19, SO_SNDTIMEO = 21, @@ -556,6 +563,7 @@ version (linux) SO_RCVLOWAT = 18, SO_RCVTIMEO = 20, SO_REUSEADDR = 2, + SO_REUSEPORT = 15, SO_SNDBUF = 7, SO_SNDLOWAT = 19, SO_SNDTIMEO = 21, @@ -1547,6 +1555,7 @@ else version (Solaris) SO_RCVLOWAT = 0x1004, SO_RCVTIMEO = 0x1006, SO_REUSEADDR = 0x0004, + SO_REUSEPORT = 0x100e, SO_SNDBUF = 0x1001, SO_SNDLOWAT = 0x1003, SO_SNDTIMEO = 0x1005, diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index aa35eae57e2e..fdcc058c9035 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -03aeafd2095b563bb66b75342652d2dcea66c9e8 +336bed6d8ffec74d117b755866c5bd22e3d610a1 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/functional.d b/libphobos/src/std/functional.d index cf7e3ff8cc2e..b1b1382280d7 100644 --- a/libphobos/src/std/functional.d +++ b/libphobos/src/std/functional.d @@ -1349,7 +1349,8 @@ template memoize(alias fun) alias memoize = impl; } - auto impl(Args...)(Args args) if (is(typeof(fun(args)))) + auto impl(Args...)(Args args) + if (is(typeof(fun(args)))) { import std.typecons : Tuple, tuple; import std.traits : Unqual; @@ -1393,7 +1394,8 @@ template memoize(alias fun, uint maxSize) alias memoize = impl; } - auto impl(Args...)(Args args) if (is(typeof(fun(args)))) + auto impl(Args...)(Args args) + if (is(typeof(fun(args)))) { static if (args.length > 0) { diff --git a/libphobos/src/std/socket.d b/libphobos/src/std/socket.d index 7fa9974189f6..99ac97ac1e3a 100644 --- a/libphobos/src/std/socket.d +++ b/libphobos/src/std/socket.d @@ -15,7 +15,7 @@ /** * Socket primitives. - * Example: See $(SAMPLESRC listener.d) and $(SAMPLESRC htmlget.d) + * Example: See [listener.d](https://github.com/dlang/undeaD/blob/master/dmdsamples/listener.d) and [htmlget.d](https://github.com/dlang/undeaD/blob/master/dmdsamples/htmlget.d) * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). * Authors: Christopher E. Miller, $(HTTP klickverbot.at, David Nadlinger), * $(HTTP thecybershadow.net, Vladimir Panteleev) diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index bd462f53a5b1..a841e4720b2c 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -3348,7 +3348,7 @@ package(std) Rebindable2!T rebindable2(T)(T value) this(ref inout S rhs) @safe inout { - this.i = i; + this.i = rhs.i; copied = true; } } diff --git a/libphobos/testsuite/libphobos.init_fini/custom_gc.d b/libphobos/testsuite/libphobos.init_fini/custom_gc.d index cb7238409594..bcbd84c844f1 100644 --- a/libphobos/testsuite/libphobos.init_fini/custom_gc.d +++ b/libphobos/testsuite/libphobos.init_fini/custom_gc.d @@ -22,6 +22,12 @@ extern (C) void register_default_gcs() class MallocGC : GC { nothrow @nogc: + // To make sure all allocations are multiples of 8 bytes for alignment + private size_t alignUp(size_t size) + { + return (size + 7) & ~7LU; + } + static GC initialize() { import core.stdc.string : memcpy; @@ -81,21 +87,25 @@ nothrow @nogc: void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow { + size = alignUp(size); return sentinelAdd(.malloc(size + sentinelSize), size); } BlkInfo qalloc(size_t size, uint bits, const scope TypeInfo ti) nothrow { + size = alignUp(size); return BlkInfo(malloc(size, bits, ti), size); } void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow { + size = alignUp(size); return sentinelAdd(.calloc(1, size + sentinelSize), size); } void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow { + size = alignUp(size); return sentinelAdd(.realloc(p - sentinelSize, size + sentinelSize), size); }