]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
d: Merge upstream dmd, druntime d6f693b46a, phobos 336bed6d8.
authorIain Buclaw <ibuclaw@gdcproject.org>
Tue, 14 Jan 2025 19:51:45 +0000 (20:51 +0100)
committerIain Buclaw <ibuclaw@gdcproject.org>
Tue, 14 Jan 2025 20:01:33 +0000 (21:01 +0100)
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.

50 files changed:
gcc/d/d-incpath.cc
gcc/d/dmd/MERGE
gcc/d/dmd/clone.d
gcc/d/dmd/ctfeexpr.d
gcc/d/dmd/dcast.d
gcc/d/dmd/dimport.d
gcc/d/dmd/dmodule.d
gcc/d/dmd/doc.d
gcc/d/dmd/dstruct.d
gcc/d/dmd/dsymbolsem.d
gcc/d/dmd/dtemplate.d
gcc/d/dmd/dtoh.d
gcc/d/dmd/errors.d
gcc/d/dmd/expression.d
gcc/d/dmd/expressionsem.d
gcc/d/dmd/file_manager.d
gcc/d/dmd/func.d
gcc/d/dmd/funcsem.d
gcc/d/dmd/globals.d
gcc/d/dmd/globals.h
gcc/d/dmd/hdrgen.d
gcc/d/dmd/json.d
gcc/d/dmd/lexer.d
gcc/d/dmd/mtype.d
gcc/d/dmd/parse.d
gcc/d/dmd/pragmasem.d
gcc/d/dmd/semantic3.d
gcc/d/dmd/templateparamsem.d
gcc/d/dmd/traits.d
gcc/d/dmd/typesem.d
gcc/d/dmd/typinf.d
gcc/testsuite/gdc.test/compilable/copyCtor2.d [new file with mode: 0644]
gcc/testsuite/gdc.test/compilable/cppmangle.d
gcc/testsuite/gdc.test/compilable/testInference.d
gcc/testsuite/gdc.test/fail_compilation/failCopyCtor2.d [deleted file]
gcc/testsuite/gdc.test/fail_compilation/retscope2.d
gcc/testsuite/gdc.test/fail_compilation/retscope3.d
gcc/testsuite/gdc.test/fail_compilation/retscope6.d
gcc/testsuite/gdc.test/fail_compilation/test18282.d
gcc/testsuite/gdc.test/runnable/rvalue1.d
libphobos/libdruntime/MERGE
libphobos/libdruntime/core/builtins.d
libphobos/libdruntime/core/demangle.d
libphobos/libdruntime/core/internal/gc/os.d
libphobos/libdruntime/core/sys/posix/sys/socket.d
libphobos/src/MERGE
libphobos/src/std/functional.d
libphobos/src/std/socket.d
libphobos/src/std/typecons.d
libphobos/testsuite/libphobos.init_fini/custom_gc.d

index 3f62f437cb986cabc033f58250be37ae7c361368..155dc99c5550f932da35f303c12f9ce1c4a6883d 100644 (file)
@@ -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;
index b145d1bd65933b9f8249d2478e3a33ceb15dfb12..33bb398c00d4d3f182794700261866d2316a453b 100644 (file)
@@ -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.
index 1b838603c7e8d3c62d675ff5d87d6ef4abb1ba11..d7658c68ec255e21719c29b9536bf44c2f9d7952 100644 (file)
@@ -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;
 }
index 156c5f8c7e05790a602ab2236a7d6112b27a7610..a6cfe6e9eafe04e7147e29277f44ac91cc11ca82 100644 (file)
@@ -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());
index 7c675eba67c23bdbbabd940b263d7ccadea7978c..0c4b469de5d4854192e4e74ec833484229f1085d 100644 (file)
@@ -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)
index 96e821aea6af2c2f1454c97617e041324d998d12..ec7abb558e52e44eb03eddbaa6755baece2df4e8 100644 (file)
@@ -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());
index 7996d3441934ffe4bf9b106f98a0df84b20e4705..f26c5812ddf9477c269ee5fbbb72b87dcdd7c9e4 100644 (file)
@@ -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
             {
index 21391dc1838877f04d12f718996264e49698164f..eba8dddaf9881d04ce9d92d9b6be05f6341c487e 100644 (file)
@@ -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 ')':
index abeffcb39d2d73977d7b1519acaa49890ad24784..9a9058f61dc8329a537b7360440ed061c56e9e96 100644 (file)
@@ -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
index 1ab646f413826b80fc2be4da4957811cdc537677..0d87f6e26eccdfe801b3aa3dddd2e138fbf1e96b 100644 (file)
@@ -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)
index 5bb70495bb3d5b61daa8dd9e6445211ee59d5305..7f7437cdb1510bb32d4d729ad98580a61e12f5e6 100644 (file)
@@ -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);
 }
 
 
index 296e13c63d51aaeea36bae93fe7a0ab6782e5925..efd0a2f53e20e395987bd1f8c009e36c11da651b 100644 (file)
@@ -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())
             {
index 1babb18bcc6b8477409b376decb0ae3c2cac4de4..7faa536dea6f025766ed95f660f2995306ca0e7f 100644 (file)
@@ -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
index 355bdc42468e60e2ccee5861a9a62b826b08f8fe..2a828d85473fc274feb517d9aae4df1ad499a925 100644 (file)
@@ -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
index 302038701aff537aba7fb894545efe533e6b3840..cd7548ea27cfbca3a2bfe33ea155fd0b82f78f5f 100644 (file)
@@ -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());
index 6ad3d621708d3cea0878997378d37b7d2d8e160c..7f39ec91f0232372387db3eec3284519316e48d0 100644 (file)
@@ -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);
index 40d39aea0ea833cc297f48779493c7812b60ee35..b42ac768b4500ac4c9da88a759c636ea86d22148 100644 (file)
@@ -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);
     }
 
index 39da0256eebc6b752b468c67657198522b395ba8..2bd593ed49b21b5204dc519e51d9ce2836cee983 100644 (file)
@@ -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.
index 77bb4986e7243c1febafb05b567b4fc2956203da..4d3c1b9d19706dba2058a6b683ac8391ae01961a 100644 (file)
@@ -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");
index 669f83e2101f0118d02559ddd9d143a30399c57c..6dd4be4b0a0131444570139e8e5bd6dedc2e04b9 100644 (file)
@@ -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;
index a5e897d62466a754b702ae5d9e5bbfbf7227f0d5..d391bdb581ac57f5a36e28f70afdc1ad1995f6dd 100644 (file)
@@ -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);
 
index b1b5a4f6cb861381ebd4da9f06c4b36934c86e1e..37f8cfdbeac9b09caed040cbd1b377a6dbea06d8 100644 (file)
@@ -906,7 +906,7 @@ public:
         arrayStart();
         foreach (importPath; global.params.imppath[])
         {
-            item(importPath.toDString);
+            item(importPath.path.toDString);
         }
         arrayEnd();
 
index d9f4b1c678f655a040869ad0dc76549dca2f7474..7bf32a9ddb8d920fa6bad07aab113c38737e13ee 100644 (file)
@@ -643,7 +643,7 @@ class Lexer
 
                         if (isidchar(c))
                             continue;
-                        else if (c & 0x80)
+                        if (c & 0x80)
                         {
                             const s = p;
                             const u = decodeUTF();
index 4a4254fcbdd3798988d53634aecb78afa52223d5..b6d44c7f136b28033c04ff79c5b1c80271e1539e 100644 (file)
@@ -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;
index b408f8bffa4fd8341a5756976a5926d94de020bc..415d57824d1431ab6575f4334c01196e83fa8f42 100644 (file)
@@ -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();
index f2f748500a633cef34d2aa469cd2d080535ce801..c5d18ef40a5af863894e7758d6de259a8c04f304 100644 (file)
@@ -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;
 }
 
index 92e00e8992b927998ae89140f2ee28067d965247..3553d3dbbf4692bd3ff30102c25ac67154546df2 100644 (file)
@@ -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)
index f2dc50ebb7021979a1f6bd98314e1bebc36233ef..8a08e71652494cc17b666f71bd447a3907f83508 100644 (file)
@@ -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);
index 34cdf816eb0f801f6f09d70d274c500bed4581d7..42344c68fd0af407188ce60379e7100e614a54df 100644 (file)
@@ -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)
     {
index c631e640815ef80e7722931077d9ddd1d0ad744f..dc3f9da894104a550886f289bab08bbbb7f4ce25 100644 (file)
@@ -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;
 }
index ceff41473e42862335b0e340cf5981141a272283..35d5ad40bebde91f6acc181595c16f119d4d7c38 100644 (file)
@@ -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 (file)
index 0000000..084ef3b
--- /dev/null
@@ -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 {}
+}
index 4b9046e81102728e40485cd9d64b9a04448f235c..c6c921d7b0cb9aa371bc906eb3f13e2a7002db7c 100644 (file)
@@ -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
index bddbaf4294654dbfe7fa1ee3c3b21fd26afacb7e..5091b99896a10ad2f0122d7bf9ff4bc075e25b43 100644 (file)
@@ -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 (file)
index 5e8f8c4..0000000
+++ /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 {}
-}
index 8e10a7caae78e122e8bf0805d8eb900180774b9d..4638cdc139abf8aee4784ced554a480c3ced49c8 100644 (file)
@@ -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
 ---
 */
 
index 59bf11b626831cc00ecf28dc3499cc944b0876ad..819071f15d04b65cd94bdc243bfb7270ba8989cb 100644 (file)
@@ -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
index 49751a4b339b86561b53e12cf761d58f94c1f467..e3b734f03d40ca7ed97d32aa17d6a85d93248d09 100644 (file)
@@ -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
 ---
 */
 
index 97b2b2b13331eaa00de529913a37a0a1a238dfcb..b5db07fd9385e57b515337d5f2a0a6d46b90afb7 100644 (file)
@@ -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
 ---
 */
index f8134f718a9f938441bc1987bf871e53bafa2353..2592f2a9e95e04643ece253d9e9fdab8573e94b1 100644 (file)
@@ -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;
 }
index b145d1bd65933b9f8249d2478e3a33ceb15dfb12..33bb398c00d4d3f182794700261866d2316a453b 100644 (file)
@@ -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.
index bc12759e9a18fd4a07f5d8f29ea12e0d1b3f0a58..4e0c6d4d622ed90edf4f058af533e4759757ba15 100644 (file)
@@ -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))
+    {
+        // ...
+    }
+}
index c9bde27da69e32c24f51cc9cb32b821fb412ae90..e7efc8c3ec9a18ae63afbe7f108cb1ce1be7ff29 100644 (file)
@@ -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 ) ) )
                 {
index bde90e9522800cb6f7a077eaf5b1336a69e8137d..9142708a4a4f01d0bec4357843612795a9a966df 100644 (file)
@@ -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;
     }
index 7c6fab6315a43fa9584bad3ccd7c885a9c9f031a..12824373d586484e279452ef9a819c96ee2d1385 100644 (file)
@@ -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,
index aa35eae57e2ef23be8e5f2eedad1ff5c819ba5ea..fdcc058c9035e7d89ffd647d063d9ca5fee074ef 100644 (file)
@@ -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.
index cf7e3ff8cc2eb92f1501864988f414701d958481..b1b1382280d712aed7124ca79b3d00fd01a133e7 100644 (file)
@@ -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)
         {
index 7fa9974189f66dd8d484e0faae7b838edff7adb8..99ac97ac1e3a0a262626272acbc2fe0caa003632 100644 (file)
@@ -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)
index bd462f53a5b1c8119cfd9f9923bcb5ad27114f51..a841e4720b2cad94153e3798afbb374bae66ebe7 100644 (file)
@@ -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;
             }
         }
index cb72384095944cabd412c7f566e521d30b953513..bcbd84c844f16b3aded9ead6b1a771dba6b3c1ad 100644 (file)
@@ -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);
     }