]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
d: Merge upstream dmd, druntime d115713410, phobos 1b242048c.
authorIain Buclaw <ibuclaw@gdcproject.org>
Sat, 18 Jan 2025 16:35:27 +0000 (17:35 +0100)
committerIain Buclaw <ibuclaw@gdcproject.org>
Sat, 18 Jan 2025 22:42:43 +0000 (23:42 +0100)
D front-end changes:

- Import latest fixes from dmd v2.110.0-rc.1.
- Integers in debug or version statements have been removed from
  the language.

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.

gcc/d/ChangeLog:

* dmd/MERGE: Merge upstream dmd d115713410.

libphobos/ChangeLog:

* libdruntime/MERGE: Merge upstream druntime d115713410.
* src/MERGE: Merge upstream phobos 1b242048c.

gcc/testsuite/ChangeLog:

* gdc.dg/asm3.d: Adjust test.

65 files changed:
gcc/d/dmd/MERGE
gcc/d/dmd/blockexit.d
gcc/d/dmd/dcast.d
gcc/d/dmd/dscope.d
gcc/d/dmd/dversion.d
gcc/d/dmd/escape.d
gcc/d/dmd/expression.d
gcc/d/dmd/expressionsem.d
gcc/d/dmd/func.d
gcc/d/dmd/funcsem.d
gcc/d/dmd/lexer.d
gcc/d/dmd/mtype.d
gcc/d/dmd/nogc.d
gcc/d/dmd/ob.d
gcc/d/dmd/opover.d
gcc/d/dmd/parse.d
gcc/d/dmd/root/filename.d
gcc/d/dmd/safe.d
gcc/d/dmd/semantic3.d
gcc/d/dmd/statementsem.d
gcc/d/dmd/typesem.d
gcc/testsuite/gdc.dg/asm3.d
gcc/testsuite/gdc.test/fail_compilation/attributediagnostic.d
gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_nogc.d
gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_nothrow.d
gcc/testsuite/gdc.test/fail_compilation/attributediagnostic_pure.d
gcc/testsuite/gdc.test/fail_compilation/diag10319.d
gcc/testsuite/gdc.test/fail_compilation/diag11198.d
gcc/testsuite/gdc.test/fail_compilation/diag9620.d
gcc/testsuite/gdc.test/fail_compilation/diag_debug_conditional.d
gcc/testsuite/gdc.test/fail_compilation/fail12932.d
gcc/testsuite/gdc.test/fail_compilation/fail21928.d
gcc/testsuite/gdc.test/fail_compilation/fail21928b.d
gcc/testsuite/gdc.test/fail_compilation/lexer23465.d
gcc/testsuite/gdc.test/fail_compilation/nogc1.d
gcc/testsuite/gdc.test/fail_compilation/nogc2.d
gcc/testsuite/gdc.test/fail_compilation/nogc3.d
gcc/testsuite/gdc.test/fail_compilation/systemvariables_deprecation.d
gcc/testsuite/gdc.test/fail_compilation/test13786.d
gcc/testsuite/gdc.test/fail_compilation/test20655.d
gcc/testsuite/gdc.test/fail_compilation/test23170.d
gcc/testsuite/gdc.test/fail_compilation/testInference.d
gcc/testsuite/gdc.test/runnable/lexer.d
gcc/testsuite/gdc.test/runnable/sdtor.d
libphobos/libdruntime/MERGE
libphobos/libdruntime/core/gc/config.d
libphobos/libdruntime/core/int128.d
libphobos/libdruntime/core/internal/array/construction.d
libphobos/libdruntime/core/internal/array/utils.d
libphobos/libdruntime/core/internal/gc/blockmeta.d
libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
libphobos/libdruntime/core/lifetime.d
libphobos/libdruntime/core/memory.d
libphobos/libdruntime/core/runtime.d
libphobos/libdruntime/core/sync/condition.d
libphobos/libdruntime/core/sync/semaphore.d
libphobos/libdruntime/core/sys/linux/perf_event.d
libphobos/libdruntime/core/thread/osthread.d
libphobos/libdruntime/core/time.d
libphobos/libdruntime/rt/dmain2.d
libphobos/libdruntime/rt/lifetime.d
libphobos/src/MERGE
libphobos/src/std/algorithm/mutation.d
libphobos/src/std/stdio.d
libphobos/src/std/typecons.d

index 33bb398c00d4d3f182794700261866d2316a453b..4172630afa08de5c8fbb63f151f71260248bec10 100644 (file)
@@ -1,4 +1,4 @@
-d6f693b46a1565172cac7a1438905141783a164f
+d1157134103a209d36d6ee9c1df1d61d5929ec6d
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
index dc3e379e8d4be878b7c76ef73d5e1fc1a651d01d..2125fb9386aa8bf4785e1ba892b121c48009a4c7 100644 (file)
@@ -478,7 +478,7 @@ int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink)
             if (!(s.stc & STC.nothrow_))
             {
                 if(func)
-                    func.setThrow(s.loc, "`asm` statement is assumed to throw - mark it with `nothrow` if it does not");
+                    func.setThrow(s.loc, "executing an `asm` statement without a `nothrow` annotation");
                 if (eSink)
                     eSink.error(s.loc, "`asm` statement is assumed to throw - mark it with `nothrow` if it does not"); // TODO
                 else
@@ -523,7 +523,7 @@ BE checkThrow(ref const Loc loc, Expression exp, FuncDeclaration func, ErrorSink
     if (eSink)
         eSink.error(loc, "`%s` is thrown but not caught", exp.type.toChars());
     else if (func)
-        func.setThrow(loc, "`%s` is thrown but not caught", exp.type);
+        func.setThrow(loc, "`%s` being thrown but not caught", exp.type);
 
     return BE.throw_;
 }
index 0c4b469de5d4854192e4e74ec833484229f1085d..2f33301f0c27687ee7c260974f9d337c5c89a9c0 100644 (file)
@@ -2922,7 +2922,10 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
         {
             printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n", e.toChars(), e.type.toChars(), t.toChars());
         }
-        static immutable msg = "cannot form delegate due to covariant return type";
+        void errorCovariantReturnType()
+        {
+            error(e.loc, "cannot form delegate due to covariant return type");
+        }
 
         Type tb = t.toBasetype();
         Type typeb = e.type.toBasetype();
@@ -2932,7 +2935,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
             int offset;
             e.func.tookAddressOf++;
             if (e.func.tintro && e.func.tintro.nextOf().isBaseOf(e.func.type.nextOf(), &offset) && offset)
-                error(e.loc, "%s", msg.ptr);
+                errorCovariantReturnType();
             auto result = e.copy();
             result.type = t;
             return result;
@@ -2947,7 +2950,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
                 {
                     int offset;
                     if (f.tintro && f.tintro.nextOf().isBaseOf(f.type.nextOf(), &offset) && offset)
-                        error(e.loc, "%s", msg.ptr);
+                        errorCovariantReturnType();
                     if (f != e.func)    // if address not already marked as taken
                         f.tookAddressOf++;
                     auto result = new DelegateExp(e.loc, e.e1, f, false, e.vthis2);
@@ -2955,7 +2958,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
                     return result;
                 }
                 if (e.func.tintro)
-                    error(e.loc, "%s", msg.ptr);
+                    errorCovariantReturnType();
             }
         }
 
index 8648231b4a832673e5b28badc4ce19d8b4bbdd54..a683d9c3c0fb1a959d57198d11c091a549acc118 100644 (file)
@@ -88,6 +88,7 @@ private struct Previews
         bool dip1008;
         bool dip1021;
         bool dip25;
+        bool fieldwise;
         bool fixAliasThis;
         bool fixImmutableConv;
         bool in_;
@@ -116,6 +117,7 @@ private struct Previews
         this.rvalueRefParam = params.rvalueRefParam == FeatureState.enabled;
         this.safer = params.safer == FeatureState.enabled;
         this.systemVariables = params.systemVariables;
+        this.fieldwise = params.fieldwise == FeatureState.enabled;
     }
 }
 
index 36e9cf80189dce0acd9aa4df56337baa7fc97be2..42d7d8f451888f4356173bb202134ce621f23cec 100644 (file)
@@ -59,12 +59,9 @@ extern (C++) final class DebugSymbol : Dsymbol
     {
         if (ident)
             return ident.toChars();
-        else
-        {
-            OutBuffer buf;
-            buf.print(level);
-            return buf.extractChars();
-        }
+        OutBuffer buf;
+        buf.print(level);
+        return buf.extractChars();
     }
 
     override const(char)* kind() const nothrow
@@ -116,12 +113,9 @@ extern (C++) final class VersionSymbol : Dsymbol
     {
         if (ident)
             return ident.toChars();
-        else
-        {
-            OutBuffer buf;
-            buf.print(level);
-            return buf.extractChars();
-        }
+        OutBuffer buf;
+        buf.print(level);
+        return buf.extractChars();
     }
 
     override const(char)* kind() const nothrow
index 947abf0c4bcb14c6313f13a3e3682c1cb11ea28e..ecf4f919f28f9ef22ade098d62194e1fc97b3195 100644 (file)
@@ -2191,9 +2191,9 @@ private EnclosedBy enclosesLifetimeOf(VarDeclaration va, VarDeclaration v)
 // `setUnsafePreview` partially evaluated for dip1000
 public
 bool setUnsafeDIP1000(ref Scope sc, bool gag, Loc loc, const(char)* msg,
-    RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
+    RootObject[] args...)
 {
-    return setUnsafePreview(&sc, sc.useDIP1000, gag, loc, msg, arg0, arg1, arg2);
+    return setUnsafePreview(&sc, sc.useDIP1000, gag, loc, msg, args);
 }
 
 /***************************************
index 2a828d85473fc274feb517d9aae4df1ad499a925..75d64682aea5455db2e244183ae1b31d4aae68d2 100644 (file)
@@ -1074,7 +1074,7 @@ extern (C++) final class ErrorExp : Expression
               * and we need to set the error count to prevent bogus code
               * generation. At least give a message.
               */
-            .error(Loc.initial, "unknown, please file report on issues.dlang.org");
+            .error(Loc.initial, "unknown, please file report at https://github.com/dlang/dmd/issues/new");
         }
 
         return errorexp;
index cd7548ea27cfbca3a2bfe33ea155fd0b82f78f5f..eb4a5f884f64f88c65aaa5468fca820829a689dc 100644 (file)
@@ -2073,7 +2073,7 @@ public void errorSupplementalInferredAttr(FuncDeclaration fd, int maxDepth, bool
     auto errorFunc = deprecation ? &eSink.deprecationSupplemental : &eSink.errorSupplemental;
 
     AttributeViolation* s;
-    const(char)* attr;
+    string attr;
     if (stc & STC.safe)
     {
         s = fd.safetyViolation;
@@ -2098,21 +2098,9 @@ public void errorSupplementalInferredAttr(FuncDeclaration fd, int maxDepth, bool
     if (!s)
         return;
 
-    if (s.format)
+    if (s.action.length > 0)
     {
-        errorFunc(s.loc, deprecation ?
-            "which wouldn't be `%s` because of:" :
-            "which wasn't inferred `%s` because of:", attr);
-        if (stc == STC.nogc || stc == STC.pure_)
-        {
-            auto f = (cast(Dsymbol) s.arg0).isFuncDeclaration();
-            errorFunc(s.loc, s.format, f.kind(), f.toPrettyChars(), s.arg1 ? s.arg1.toChars() : "");
-        }
-        else
-        {
-            errorFunc(s.loc, s.format,
-                s.arg0 ? s.arg0.toChars() : "", s.arg1 ? s.arg1.toChars() : "", s.arg2 ? s.arg2.toChars() : "");
-        }
+        errorFunc(s.loc, "and %.*s makes it fail to infer `%.*s`", s.action.fTuple.expand, attr.fTuple.expand);
     }
     else if (s.fd)
     {
@@ -2176,7 +2164,7 @@ private bool checkPurity(VarDeclaration v, const ref Loc loc, Scope* sc)
         if (v.ident == Id.gate)
             return false;
 
-        if (checkImpure(sc, loc, "`pure` %s `%s` cannot access mutable static data `%s`", v))
+        if (checkImpure(sc, loc, "accessing mutable static data `%s`", v))
         {
             error(loc, "`pure` %s `%s` cannot access mutable static data `%s`",
                 sc.func.kind(), sc.func.toPrettyChars(), v.toChars());
@@ -6710,20 +6698,20 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
             else if (sc.func && sc.intypeof != 1 && !(sc.ctfe || sc.debug_))
             {
                 bool err = false;
-                if (!tf.purity && sc.func.setImpure(exp.loc, "`pure` %s `%s` cannot call impure `%s`", exp.e1))
+                if (!tf.purity && sc.func.setImpure(exp.loc, "calling impure `%s`", exp.e1))
                 {
                     error(exp.loc, "`pure` %s `%s` cannot call impure %s `%s`",
                         sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
                     err = true;
                 }
-                if (!tf.isNogc && sc.func.setGC(exp.loc, "`@nogc` %s `%s` cannot call non-@nogc `%s`", exp.e1))
+                if (!tf.isNogc && sc.func.setGC(exp.loc, "calling non-@nogc `%s`", exp.e1))
                 {
                     error(exp.loc, "`@nogc` %s `%s` cannot call non-@nogc %s `%s`",
                         sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
                     err = true;
                 }
                 if (tf.trust <= TRUST.system && sc.setUnsafe(true, exp.loc,
-                    "`@safe` function `%s` cannot call `@system` `%s`", sc.func, exp.e1))
+                    "calling `@system` `%s`", exp.e1))
                 {
                     error(exp.loc, "`@safe` %s `%s` cannot call `@system` %s `%s`",
                         sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
index b42ac768b4500ac4c9da88a759c636ea86d22148..993bce85ee6c49b4b7b71faf5b76e895fc0466c7 100644 (file)
@@ -691,14 +691,13 @@ extern (C++) class FuncDeclaration : Declaration
      * Params:
      *     loc = location of action
      *     format = format string for error message
-     *     arg0 = (optional) argument to format string
+     *     args = arguments to format string
      */
-    extern (D) final void setThrow(Loc loc, const(char)* format, RootObject arg0 = null)
+    extern (D) final void setThrow(Loc loc, const(char)* format, RootObject[] args...)
     {
         if (nothrowInprocess && !nothrowViolation)
         {
-            assert(format);
-            nothrowViolation = new AttributeViolation(loc, format, arg0); // action that requires GC
+            nothrowViolation = new AttributeViolation(loc, format, args); // action that requires GC
         }
     }
 
@@ -1873,11 +1872,10 @@ extern (C++) final class NewDeclaration : FuncDeclaration
 /// Stores a reason why a function failed to infer a function attribute like `@safe` or `pure`
 ///
 /// Has two modes:
-/// - a regular safety error, stored in (fmtStr, arg0, arg1)
+/// - a regular safety error, stored in `action`
 /// - a call to a function without the attribute, which is a special case, because in that case,
 ///   that function might recursively also have a `AttributeViolation`. This way, in case
 ///   of a big call stack, the error can go down all the way to the root cause.
-///   The `FunctionDeclaration` is then stored in `arg0` and `fmtStr` must be `null`.
 struct AttributeViolation
 {
     Loc loc;               /// location of error
@@ -1886,20 +1884,21 @@ struct AttributeViolation
 
     // -- OR --
 
-    const(char)* format;   /// printf-style format string
-    RootObject arg0;       /// Arguments for up to two `%s` format specifiers in format string
-    RootObject arg1;       /// ditto
-    RootObject arg2;       /// ditto
+    string action;   /// Action that made the attribute fail to get inferred
 
     this(ref Loc loc, FuncDeclaration fd) { this.loc = loc; this.fd = fd; }
 
-    this(ref Loc loc, const(char)* format, RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
+    this(ref Loc loc, const(char)* fmt, RootObject[] args)
     {
-        assert(format);
         this.loc = loc;
-        this.format = format;
-        this.arg0 = arg0;
-        this.arg1 = arg1;
-        this.arg2 = arg2;
+        assert(args.length <= 4); // expand if necessary
+        OutBuffer buf;
+        buf.printf(fmt,
+            args.length > 0 && args[0] ? args[0].toChars() : "",
+            args.length > 1 && args[1] ? args[1].toChars() : "",
+            args.length > 2 && args[2] ? args[2].toChars() : "",
+            args.length > 3 && args[3] ? args[3].toChars() : "",
+        );
+        this.action = buf.extractSlice();
     }
 }
index 2bd593ed49b21b5204dc519e51d9ce2836cee983..9f2ff1e1afd1df59b020615301a8cff1f38992f9 100644 (file)
@@ -3032,21 +3032,21 @@ extern (D) bool checkNRVO(FuncDeclaration fd)
  * Params:
  *     fd = function declaration to mark
  *     loc = location of impure action
- *     fmt = format string for error message. Must include "%s `%s`" for the function kind and name.
- *     arg0 = (optional) argument to format string
+ *     fmt = format string for error message
+ *     args = argument to format string
  *
  * Returns: `true` if there's a purity error
  */
-extern (D) bool setImpure(FuncDeclaration fd, Loc loc = Loc.init, const(char)* fmt = null, RootObject arg0 = null)
+extern (D) bool setImpure(FuncDeclaration fd, Loc loc, const(char)* fmt, RootObject[] args...)
 {
     if (fd.purityInprocess)
     {
         fd.purityInprocess = false;
         if (fmt)
-            fd.pureViolation = new AttributeViolation(loc, fmt, fd, arg0); // impure action
-        else if (arg0)
+            fd.pureViolation = new AttributeViolation(loc, fmt, args); // impure action
+        else if (args.length > 0)
         {
-            if (auto sa = arg0.isDsymbol())
+            if (auto sa = args[0].isDsymbol())
             {
                 if (FuncDeclaration fd2 = sa.isFuncDeclaration())
                 {
@@ -3056,7 +3056,7 @@ extern (D) bool setImpure(FuncDeclaration fd, Loc loc = Loc.init, const(char)* f
         }
 
         if (fd.fes)
-            fd.fes.func.setImpure(loc, fmt, arg0);
+            fd.fes.func.setImpure(loc, fmt, args);
     }
     else if (fd.isPure())
         return true;
@@ -3070,7 +3070,7 @@ PURE isPure(FuncDeclaration fd)
 
     TypeFunction tf = fd.type.toTypeFunction();
     if (fd.purityInprocess)
-        fd.setImpure();
+        fd.setImpure(Loc.initial, null);
     if (tf.purity == PURE.fwdref)
         tf.purityLevel();
     PURE purity = tf.purity;
index 7bf32a9ddb8d920fa6bad07aab113c38737e13ee..406829d8257e1537c97a1216284f0d23335cd2c0 100644 (file)
@@ -2571,19 +2571,19 @@ class Lexer
     Ldone:
         if (errorDigit)
         {
-            error(token.loc, "%s digit expected, not `%c`", base == 2 ? "binary".ptr :
+            error(scanloc, "%s digit expected, not `%c`", base == 2 ? "binary".ptr :
                                                  base == 8 ? "octal".ptr :
                                                  "decimal".ptr, errorDigit);
             err = true;
         }
         if (overflow && !err)
         {
-            error("integer overflow");
+            error(scanloc, "integer overflow");
             err = true;
         }
         if ((base == 2 && !anyBinaryDigitsNoSingleUS) ||
             (base == 16 && !anyHexDigitsNoSingleUS))
-            error(token.loc, "`%.*s` isn't a valid integer literal, use `%.*s0` instead", cast(int)(p - start), start, 2, start);
+            error(scanloc, "`%.*s` isn't a valid integer literal, use `%.*s0` instead", cast(int)(p - start), start, 2, start);
 
         t.unsvalue = n;
 
@@ -2612,7 +2612,7 @@ class Lexer
                 goto L1;
             case 'l':
                 f = FLAGS.long_;
-                error("lower case integer suffix 'l' is not allowed. Please use 'L' instead");
+                error(scanloc, "lower case integer suffix 'l' is not allowed. Please use 'L' instead");
                 goto L1;
             case 'L':
                 f = FLAGS.long_;
@@ -2620,7 +2620,7 @@ class Lexer
                 p++;
                 if ((flags & f) && !err)
                 {
-                    error("repeated integer suffix `%c`", p[-1]);
+                    error(scanloc, "repeated integer suffix `%c`", p[-1]);
                     err = true;
                 }
                 flags = cast(FLAGS)(flags | f);
@@ -2634,9 +2634,9 @@ class Lexer
         {
             if (err)
                 // can't translate invalid octal value, just show a generic message
-                error("octal literals larger than 7 are no longer supported");
+                error(scanloc, "octal literals larger than 7 are no longer supported");
             else
-                error(token.loc, "octal literals `0%llo%.*s` are no longer supported, use `std.conv.octal!\"%llo%.*s\"` instead",
+                error(scanloc, "octal literals `0%llo%.*s` are no longer supported, use `std.conv.octal!\"%llo%.*s\"` instead",
                     n, cast(int)(p - psuffix), psuffix, n, cast(int)(p - psuffix), psuffix);
         }
         TOK result;
index b6d44c7f136b28033c04ff79c5b1c80271e1539e..f91687b7f39f139b90e6390a74b7cf508b741c25 100644 (file)
@@ -529,12 +529,9 @@ extern (C++) abstract class Type : ASTNode
             auto sv = t.stringtable.update(buf[]);
             if (sv.value)
                 return sv.value;
-            else
-            {
-                t.deco = cast(char*)sv.toDchars();
-                sv.value = t;
-                return t;
-            }
+            t.deco = cast(char*)sv.toDchars();
+            sv.value = t;
+            return t;
         }
 
         for (size_t i = 0; basetab[i] != Terror; i++)
index ff1e173af476bf9971378f631d0e207c9f9e52a5..d9a742f7022a284a85e7bbba1db5704f428b2579 100644 (file)
@@ -18,6 +18,7 @@ import core.stdc.stdio;
 import dmd.aggregate;
 import dmd.astenums;
 import dmd.declaration;
+import dmd.common.outbuffer;
 import dmd.dmodule;
 import dmd.dscope;
 import dmd.dtemplate : isDsymbol;
@@ -80,20 +81,19 @@ public:
      * Register that expression `e` requires the GC
      * Params:
      *   e = expression that uses GC
-     *   format = error message when `e` is used in a `@nogc` function.
-     *            Must contain format strings "`@nogc` %s `%s`" referring to the function.
+     *   msg = error message when `e` is used in a `@nogc` function.
      * Returns: `true` if `err` was set, `false` if it's not in a `@nogc` and not checkonly (-betterC)
      */
-    private bool setGC(Expression e, const(char)* format)
+    private bool setGC(Expression e, const(char)* msg)
     {
         if (checkOnly)
         {
             err = true;
             return true;
         }
-        if (f.setGC(e.loc, format))
+        if (f.setGC(e.loc, msg))
         {
-            error(e.loc, format, f.kind(), f.toPrettyChars());
+            error(e.loc, "%s causes a GC allocation in `@nogc` %s `%s`", msg, f.kind(), f.toChars());
             err = true;
             return true;
         }
@@ -111,7 +111,7 @@ public:
         auto fd = stripHookTraceImpl(e.f);
         if (fd.ident == Id._d_arraysetlengthT)
         {
-            if (setGC(e, "setting `length` in `@nogc` %s `%s` may cause a GC allocation"))
+            if (setGC(e, "setting this array's `length`"))
                 return;
             f.printGCUsage(e.loc, "setting `length` may cause a GC allocation");
         }
@@ -121,7 +121,7 @@ public:
     {
         if (e.type.ty != Tarray || !e.elements || !e.elements.length || e.onstack)
             return;
-        if (setGC(e, "array literal in `@nogc` %s `%s` may cause a GC allocation"))
+        if (setGC(e, "this array literal"))
             return;
         f.printGCUsage(e.loc, "array literal may cause a GC allocation");
     }
@@ -130,7 +130,7 @@ public:
     {
         if (!e.keys.length)
             return;
-        if (setGC(e, "associative array literal in `@nogc` %s `%s` may cause a GC allocation"))
+        if (setGC(e, "this associative array literal"))
             return;
         f.printGCUsage(e.loc, "associative array literal may cause a GC allocation");
     }
@@ -147,7 +147,7 @@ public:
         if (nogcExceptions && e.thrownew)
             return;                     // separate allocator is called for this, not the GC
 
-        if (setGC(e, "cannot use `new` in `@nogc` %s `%s`"))
+        if (setGC(e, "allocating with `new`"))
             return;
         f.printGCUsage(e.loc, "`new` causes a GC allocation");
     }
@@ -170,7 +170,7 @@ public:
         Type t1b = e.e1.type.toBasetype();
         if (e.modifiable && t1b.ty == Taarray)
         {
-            if (setGC(e, "assigning an associative array element in `@nogc` %s `%s` may cause a GC allocation"))
+            if (setGC(e, "assigning this associative array element"))
                 return;
             f.printGCUsage(e.loc, "assigning an associative array element may cause a GC allocation");
         }
@@ -180,7 +180,7 @@ public:
     {
         if (e.e1.op == EXP.arrayLength)
         {
-            if (setGC(e, "setting `length` in `@nogc` %s `%s` may cause a GC allocation"))
+            if (setGC(e, "setting this array's `length`"))
                 return;
             f.printGCUsage(e.loc, "setting `length` may cause a GC allocation");
         }
@@ -193,14 +193,14 @@ public:
             err = true;
             return;
         }
-        if (setGC(e, "cannot use operator `~=` in `@nogc` %s `%s`"))
+        if (setGC(e, "appending to this array with operator `~=`"))
             return;
         f.printGCUsage(e.loc, "operator `~=` may cause a GC allocation");
     }
 
     override void visit(CatExp e)
     {
-        if (setGC(e, "cannot use operator `~` in `@nogc` %s `%s`"))
+        if (setGC(e, "concatenating with operator `~`"))
             return;
         f.printGCUsage(e.loc, "operator `~` may cause a GC allocation");
     }
@@ -284,12 +284,12 @@ private FuncDeclaration stripHookTraceImpl(FuncDeclaration fd)
  *     fd = function
  *     loc = location of GC action
  *     fmt = format string for error message. Must include "%s `%s`" for the function kind and name.
- *     arg0 = (optional) argument to format string
+ *     args = arguments to format string
  *
  * Returns:
  *      true if function is marked as @nogc, meaning a user error occurred
  */
-extern (D) bool setGC(FuncDeclaration fd, Loc loc, const(char)* fmt, RootObject arg0 = null)
+extern (D) bool setGC(FuncDeclaration fd, Loc loc, const(char)* fmt, RootObject[] args...)
 {
     //printf("setGC() %s\n", toChars());
     if (fd.nogcInprocess && fd.semanticRun < PASS.semantic3 && fd._scope)
@@ -302,10 +302,10 @@ extern (D) bool setGC(FuncDeclaration fd, Loc loc, const(char)* fmt, RootObject
     {
         fd.nogcInprocess = false;
         if (fmt)
-            fd.nogcViolation = new AttributeViolation(loc, fmt, fd, arg0); // action that requires GC
-        else if (arg0)
+            fd.nogcViolation = new AttributeViolation(loc, fmt, args); // action that requires GC
+        else if (args.length > 0)
         {
-            if (auto sa = arg0.isDsymbol())
+            if (auto sa = args[0].isDsymbol())
             {
                 if (FuncDeclaration fd2 = sa.isFuncDeclaration())
                 {
index 2019e82cd7bdd01afc48f03b08ae02b20271b099..ab480190a5d5a2ff1adf3ebd607072f12641de77 100644 (file)
@@ -379,7 +379,7 @@ void toObNodes(ref ObNodes obnodes, Statement s)
             return ob;
         }
 
-        // block_goto(blx, BCgoto, null)
+        // block_goto(blx, BC.goto_, null)
         ObNode* gotoNextNode()
         {
             return gotoNextNodeIs(newNode());
index c126b1d28c4a8dbc679b9f5fab2b53bf1ff4f417..56b36010be59967acb26d37bfb2921be7136e2cf 100644 (file)
@@ -1009,7 +1009,7 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
                 return null;
 
             import dmd.clone : needOpEquals;
-            if (global.params.fieldwise != FeatureState.enabled && !needOpEquals(sd))
+            if (!sc.previews.fieldwise && !needOpEquals(sd))
             {
                 // Use bitwise equality.
                 auto op2 = e.op == EXP.equal ? EXP.identity : EXP.notIdentity;
index 415d57824d1431ab6575f4334c01196e83fa8f42..b851b9aafe7e673813601e4115c26aa08cb93bfb 100644 (file)
@@ -2257,17 +2257,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
         nextToken();
         if (token.value == TOK.identifier)
             s = new AST.DebugSymbol(token.loc, token.ident);
-        else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)
-        {
-            // @@@DEPRECATED_2.111@@@
-            // Deprecated in 2.101, remove in 2.111
-            deprecation("`debug = <integer>` is deprecated, use debug identifiers instead");
-
-            s = new AST.DebugSymbol(token.loc, cast(uint)token.unsvalue);
-        }
         else
         {
-            error("identifier or integer expected, not `%s`", token.toChars());
+            error("identifier expected, not `%s`", token.toChars());
             s = null;
         }
         nextToken();
@@ -2292,16 +2284,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
 
             if (token.value == TOK.identifier)
                 id = token.ident;
-            else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)
-            {
-                // @@@DEPRECATED_2.111@@@
-                // Deprecated in 2.101, remove in 2.111
-                deprecation("`debug( <integer> )` is deprecated, use debug identifiers instead");
-
-                level = cast(uint)token.unsvalue;
-            }
             else
-                error("identifier or integer expected inside `debug(...)`, not `%s`", token.toChars());
+                error("identifier expected inside `debug(...)`, not `%s`", token.toChars());
             loc = token.loc;
             nextToken();
             check(TOK.rightParenthesis);
@@ -2318,16 +2302,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
         nextToken();
         if (token.value == TOK.identifier)
             s = new AST.VersionSymbol(token.loc, token.ident);
-        else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)
-        {
-            // @@@DEPRECATED_2.111@@@
-            // Deprecated in 2.101, remove in 2.111
-            deprecation("`version = <integer>` is deprecated, use version identifiers instead");
-            s = new AST.VersionSymbol(token.loc, cast(uint)token.unsvalue);
-        }
         else
         {
-            error("identifier or integer expected, not `%s`", token.toChars());
+            error("identifier expected, not `%s`", token.toChars());
             s = null;
         }
         nextToken();
@@ -2357,20 +2334,12 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
             loc = token.loc;
             if (token.value == TOK.identifier)
                 id = token.ident;
-            else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)
-            {
-                // @@@DEPRECATED_2.111@@@
-                // Deprecated in 2.101, remove in 2.111
-                deprecation("`version( <integer> )` is deprecated, use version identifiers instead");
-
-                level = cast(uint)token.unsvalue;
-            }
             else if (token.value == TOK.unittest_)
                 id = Identifier.idPool(Token.toString(TOK.unittest_));
             else if (token.value == TOK.assert_)
                 id = Identifier.idPool(Token.toString(TOK.assert_));
             else
-                error("identifier or integer expected inside `version(...)`, not `%s`", token.toChars());
+                error("identifier expected inside `version(...)`, not `%s`", token.toChars());
             nextToken();
             check(TOK.rightParenthesis);
         }
index cf00d8ad7f63257dbb8e1a0e973291d3f369e401..bd1233d2acb50e5dd638272f08fa68e1b397306c 100644 (file)
@@ -877,10 +877,9 @@ nothrow:
                 const dw = GetFileAttributesW(&wname[0]);
                 if (dw == -1)
                     return 0;
-                else if (dw & FILE_ATTRIBUTE_DIRECTORY)
+                if (dw & FILE_ATTRIBUTE_DIRECTORY)
                     return 2;
-                else
-                    return 1;
+                return 1;
             });
         }
         else
index f6427a33fc12c87ac5aeb382914c575a5c42dcdb..bb9cbe9f1676e8f0fd7099f6b73aa0ba9f0d9982 100644 (file)
@@ -34,6 +34,7 @@ import dmd.identifier;
 import dmd.location;
 import dmd.mtype;
 import dmd.rootobject;
+import dmd.root.string : fTuple;
 import dmd.target;
 import dmd.tokens;
 import dmd.typesem : hasPointers, arrayOf, size;
@@ -315,8 +316,7 @@ bool checkUnsafeDotExp(Scope* sc, Expression e, Identifier id, int flag)
     {
         if (id == Id.ptr)
             return sc.setUnsafe(false, e.loc, "using `%s.ptr` (instead of `&%s[0])`", e, e);
-        else
-            return sc.setUnsafe(false, e.loc, "using `%s.%s`", e, id);
+        return sc.setUnsafe(false, e.loc, "using `%s.%s`", e, id);
     }
     return false;
 }
@@ -359,20 +359,20 @@ bool isTrusted(FuncDeclaration fd)
  *   gag   = suppress error message (used in escape.d)
  *   loc   = location of error
  *   format = printf-style format string
- *   arg0  = (optional) argument for first %s format specifier
- *   arg1  = (optional) argument for second %s format specifier
- *   arg2  = (optional) argument for third %s format specifier
+ *   args  = arguments for %s format specifier
  */
 extern (D) void reportSafeError(FuncDeclaration fd, bool gag, Loc loc,
-    const(char)* format = null, RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
+    const(char)* format, RootObject[] args...)
 {
     if (fd.type.toTypeFunction().trust == TRUST.system) // function was just inferred to be @system
     {
         if (format)
-            fd.safetyViolation = new AttributeViolation(loc, format, arg0, arg1, arg2);
-        else if (arg0)
         {
-            if (FuncDeclaration fd2 = (cast(Dsymbol) arg0).isFuncDeclaration())
+            fd.safetyViolation = new AttributeViolation(loc, format, args);
+        }
+        else if (args.length > 0)
+        {
+            if (FuncDeclaration fd2 = (cast(Dsymbol) args[0]).isFuncDeclaration())
             {
                 fd.safetyViolation = new AttributeViolation(loc, fd2); // call to non-@nogc function
             }
@@ -383,12 +383,17 @@ extern (D) void reportSafeError(FuncDeclaration fd, bool gag, Loc loc,
         if (!gag && format)
         {
             OutBuffer buf;
-            buf.printf(format, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
+            buf.writestring(AttributeViolation(loc, format, args).action);
             if (fd.isSafe())
                 buf.writestring(" is not allowed in a `@safe` function");
             else
-                buf.writestring(" is not allowed in a function with default safety with `-preview=safer`");
-            .error(loc, buf.extractChars());
+            {
+                version (IN_GCC)
+                    buf.writestring(" is not allowed in a function with default safety with `-fpreview=safer`");
+                else
+                    buf.writestring(" is not allowed in a function with default safety with `-preview=safer`");
+            }
+            .error(loc, "%s", buf.extractChars());
         }
     }
 }
@@ -447,14 +452,10 @@ extern (D) bool setUnsafeCall(FuncDeclaration fd, FuncDeclaration f)
  *   gag = surpress error message (used in escape.d)
  *   loc = location of error
  *   format = printf-style format string
- *   arg0  = (optional) argument for first %s format specifier
- *   arg1  = (optional) argument for second %s format specifier
- *   arg2  = (optional) argument for third %s format specifier
+ *   args  = arguments for format string
  * Returns: whether there is a safe error
  */
-bool setUnsafe(Scope* sc,
-    bool gag = false, Loc loc = Loc.init, const(char)* format = null,
-    RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
+bool setUnsafe(Scope* sc, bool gag, Loc loc, const(char)* format, RootObject[] args...)
 {
     if (sc.intypeof)
         return false; // typeof(cast(int*)0) is safe
@@ -468,11 +469,8 @@ bool setUnsafe(Scope* sc,
         {
             if (sc.varDecl.storage_class & STC.safe)
             {
-                OutBuffer buf;
-                buf.printf(format, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
-                buf.printf(" can't initialize `@safe` variable `%s`", sc.varDecl.toChars());
-                .error(loc, buf.extractChars());
-
+                string action = AttributeViolation(loc, format, args).action;
+                .error(loc, "%.*s can't initialize `@safe` variable `%s`", action.fTuple.expand, sc.varDecl.toChars());
                 return true;
             }
             else if (!(sc.varDecl.storage_class & STC.trusted))
@@ -491,10 +489,8 @@ bool setUnsafe(Scope* sc,
         {
             // Message wil be gagged, but still call error() to update global.errors and for
             // -verrors=spec
-            OutBuffer buf;
-            buf.printf(format, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
-            buf.writestring(" is not allowed in a `@safe` function");
-            .error(loc, buf.extractChars());
+            string action = AttributeViolation(loc, format, args).action;
+            .error(loc, "%.*s is not allowed in a `@safe` function", action.fTuple.expand);
             return true;
         }
         return false;
@@ -502,9 +498,9 @@ bool setUnsafe(Scope* sc,
 
     if (setFunctionToUnsafe(sc.func))
     {
-        if (format || arg0)
+        if (format || args.length > 0)
         {
-            reportSafeError(sc.func, gag, loc, format, arg0, arg1, arg2);
+            reportSafeError(sc.func, gag, loc, format, args);
         }
         return sc.func.isSafe(); // it is only an error if in an @safe function
     }
@@ -527,13 +523,10 @@ bool setUnsafe(Scope* sc,
  *   gag = surpress error message
  *   loc = location of error
  *   format = printf-style format string
- *   arg0  = (optional) argument for first %s format specifier
- *   arg1  = (optional) argument for second %s format specifier
- *   arg2  = (optional) argument for third %s format specifier
+ *   args  = arguments for format string
  * Returns: whether an actual safe error (not deprecation) occured
  */
-bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)* format,
-    RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
+bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)* format, RootObject[] args...)
 {
     //printf("setUnsafePreview() fs:%d %s\n", fs, fmt);
     assert(format);
@@ -543,7 +536,7 @@ bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)
         return false;
 
       case enabled:
-        return sc.setUnsafe(gag, loc, format, arg0, arg1, arg2);
+        return sc.setUnsafe(gag, loc, format, args);
 
       case default_:
         if (!sc.func)
@@ -552,16 +545,14 @@ bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)
         {
             if (!gag && !sc.isDeprecated())
             {
-                OutBuffer buf;
-                buf.printf(format, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
-                buf.writestring(" will become `@system` in a future release");
-                deprecation(loc, buf.extractChars());
+                string action = AttributeViolation(loc, format, args).action;
+                deprecation(loc, "%.*s will become `@system` in a future release", action.fTuple.expand);
             }
         }
         else if (!sc.func.safetyViolation)
         {
             import dmd.func : AttributeViolation;
-            sc.func.safetyViolation = new AttributeViolation(loc, format, arg0, arg1, arg2);
+            sc.func.safetyViolation = new AttributeViolation(loc, format, args);
         }
         return false;
     }
index 3553d3dbbf4692bd3ff30102c25ac67154546df2..def7d46d3e499c78dddd060f5f18c32bfab97638 100644 (file)
@@ -1699,7 +1699,7 @@ extern (D) bool checkClosure(FuncDeclaration fd)
     if (!fd.needsClosure())
         return false;
 
-    if (fd.setGC(fd.loc, "%s `%s` is `@nogc` yet allocates closure for `%s()` with the GC", fd))
+    if (fd.setGC(fd.loc, "allocating a closure for `%s()`", fd))
     {
         .error(fd.loc, "%s `%s` is `@nogc` yet allocates closure for `%s()` with the GC", fd.kind, fd.toPrettyChars(), fd.toChars());
         if (global.gag)     // need not report supplemental errors
index 932830d533f066ab62b2437438f11175b23102e9..6bbc1a9b28eb2ed98be2ae8ce28339f3b330346c 100644 (file)
@@ -3623,9 +3623,9 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
         }
 
         assert(sc.func);
-        if (!(cas.stc & STC.pure_) && sc.func.setImpure(cas.loc, "`asm` statement is assumed to be impure - mark it with `pure` if it is not"))
+        if (!(cas.stc & STC.pure_) && sc.func.setImpure(cas.loc, "executing an `asm` statement without `pure` annotation"))
             error(cas.loc, "`asm` statement is assumed to be impure - mark it with `pure` if it is not");
-        if (!(cas.stc & STC.nogc) && sc.func.setGC(cas.loc, "`asm` statement in %s `%s` is assumed to use the GC - mark it with `@nogc` if it does not"))
+        if (!(cas.stc & STC.nogc) && sc.func.setGC(cas.loc, "executing an `asm` statement without `@nogc` annotation"))
             error(cas.loc, "`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not");
         // @@@DEPRECATED_2.114@@@
         // change deprecation() to error(), add `else` and remove `| STC.safe`
@@ -3634,7 +3634,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
             deprecation(cas.loc, "`asm` statement cannot be marked `@safe`, use `@system` or `@trusted` instead");
         if (!(cas.stc & (STC.trusted | STC.safe)))
         {
-            sc.setUnsafe(false, cas.loc, "`asm` statement without `@trusted` annotation");
+            sc.setUnsafe(false, cas.loc, "executing an `asm` statement without `@trusted` annotation");
         }
 
         sc.pop();
index dc3f9da894104a550886f289bab08bbbb7f4ce25..ca10db1a2f5e1e3203b3bfe2861011ed6746043d 100644 (file)
@@ -944,8 +944,8 @@ private extern(D) bool isCopyConstructorCallable (StructDeclaration argStruct,
         return false;
     }
 
-    bool bpure = !f.isPure && sc.func.setImpure();
-    bool bsafe = !f.isSafe() && !f.isTrusted() && sc.setUnsafe();
+    bool bpure = !f.isPure && sc.func.setImpure(arg.loc, null);
+    bool bsafe = !f.isSafe() && !f.isTrusted() && sc.setUnsafe(false, arg.loc, null);
     bool bnogc = !f.isNogc && sc.func.setGC(arg.loc, null);
     if (bpure | bsafe | bnogc)
     {
index eadb1c7f7e3f4abf359eab88e7c377e4cca053a0..00c5007622486ed711ec372fcddf8e6f0c3b9d68 100644 (file)
@@ -19,6 +19,6 @@ void test3() @nogc
 
 void test4() @safe
 {
-    asm { }             // { dg-error "'asm' statement without '@trusted' annotation is not allowed in a '@safe' function" }
+    asm { }             // { dg-error ".asm. statement without .@trusted. annotation is not allowed in a .@safe. function" }
 }
 
index da7f8edb6d84fa92ee504aebf93587ed2c635d42..18d1f3604d5adca04c2df0b68cf8c304ba71d46d 100644 (file)
@@ -1,20 +1,17 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/attributediagnostic.d(24): Error: `@safe` function `attributediagnostic.layer2` cannot call `@system` function `attributediagnostic.layer1`
-fail_compilation/attributediagnostic.d(26):        which calls `attributediagnostic.layer0`
-fail_compilation/attributediagnostic.d(28):        which calls `attributediagnostic.system`
-fail_compilation/attributediagnostic.d(30):        which wasn't inferred `@safe` because of:
-fail_compilation/attributediagnostic.d(30):        `asm` statement without `@trusted` annotation
-fail_compilation/attributediagnostic.d(25):        `attributediagnostic.layer1` is declared here
-fail_compilation/attributediagnostic.d(46): Error: `@safe` function `D main` cannot call `@system` function `attributediagnostic.system1`
-fail_compilation/attributediagnostic.d(35):        which wasn't inferred `@safe` because of:
-fail_compilation/attributediagnostic.d(35):        cast from `uint` to `int*`
-fail_compilation/attributediagnostic.d(33):        `attributediagnostic.system1` is declared here
-fail_compilation/attributediagnostic.d(47): Error: `@safe` function `D main` cannot call `@system` function `attributediagnostic.system2`
-fail_compilation/attributediagnostic.d(41):        which wasn't inferred `@safe` because of:
-fail_compilation/attributediagnostic.d(41):        `@safe` function `system2` cannot call `@system` `fsys`
-fail_compilation/attributediagnostic.d(39):        `attributediagnostic.system2` is declared here
+fail_compilation/attributediagnostic.d(21): Error: `@safe` function `attributediagnostic.layer2` cannot call `@system` function `attributediagnostic.layer1`
+fail_compilation/attributediagnostic.d(23):        which calls `attributediagnostic.layer0`
+fail_compilation/attributediagnostic.d(25):        which calls `attributediagnostic.system`
+fail_compilation/attributediagnostic.d(27):        and executing an `asm` statement without `@trusted` annotation makes it fail to infer `@safe`
+fail_compilation/attributediagnostic.d(22):        `attributediagnostic.layer1` is declared here
+fail_compilation/attributediagnostic.d(43): Error: `@safe` function `D main` cannot call `@system` function `attributediagnostic.system1`
+fail_compilation/attributediagnostic.d(32):        and cast from `uint` to `int*` makes it fail to infer `@safe`
+fail_compilation/attributediagnostic.d(30):        `attributediagnostic.system1` is declared here
+fail_compilation/attributediagnostic.d(44): Error: `@safe` function `D main` cannot call `@system` function `attributediagnostic.system2`
+fail_compilation/attributediagnostic.d(38):        and calling `@system` `fsys` makes it fail to infer `@safe`
+fail_compilation/attributediagnostic.d(36):        `attributediagnostic.system2` is declared here
 ---
 */
 
index e3dbee899fc16e7edb7993cd35cc1ae37985d46e..9069ecc4788ded93f7b541d975dc78a069ea9d19 100644 (file)
@@ -4,17 +4,13 @@ TEST_OUTPUT:
 fail_compilation/attributediagnostic_nogc.d(21): Error: `@nogc` function `attributediagnostic_nogc.layer2` cannot call non-@nogc function `attributediagnostic_nogc.layer1`
 fail_compilation/attributediagnostic_nogc.d(22):        which calls `attributediagnostic_nogc.layer0`
 fail_compilation/attributediagnostic_nogc.d(23):        which calls `attributediagnostic_nogc.gc`
-fail_compilation/attributediagnostic_nogc.d(27):        which wasn't inferred `@nogc` because of:
-fail_compilation/attributediagnostic_nogc.d(27):        `asm` statement in function `attributediagnostic_nogc.gc` is assumed to use the GC - mark it with `@nogc` if it does not
+fail_compilation/attributediagnostic_nogc.d(27):        and executing an `asm` statement without `@nogc` annotation makes it fail to infer `@nogc`
 fail_compilation/attributediagnostic_nogc.d(43): Error: `@nogc` function `D main` cannot call non-@nogc function `attributediagnostic_nogc.gc1`
-fail_compilation/attributediagnostic_nogc.d(32):        which wasn't inferred `@nogc` because of:
-fail_compilation/attributediagnostic_nogc.d(32):        cannot use `new` in `@nogc` function `attributediagnostic_nogc.gc1`
+fail_compilation/attributediagnostic_nogc.d(32):        and allocating with `new` makes it fail to infer `@nogc`
 fail_compilation/attributediagnostic_nogc.d(44): Error: `@nogc` function `D main` cannot call non-@nogc function `attributediagnostic_nogc.gc2`
-fail_compilation/attributediagnostic_nogc.d(38):        which wasn't inferred `@nogc` because of:
-fail_compilation/attributediagnostic_nogc.d(38):        `@nogc` function `attributediagnostic_nogc.gc2` cannot call non-@nogc `fgc`
+fail_compilation/attributediagnostic_nogc.d(38):        and calling non-@nogc `fgc` makes it fail to infer `@nogc`
 fail_compilation/attributediagnostic_nogc.d(45): Error: `@nogc` function `D main` cannot call non-@nogc function `attributediagnostic_nogc.gcClosure`
-fail_compilation/attributediagnostic_nogc.d(48):        which wasn't inferred `@nogc` because of:
-fail_compilation/attributediagnostic_nogc.d(48):        function `attributediagnostic_nogc.gcClosure` is `@nogc` yet allocates closure for `gcClosure()` with the GC
+fail_compilation/attributediagnostic_nogc.d(48):        and allocating a closure for `gcClosure()` makes it fail to infer `@nogc`
 ---
 */
 #line 18
index 7fea322441267674b7cc7e30a0918ef0a0bf1712..add5ccc05a67765845c2878efd5b373188ba872b 100644 (file)
@@ -1,17 +1,15 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/attributediagnostic_nothrow.d(21): Error: function `attributediagnostic_nothrow.layer1` is not `nothrow`
-fail_compilation/attributediagnostic_nothrow.d(22):        which calls `attributediagnostic_nothrow.layer0`
-fail_compilation/attributediagnostic_nothrow.d(23):        which calls `attributediagnostic_nothrow.gc`
-fail_compilation/attributediagnostic_nothrow.d(27):        which wasn't inferred `nothrow` because of:
-fail_compilation/attributediagnostic_nothrow.d(27):        `asm` statement is assumed to throw - mark it with `nothrow` if it does not
-fail_compilation/attributediagnostic_nothrow.d(21): Error: function `attributediagnostic_nothrow.layer2` may throw but is marked as `nothrow`
-fail_compilation/attributediagnostic_nothrow.d(43): Error: function `attributediagnostic_nothrow.gc1` is not `nothrow`
-fail_compilation/attributediagnostic_nothrow.d(32):        which wasn't inferred `nothrow` because of:
-fail_compilation/attributediagnostic_nothrow.d(32):        `object.Exception` is thrown but not caught
-fail_compilation/attributediagnostic_nothrow.d(44): Error: function `attributediagnostic_nothrow.gc2` is not `nothrow`
-fail_compilation/attributediagnostic_nothrow.d(41): Error: function `D main` may throw but is marked as `nothrow`
+fail_compilation/attributediagnostic_nothrow.d(19): Error: function `attributediagnostic_nothrow.layer1` is not `nothrow`
+fail_compilation/attributediagnostic_nothrow.d(20):        which calls `attributediagnostic_nothrow.layer0`
+fail_compilation/attributediagnostic_nothrow.d(21):        which calls `attributediagnostic_nothrow.gc`
+fail_compilation/attributediagnostic_nothrow.d(25):        and executing an `asm` statement without a `nothrow` annotation makes it fail to infer `nothrow`
+fail_compilation/attributediagnostic_nothrow.d(19): Error: function `attributediagnostic_nothrow.layer2` may throw but is marked as `nothrow`
+fail_compilation/attributediagnostic_nothrow.d(41): Error: function `attributediagnostic_nothrow.gc1` is not `nothrow`
+fail_compilation/attributediagnostic_nothrow.d(30):        and `object.Exception` being thrown but not caught makes it fail to infer `nothrow`
+fail_compilation/attributediagnostic_nothrow.d(42): Error: function `attributediagnostic_nothrow.gc2` is not `nothrow`
+fail_compilation/attributediagnostic_nothrow.d(39): Error: function `D main` may throw but is marked as `nothrow`
 ---
 */
 
index a120dabf852d3c5b979648bfb6631732b9db8143..ef3863c475b00ea6488b2a3345f48d48461e0e73 100644 (file)
@@ -1,9 +1,8 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/attributediagnostic_pure.d(20): Error: `pure` function `D main` cannot call impure function `attributediagnostic_pure.gc`
-fail_compilation/attributediagnostic_pure.d(15):        which wasn't inferred `pure` because of:
-fail_compilation/attributediagnostic_pure.d(15):        `asm` statement is assumed to be impure - mark it with `pure` if it is not
+fail_compilation/attributediagnostic_pure.d(19): Error: `pure` function `D main` cannot call impure function `attributediagnostic_pure.gc`
+fail_compilation/attributediagnostic_pure.d(14):        and executing an `asm` statement without `pure` annotation makes it fail to infer `pure`
 ---
 */
 
index 78bd57fe1f217768a3790c8ee60d636e07218ea5..3083192950019184baee6bfde37147174d3899a9 100644 (file)
@@ -1,21 +1,18 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/diag10319.d(33): Error: `pure` function `D main` cannot call impure function `diag10319.foo`
-fail_compilation/diag10319.d(33): Error: `@safe` function `D main` cannot call `@system` function `diag10319.foo`
-fail_compilation/diag10319.d(22):        `diag10319.foo` is declared here
-fail_compilation/diag10319.d(34): Error: `pure` function `D main` cannot call impure function `diag10319.bar!int.bar`
-fail_compilation/diag10319.d(26):        which wasn't inferred `pure` because of:
-fail_compilation/diag10319.d(26):        `pure` function `diag10319.bar!int.bar` cannot access mutable static data `g`
-fail_compilation/diag10319.d(34): Error: `@safe` function `D main` cannot call `@system` function `diag10319.bar!int.bar`
-fail_compilation/diag10319.d(27):        which wasn't inferred `@safe` because of:
-fail_compilation/diag10319.d(27):        taking the address of stack-allocated local variable `x`
-fail_compilation/diag10319.d(24):        `diag10319.bar!int.bar` is declared here
-fail_compilation/diag10319.d(33): Error: function `diag10319.foo` is not `nothrow`
-fail_compilation/diag10319.d(34): Error: function `diag10319.bar!int.bar` is not `nothrow`
-fail_compilation/diag10319.d(28):        which wasn't inferred `nothrow` because of:
-fail_compilation/diag10319.d(28):        `object.Exception` is thrown but not caught
-fail_compilation/diag10319.d(31): Error: function `D main` may throw but is marked as `nothrow`
+fail_compilation/diag10319.d(30): Error: `pure` function `D main` cannot call impure function `diag10319.foo`
+fail_compilation/diag10319.d(30): Error: `@safe` function `D main` cannot call `@system` function `diag10319.foo`
+fail_compilation/diag10319.d(19):        `diag10319.foo` is declared here
+fail_compilation/diag10319.d(31): Error: `pure` function `D main` cannot call impure function `diag10319.bar!int.bar`
+fail_compilation/diag10319.d(23):        and accessing mutable static data `g` makes it fail to infer `pure`
+fail_compilation/diag10319.d(31): Error: `@safe` function `D main` cannot call `@system` function `diag10319.bar!int.bar`
+fail_compilation/diag10319.d(24):        and taking the address of stack-allocated local variable `x` makes it fail to infer `@safe`
+fail_compilation/diag10319.d(21):        `diag10319.bar!int.bar` is declared here
+fail_compilation/diag10319.d(30): Error: function `diag10319.foo` is not `nothrow`
+fail_compilation/diag10319.d(31): Error: function `diag10319.bar!int.bar` is not `nothrow`
+fail_compilation/diag10319.d(25):        and `object.Exception` being thrown but not caught makes it fail to infer `nothrow`
+fail_compilation/diag10319.d(28): Error: function `D main` may throw but is marked as `nothrow`
 ---
 */
 
index 1be0f1e85a2cdf96bd31b383ba313df3ec90ac5b..7f8979ccb33f2d0f60c64cb3bca89f377563a7ad 100644 (file)
@@ -1,14 +1,10 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/diag11198.d(17): Error: version `blah` declaration must be at module level
-fail_compilation/diag11198.d(18): Error: debug `blah` declaration must be at module level
-fail_compilation/diag11198.d(19): Deprecation: `version = <integer>` is deprecated, use version identifiers instead
-fail_compilation/diag11198.d(19): Error: version `1` level declaration must be at module level
-fail_compilation/diag11198.d(20): Deprecation: `debug = <integer>` is deprecated, use debug identifiers instead
-fail_compilation/diag11198.d(20): Error: debug `2` level declaration must be at module level
-fail_compilation/diag11198.d(21): Error: identifier or integer expected, not `""`
-fail_compilation/diag11198.d(22): Error: identifier or integer expected, not `""`
+fail_compilation/diag11198.d(13): Error: version `blah` declaration must be at module level
+fail_compilation/diag11198.d(14): Error: debug `blah` declaration must be at module level
+fail_compilation/diag11198.d(15): Error: identifier expected, not `""`
+fail_compilation/diag11198.d(16): Error: identifier expected, not `""`
 ---
 */
 
@@ -16,8 +12,6 @@ void main()
 {
     version = blah;
     debug = blah;
-    version = 1;
-    debug = 2;
     version = "";
     debug = "";
 }
index 4af87df0a2f745cce823adf7586879d03729c506..87ec1c5a9849a486802b63ff1fb4a25b8d2349f3 100644 (file)
@@ -1,10 +1,9 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/diag9620.d(20): Error: `pure` function `diag9620.main.bar` cannot call impure function `diag9620.foo1`
-fail_compilation/diag9620.d(21): Error: `pure` function `diag9620.main.bar` cannot call impure function `diag9620.foo2!().foo2`
-fail_compilation/diag9620.d(14):        which wasn't inferred `pure` because of:
-fail_compilation/diag9620.d(14):        `pure` function `diag9620.foo2!().foo2` cannot access mutable static data `x`
+fail_compilation/diag9620.d(19): Error: `pure` function `diag9620.main.bar` cannot call impure function `diag9620.foo1`
+fail_compilation/diag9620.d(20): Error: `pure` function `diag9620.main.bar` cannot call impure function `diag9620.foo2!().foo2`
+fail_compilation/diag9620.d(13):        and accessing mutable static data `x` makes it fail to infer `pure`
 ---
 */
 
index 99884c70c429bbaad4bb32b81b261352656087a2..51df97c8038f38b2df03177ddc744176f12ab309 100644 (file)
@@ -1,8 +1,8 @@
 /**
 TEST_OUTPUT:
 ---
-fail_compilation/diag_debug_conditional.d(1): Error: identifier or integer expected inside `debug(...)`, not `alias`
-fail_compilation/diag_debug_conditional.d(2): Error: identifier or integer expected inside `version(...)`, not `alias`
+fail_compilation/diag_debug_conditional.d(1): Error: identifier expected inside `debug(...)`, not `alias`
+fail_compilation/diag_debug_conditional.d(2): Error: identifier expected inside `version(...)`, not `alias`
 fail_compilation/diag_debug_conditional.d(3): Error: declaration expected following attribute, not end of file
 ---
  */
index fe68fea01ca5b638090b21295a1754b40912c164..2ef9e152d09f1cb31e6b6e8b681770465a216e4b 100644 (file)
@@ -1,8 +1,8 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail12932.d(11): Error: array literal in `@nogc` function `fail12932.foo` may cause a GC allocation
-fail_compilation/fail12932.d(15): Error: array literal in `@nogc` function `fail12932.foo` may cause a GC allocation
+fail_compilation/fail12932.d(11): Error: this array literal causes a GC allocation in `@nogc` function `foo`
+fail_compilation/fail12932.d(15): Error: this array literal causes a GC allocation in `@nogc` function `foo`
 ---
 */
 
index c9fac133ddb29128d79dfd4b7de22b4c6328981f..fd6c26ebd357e44690fe12f3715455a53c3eac27 100644 (file)
@@ -1,7 +1,7 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail21928.d(18): Error: array literal in `@nogc` function `D main` may cause a GC allocation
+fail_compilation/fail21928.d(18): Error: this array literal causes a GC allocation in `@nogc` function `main`
 ---
 */
 
index 3ce93e0a097b88547223210843eae9312f6b379f..2caf737baa3848741f73846e6a112addfefb7442 100644 (file)
@@ -1,7 +1,7 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail21928b.d(18): Error: array literal in `@nogc` function `D main` may cause a GC allocation
+fail_compilation/fail21928b.d(18): Error: this array literal causes a GC allocation in `@nogc` function `main`
 ---
 */
 
index 4ea41a58af14a8a34f6bf6b642489194bb21ac8d..adf12f5b6bf9fcca0682d7b95283f4b83600adfc 100644 (file)
@@ -1,13 +1,16 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/lexer23465.d(19): Error: character 0x1f37a is not allowed as a continue character in an identifier
-fail_compilation/lexer23465.d(19): Error: character 0x1f37a is not a valid token
-fail_compilation/lexer23465.d(20): Error: character '\' is not a valid token
-fail_compilation/lexer23465.d(21): Error: unterminated /+ +/ comment
-fail_compilation/lexer23465.d(22): Error: found `End of File` instead of array initializer
-fail_compilation/lexer23465.d(22): Error: semicolon needed to end declaration of `arr`, instead of `End of File`
-fail_compilation/lexer23465.d(17):        `arr` declared here
+fail_compilation/lexer23465.d(22): Error: character 0x1f37a is not allowed as a continue character in an identifier
+fail_compilation/lexer23465.d(22): Error: character 0x1f37a is not a valid token
+fail_compilation/lexer23465.d(23): Error: character '\' is not a valid token
+fail_compilation/lexer23465.d(24): Error: octal digit expected, not `9`
+fail_compilation/lexer23465.d(24): Error: octal literals larger than 7 are no longer supported
+fail_compilation/lexer23465.d(25): Error: integer overflow
+fail_compilation/lexer23465.d(26): Error: unterminated /+ +/ comment
+fail_compilation/lexer23465.d(27): Error: found `End of File` instead of array initializer
+fail_compilation/lexer23465.d(27): Error: semicolon needed to end declaration of `arr`, instead of `End of File`
+fail_compilation/lexer23465.d(20):        `arr` declared here
 ---
 */
 
@@ -18,4 +21,6 @@ int[] arr = [
        0,
     x🍺,
     3\,
+    09,
+    9999999999999999999999,
     5, /+
index 859bd40ab0617a1b2572f012583d7205f3788c62..b2bea5be8e8fcdb7431bc879429c83afecf149b9 100644 (file)
@@ -9,13 +9,13 @@ struct S3 { this(int) @nogc; }
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/nogc1.d(23): Error: cannot use `new` in `@nogc` function `nogc1.testNew`
-fail_compilation/nogc1.d(25): Error: cannot use `new` in `@nogc` function `nogc1.testNew`
-fail_compilation/nogc1.d(26): Error: cannot use `new` in `@nogc` function `nogc1.testNew`
-fail_compilation/nogc1.d(28): Error: cannot use `new` in `@nogc` function `nogc1.testNew`
+fail_compilation/nogc1.d(23): Error: allocating with `new` causes a GC allocation in `@nogc` function `testNew`
+fail_compilation/nogc1.d(25): Error: allocating with `new` causes a GC allocation in `@nogc` function `testNew`
+fail_compilation/nogc1.d(26): Error: allocating with `new` causes a GC allocation in `@nogc` function `testNew`
+fail_compilation/nogc1.d(28): Error: allocating with `new` causes a GC allocation in `@nogc` function `testNew`
 fail_compilation/nogc1.d(29): Error: `@nogc` function `nogc1.testNew` cannot call non-@nogc constructor `nogc1.S2.this`
-fail_compilation/nogc1.d(30): Error: cannot use `new` in `@nogc` function `nogc1.testNew`
-fail_compilation/nogc1.d(32): Error: cannot use `new` in `@nogc` function `nogc1.testNew`
+fail_compilation/nogc1.d(30): Error: allocating with `new` causes a GC allocation in `@nogc` function `testNew`
+fail_compilation/nogc1.d(32): Error: allocating with `new` causes a GC allocation in `@nogc` function `testNew`
 ---
 */
 @nogc void testNew()
@@ -35,12 +35,12 @@ fail_compilation/nogc1.d(32): Error: cannot use `new` in `@nogc` function `nogc1
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/nogc1.d(48): Error: cannot use `new` in `@nogc` function `nogc1.testNewScope`
-fail_compilation/nogc1.d(50): Error: cannot use `new` in `@nogc` function `nogc1.testNewScope`
-fail_compilation/nogc1.d(51): Error: cannot use `new` in `@nogc` function `nogc1.testNewScope`
-fail_compilation/nogc1.d(53): Error: cannot use `new` in `@nogc` function `nogc1.testNewScope`
+fail_compilation/nogc1.d(48): Error: allocating with `new` causes a GC allocation in `@nogc` function `testNewScope`
+fail_compilation/nogc1.d(50): Error: allocating with `new` causes a GC allocation in `@nogc` function `testNewScope`
+fail_compilation/nogc1.d(51): Error: allocating with `new` causes a GC allocation in `@nogc` function `testNewScope`
+fail_compilation/nogc1.d(53): Error: allocating with `new` causes a GC allocation in `@nogc` function `testNewScope`
 fail_compilation/nogc1.d(54): Error: `@nogc` function `nogc1.testNewScope` cannot call non-@nogc constructor `nogc1.S2.this`
-fail_compilation/nogc1.d(55): Error: cannot use `new` in `@nogc` function `nogc1.testNewScope`
+fail_compilation/nogc1.d(55): Error: allocating with `new` causes a GC allocation in `@nogc` function `testNewScope`
 ---
 */
 @nogc void testNewScope()
index 9016dd9e9696d6af4f8ae5228f4f30b37002e1b9..9601c2faa2e66ad9d03d3615ff1526f2df2b0e77 100644 (file)
@@ -5,14 +5,14 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/nogc2.d(20): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`
-fail_compilation/nogc2.d(21): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`
-fail_compilation/nogc2.d(22): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`
-fail_compilation/nogc2.d(24): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`
-fail_compilation/nogc2.d(25): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`
-fail_compilation/nogc2.d(26): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`
-fail_compilation/nogc2.d(27): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`
-fail_compilation/nogc2.d(28): Error: cannot use operator `~` in `@nogc` function `nogc2.testCat`
+fail_compilation/nogc2.d(20): Error: concatenating with operator `~` causes a GC allocation in `@nogc` function `testCat`
+fail_compilation/nogc2.d(21): Error: concatenating with operator `~` causes a GC allocation in `@nogc` function `testCat`
+fail_compilation/nogc2.d(22): Error: concatenating with operator `~` causes a GC allocation in `@nogc` function `testCat`
+fail_compilation/nogc2.d(24): Error: concatenating with operator `~` causes a GC allocation in `@nogc` function `testCat`
+fail_compilation/nogc2.d(25): Error: concatenating with operator `~` causes a GC allocation in `@nogc` function `testCat`
+fail_compilation/nogc2.d(26): Error: concatenating with operator `~` causes a GC allocation in `@nogc` function `testCat`
+fail_compilation/nogc2.d(27): Error: concatenating with operator `~` causes a GC allocation in `@nogc` function `testCat`
+fail_compilation/nogc2.d(28): Error: concatenating with operator `~` causes a GC allocation in `@nogc` function `testCat`
 ---
 */
 @nogc void testCat(int[] a, string s)
@@ -37,9 +37,9 @@ fail_compilation/nogc2.d(28): Error: cannot use operator `~` in `@nogc` function
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/nogc2.d(47): Error: cannot use operator `~=` in `@nogc` function `nogc2.testCatAssign`
-fail_compilation/nogc2.d(49): Error: cannot use operator `~=` in `@nogc` function `nogc2.testCatAssign`
-fail_compilation/nogc2.d(50): Error: cannot use operator `~=` in `@nogc` function `nogc2.testCatAssign`
+fail_compilation/nogc2.d(47): Error: appending to this array with operator `~=` causes a GC allocation in `@nogc` function `testCatAssign`
+fail_compilation/nogc2.d(49): Error: appending to this array with operator `~=` causes a GC allocation in `@nogc` function `testCatAssign`
+fail_compilation/nogc2.d(50): Error: appending to this array with operator `~=` causes a GC allocation in `@nogc` function `testCatAssign`
 ---
 */
 @nogc void testCatAssign(int[] a, string s)
@@ -57,8 +57,8 @@ fail_compilation/nogc2.d(50): Error: cannot use operator `~=` in `@nogc` functio
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/nogc2.d(69): Error: array literal in `@nogc` function `nogc2.testArray` may cause a GC allocation
-fail_compilation/nogc2.d(70): Error: array literal in `@nogc` function `nogc2.testArray` may cause a GC allocation
+fail_compilation/nogc2.d(69): Error: this array literal causes a GC allocation in `@nogc` function `testArray`
+fail_compilation/nogc2.d(70): Error: this array literal causes a GC allocation in `@nogc` function `testArray`
 ---
 */
 @nogc void testArray()
@@ -75,8 +75,8 @@ fail_compilation/nogc2.d(70): Error: array literal in `@nogc` function `nogc2.te
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/nogc2.d(86): Error: associative array literal in `@nogc` function `nogc2.testAssocArray` may cause a GC allocation
-fail_compilation/nogc2.d(87): Error: associative array literal in `@nogc` function `nogc2.testAssocArray` may cause a GC allocation
+fail_compilation/nogc2.d(86): Error: this associative array literal causes a GC allocation in `@nogc` function `testAssocArray`
+fail_compilation/nogc2.d(87): Error: this associative array literal causes a GC allocation in `@nogc` function `testAssocArray`
 ---
 */
 @nogc void testAssocArray()
@@ -92,7 +92,7 @@ fail_compilation/nogc2.d(87): Error: associative array literal in `@nogc` functi
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/nogc2.d(100): Error: assigning an associative array element in `@nogc` function `nogc2.testIndex` may cause a GC allocation
+fail_compilation/nogc2.d(100): Error: assigning this associative array element causes a GC allocation in `@nogc` function `testIndex`
 ---
 */
 @nogc void testIndex(int[int] aa)
index b53903ffbc0fc73d54cae26728e8fe925ae4b7b8..6fa115a6a8ac7ad526f26c087edf6d0358d90e74 100644 (file)
@@ -5,9 +5,9 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/nogc3.d(15): Error: setting `length` in `@nogc` function `nogc3.testArrayLength` may cause a GC allocation
-fail_compilation/nogc3.d(16): Error: setting `length` in `@nogc` function `nogc3.testArrayLength` may cause a GC allocation
-fail_compilation/nogc3.d(17): Error: setting `length` in `@nogc` function `nogc3.testArrayLength` may cause a GC allocation
+fail_compilation/nogc3.d(15): Error: setting this array's `length` causes a GC allocation in `@nogc` function `testArrayLength`
+fail_compilation/nogc3.d(16): Error: setting this array's `length` causes a GC allocation in `@nogc` function `testArrayLength`
+fail_compilation/nogc3.d(17): Error: setting this array's `length` causes a GC allocation in `@nogc` function `testArrayLength`
 ---
 */
 @nogc void testArrayLength(int[] a)
@@ -75,10 +75,10 @@ fail_compilation/nogc3.d(68):        `x` declared here
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/nogc3.d(87): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation
-fail_compilation/nogc3.d(88): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation
-fail_compilation/nogc3.d(94): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation
-fail_compilation/nogc3.d(93): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation
+fail_compilation/nogc3.d(87): Error: this array literal causes a GC allocation in `@nogc` function `foo13702`
+fail_compilation/nogc3.d(88): Error: this array literal causes a GC allocation in `@nogc` function `foo13702`
+fail_compilation/nogc3.d(94): Error: this array literal causes a GC allocation in `@nogc` function `bar13702`
+fail_compilation/nogc3.d(93): Error: this array literal causes a GC allocation in `@nogc` function `bar13702`
 ---
 */
 int[] foo13702(bool b) @nogc
index 5ba078d5166511b1674d6635818c4d397e2c62c1..88f6d83632b6e9dcd3739820a3bb21a05a71c438 100644 (file)
@@ -2,10 +2,9 @@
 REQUIRED_ARGS: -de
 TEST_OUTPUT:
 ---
-fail_compilation/systemvariables_deprecation.d(16): Deprecation: `@safe` function `main` calling `middle`
-fail_compilation/systemvariables_deprecation.d(21):        which calls `systemvariables_deprecation.inferred`
-fail_compilation/systemvariables_deprecation.d(27):        which wouldn't be `@safe` because of:
-fail_compilation/systemvariables_deprecation.d(27):        access `@system` variable `x0`
+fail_compilation/systemvariables_deprecation.d(15): Deprecation: `@safe` function `main` calling `middle`
+fail_compilation/systemvariables_deprecation.d(20):        which calls `systemvariables_deprecation.inferred`
+fail_compilation/systemvariables_deprecation.d(26):        and access `@system` variable `x0` makes it fail to infer `@safe`
 ---
 */
 
index 73ec588c777370d2a65b3eea1da47be2e873869f..5a873bf9c96ef05c6f424586c661397323386ffb 100644 (file)
@@ -1,21 +1,15 @@
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/test13786.d(16): Deprecation: `debug = <integer>` is deprecated, use debug identifiers instead
-fail_compilation/test13786.d(18): Deprecation: `version = <integer>` is deprecated, use version identifiers instead
-fail_compilation/test13786.d(16): Error: debug `123` level declaration must be at module level
-fail_compilation/test13786.d(17): Error: debug `abc` declaration must be at module level
-fail_compilation/test13786.d(18): Error: version `123` level declaration must be at module level
-fail_compilation/test13786.d(19): Error: version `abc` declaration must be at module level
-fail_compilation/test13786.d(22): Error: template instance `test13786.T!()` error instantiating
+fail_compilation/test13786.d(12): Error: debug `abc` declaration must be at module level
+fail_compilation/test13786.d(13): Error: version `abc` declaration must be at module level
+fail_compilation/test13786.d(16): Error: template instance `test13786.T!()` error instantiating
 ---
 */
 
 template T()
 {
-    debug = 123;
     debug = abc;
-    version = 123;
     version = abc;
 }
 
index 48a6fe2e9c1448b4398b4129b7294cb1c57a45dd..25471d242fa161158815e9e2fdeeb90e19350b4c 100644 (file)
@@ -2,15 +2,12 @@
 REQUIRED_ARGS: -de
 TEST_OUTPUT:
 ---
-fail_compilation/test20655.d(29): Deprecation: `@safe` function `g` calling `f1`
-fail_compilation/test20655.d(24):        which wouldn't be `@safe` because of:
-fail_compilation/test20655.d(24):        accessing overlapped field `U.s` with pointers
-fail_compilation/test20655.d(30): Deprecation: `@safe` function `g` calling `f2`
-fail_compilation/test20655.d(25):        which wouldn't be `@safe` because of:
-fail_compilation/test20655.d(25):        accessing overlapped field `U.s` with pointers
-fail_compilation/test20655.d(31): Deprecation: `@safe` function `g` calling `f3`
-fail_compilation/test20655.d(28):        which wouldn't be `@safe` because of:
-fail_compilation/test20655.d(28):        accessing overlapped field `U.s` with pointers
+fail_compilation/test20655.d(26): Deprecation: `@safe` function `g` calling `f1`
+fail_compilation/test20655.d(21):        and accessing overlapped field `U.s` with pointers makes it fail to infer `@safe`
+fail_compilation/test20655.d(27): Deprecation: `@safe` function `g` calling `f2`
+fail_compilation/test20655.d(22):        and accessing overlapped field `U.s` with pointers makes it fail to infer `@safe`
+fail_compilation/test20655.d(28): Deprecation: `@safe` function `g` calling `f3`
+fail_compilation/test20655.d(25):        and accessing overlapped field `U.s` with pointers makes it fail to infer `@safe`
 ---
 */
 
index fedf31b5fc838364797dc3bf664dd6d744eb3554..f447128da029144fc6fb4ed97ef16fdd6abd521c 100644 (file)
@@ -1,7 +1,7 @@
 /*\r
 TEST_OUTPUT:\r
 ---\r
-fail_compilation/test23170.d(10): Error: array literal in `@nogc` delegate `test23170.__lambda_L10_C15` may cause a GC allocation\r
+fail_compilation/test23170.d(10): Error: this array literal causes a GC allocation in `@nogc` delegate `__lambda_L10_C15`\r
 ---\r
 */\r
 // https://issues.dlang.org/show_bug.cgi?id=23170\r
index a04feae2500f5a12eb5a9c2935ca0a5d1f60b8bf..8a72ff116f8fbb4c95661829274afb475986304d 100644 (file)
@@ -140,8 +140,7 @@ TEST_OUTPUT:
 fail_compilation/testInference.d(154): Error: `pure` function `testInference.bar14049` cannot call impure function `testInference.foo14049!int.foo14049`
 fail_compilation/testInference.d(149):        which calls `testInference.foo14049!int.foo14049.__lambda_L147_C14`
 fail_compilation/testInference.d(148):        which calls `testInference.impure14049`
-fail_compilation/testInference.d(143):        which wasn't inferred `pure` because of:
-fail_compilation/testInference.d(143):        `pure` function `testInference.impure14049` cannot access mutable static data `i`
+fail_compilation/testInference.d(143):        and accessing mutable static data `i` makes it fail to infer `pure`
 ---
 */
 #line 143
@@ -191,11 +190,9 @@ void test12422() pure
 TEST_OUTPUT:
 ---
 fail_compilation/testInference.d(198): Error: `pure` function `testInference.test13729a` cannot call impure function `testInference.test13729a.foo`
-fail_compilation/testInference.d(196):        which wasn't inferred `pure` because of:
-fail_compilation/testInference.d(196):        `pure` function `testInference.test13729a.foo` cannot access mutable static data `g13729`
+fail_compilation/testInference.d(196):        and accessing mutable static data `g13729` makes it fail to infer `pure`
 fail_compilation/testInference.d(206): Error: `pure` function `testInference.test13729b` cannot call impure function `testInference.test13729b.foo!().foo`
-fail_compilation/testInference.d(204):        which wasn't inferred `pure` because of:
-fail_compilation/testInference.d(204):        `pure` function `testInference.test13729b.foo!().foo` cannot access mutable static data `g13729`
+fail_compilation/testInference.d(204):        and accessing mutable static data `g13729` makes it fail to infer `pure`
 ---
 */
 
index 18ad055addcdfeac289fe3a2f0aa025767eed23f..0e1068a42899b41508b5c90a245f8f9e1d12459b 100644 (file)
@@ -1,14 +1,3 @@
-// REQUIRED_ARGS: -verrors=simple
-/*
-TEST_OUTPUT:
----
-runnable/lexer.d(86): Deprecation: `version( <integer> )` is deprecated, use version identifiers instead
-runnable/lexer.d(87): Deprecation: `debug( <integer> )` is deprecated, use debug identifiers instead
----
-*/
-
-/*********************************************************/
-
 void test6()
 {
     string s = q"(foo(xxx))";
@@ -82,12 +71,6 @@ void test8()
 
 /*********************************************************/
 
-// https://issues.dlang.org/show_bug.cgi?id=6584
-version(9223372036854775807){}
-debug(9223372036854775807){}
-
-/*********************************************************/
-
 enum e13102=184467440737095516153.6L;
 
 /*********************************************************/
index be15cb244a1b471aa8e94c8e9bd48ccb21d893de..507c1143feca93569901af011ebbdfa6c3761303 100644 (file)
@@ -4330,28 +4330,28 @@ void test14696(int len = 2)
     check({ foo(len >  2 ? null : (len != 2 ? null : makeS(1).get()       )       ); }, "makeS(1).get(1).foo.dtor(1).");
 
     // temporary in condition and throwing callee
-    // check({ fooThrow(len == 2 ?        makeS(1).get() : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
-    // check({ fooThrow(len == 2 ? null : makeS(1).get()       ); }, "fooThrow.");
-    // check({ fooThrow(len != 2 ?        makeS(1).get() : null); }, "fooThrow.");
-    // check({ fooThrow(len != 2 ? null : makeS(1).get()       ); }, "makeS(1).get(1).fooThrow.dtor(1).");
+    check({ fooThrow(len == 2 ?        makeS(1).get() : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
+    check({ fooThrow(len == 2 ? null : makeS(1).get()       ); }, "fooThrow.");
+    check({ fooThrow(len != 2 ?        makeS(1).get() : null); }, "fooThrow.");
+    check({ fooThrow(len != 2 ? null : makeS(1).get()       ); }, "makeS(1).get(1).fooThrow.dtor(1).");
 
     // temporary in nesting condititions and throwing callee
-    // check({ fooThrow(len >= 2 ?        (len == 2 ?        makeS(1).get() : null) : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
-    // check({ fooThrow(len >= 2 ?        (len == 2 ? null : makeS(1).get()       ) : null); }, "fooThrow.");
-    // check({ fooThrow(len >= 2 ?        (len != 2 ?        makeS(1).get() : null) : null); }, "fooThrow.");
-    // check({ fooThrow(len >= 2 ?        (len != 2 ? null : makeS(1).get()       ) : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
-    // check({ fooThrow(len >= 2 ? null : (len == 2 ?        makeS(1).get() : null)       ); }, "fooThrow.");
-    // check({ fooThrow(len >= 2 ? null : (len == 2 ? null : makeS(1).get()       )       ); }, "fooThrow.");
-    // check({ fooThrow(len >= 2 ? null : (len != 2 ?        makeS(1).get() : null)       ); }, "fooThrow.");
-    // check({ fooThrow(len >= 2 ? null : (len != 2 ? null : makeS(1).get()       )       ); }, "fooThrow.");
-    // check({ fooThrow(len >  2 ?        (len == 2 ?        makeS(1).get() : null) : null); }, "fooThrow.");
-    // check({ fooThrow(len >  2 ?        (len == 2 ? null : makeS(1).get()       ) : null); }, "fooThrow.");
-    // check({ fooThrow(len >  2 ?        (len != 2 ?        makeS(1).get() : null) : null); }, "fooThrow.");
-    // check({ fooThrow(len >  2 ?        (len != 2 ? null : makeS(1).get()       ) : null); }, "fooThrow.");
-    // check({ fooThrow(len >  2 ? null : (len == 2 ?        makeS(1).get() : null)       ); }, "makeS(1).get(1).fooThrow.dtor(1).");
-    // check({ fooThrow(len >  2 ? null : (len == 2 ? null : makeS(1).get()       )       ); }, "fooThrow.");
-    // check({ fooThrow(len >  2 ? null : (len != 2 ?        makeS(1).get() : null)       ); }, "fooThrow.");
-    // check({ fooThrow(len >  2 ? null : (len != 2 ? null : makeS(1).get()       )       ); }, "makeS(1).get(1).fooThrow.dtor(1).");
+    check({ fooThrow(len >= 2 ?        (len == 2 ?        makeS(1).get() : null) : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
+    check({ fooThrow(len >= 2 ?        (len == 2 ? null : makeS(1).get()       ) : null); }, "fooThrow.");
+    check({ fooThrow(len >= 2 ?        (len != 2 ?        makeS(1).get() : null) : null); }, "fooThrow.");
+    check({ fooThrow(len >= 2 ?        (len != 2 ? null : makeS(1).get()       ) : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
+    check({ fooThrow(len >= 2 ? null : (len == 2 ?        makeS(1).get() : null)       ); }, "fooThrow.");
+    check({ fooThrow(len >= 2 ? null : (len == 2 ? null : makeS(1).get()       )       ); }, "fooThrow.");
+    check({ fooThrow(len >= 2 ? null : (len != 2 ?        makeS(1).get() : null)       ); }, "fooThrow.");
+    check({ fooThrow(len >= 2 ? null : (len != 2 ? null : makeS(1).get()       )       ); }, "fooThrow.");
+    check({ fooThrow(len >  2 ?        (len == 2 ?        makeS(1).get() : null) : null); }, "fooThrow.");
+    check({ fooThrow(len >  2 ?        (len == 2 ? null : makeS(1).get()       ) : null); }, "fooThrow.");
+    check({ fooThrow(len >  2 ?        (len != 2 ?        makeS(1).get() : null) : null); }, "fooThrow.");
+    check({ fooThrow(len >  2 ?        (len != 2 ? null : makeS(1).get()       ) : null); }, "fooThrow.");
+    check({ fooThrow(len >  2 ? null : (len == 2 ?        makeS(1).get() : null)       ); }, "makeS(1).get(1).fooThrow.dtor(1).");
+    check({ fooThrow(len >  2 ? null : (len == 2 ? null : makeS(1).get()       )       ); }, "fooThrow.");
+    check({ fooThrow(len >  2 ? null : (len != 2 ?        makeS(1).get() : null)       ); }, "fooThrow.");
+    check({ fooThrow(len >  2 ? null : (len != 2 ? null : makeS(1).get()       )       ); }, "makeS(1).get(1).fooThrow.dtor(1).");
 
     // temporaries in each conditions
     check({ foo(len == 2 ? makeS(1).get() : null, len == 2 ? makeS(2).get() : null); }, "makeS(1).get(1).makeS(2).get(2).foo.dtor(2).dtor(1).");
index 33bb398c00d4d3f182794700261866d2316a453b..4172630afa08de5c8fbb63f151f71260248bec10 100644 (file)
@@ -1,4 +1,4 @@
-d6f693b46a1565172cac7a1438905141783a164f
+d1157134103a209d36d6ee9c1df1d61d5929ec6d
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
index 258183fd50516d83c72c9c45e7d316506b7a399c..af077be77bcb4f64a1816fb52471d14e97457a3b 100644 (file)
@@ -7,8 +7,8 @@
 
 module core.gc.config;
 
-import core.stdc.stdio;
 import core.internal.parseoptions;
+import core.stdc.stdio : printf;
 
 __gshared Config config;
 
index 4c88f15abfb61795419f50de7572f8ad6f8fb22e..27c8b99d2cbf897db401a5ab121c180f3b40534c 100644 (file)
@@ -794,7 +794,7 @@ version (unittest)
 {
     version (none)
     {
-        import core.stdc.stdio;
+        import core.stdc.stdio : printf;
 
         @trusted
         void print(Cent c)
index c9761ece24bb3dffb4b81ec3b654a975d7ba0f94..c5d8c79bfbc7d823243d524687ccce50bd74f77a 100644 (file)
@@ -349,7 +349,7 @@ T[] _d_newarrayU(T)(size_t length, bool isShared=false) @trusted
 {
     import core.exception : onOutOfMemoryError;
     import core.internal.traits : Unqual;
-    import core.internal.array.utils : __arrayStart, __setArrayAllocLength, __arrayAlloc;
+    import core.internal.array.utils : __arrayAlloc;
 
     alias UnqT = Unqual!T;
 
@@ -395,16 +395,11 @@ Loverflow:
     assert(0);
 
 Lcontinue:
-    auto info = __arrayAlloc!UnqT(arraySize);
-    if (!info.base)
+    auto arr = __arrayAlloc!UnqT(arraySize);
+    if (!arr.ptr)
         goto Loverflow;
-    debug(PRINTF) printf("p = %p\n", info.base);
-
-    auto arrstart = __arrayStart(info);
-
-    __setArrayAllocLength!UnqT(info, arraySize, isShared);
-
-    return (cast(T*) arrstart)[0 .. length];
+    debug(PRINTF) printf("p = %p\n", arr.ptr);
+    return (cast(T*) arr.ptr)[0 .. length];
 }
 
 /// ditto
@@ -522,7 +517,7 @@ Tarr _d_newarraymTX(Tarr : U[], T, U)(size_t[] dims, bool isShared=false) @trust
 
     void[] __allocateInnerArray(size_t[] dims)
     {
-        import core.internal.array.utils : __arrayStart, __setArrayAllocLength, __arrayAlloc;
+        import core.internal.array.utils : __arrayAlloc;
 
         auto dim = dims[0];
 
@@ -535,15 +530,13 @@ Tarr _d_newarraymTX(Tarr : U[], T, U)(size_t[] dims, bool isShared=false) @trust
 
         auto allocSize = (void[]).sizeof * dim;
         // the array-of-arrays holds pointers! Don't use UnqT here!
-        auto info = __arrayAlloc!(void[])(allocSize);
-        __setArrayAllocLength!(void[])(info, allocSize, isShared);
-        auto p = __arrayStart(info)[0 .. dim];
+        auto arr = __arrayAlloc!(void[])(allocSize);
 
         foreach (i; 0..dim)
         {
-            (cast(void[]*)p.ptr)[i] = __allocateInnerArray(dims[1..$]);
+            (cast(void[]*)arr.ptr)[i] = __allocateInnerArray(dims[1..$]);
         }
-        return p;
+        return arr.ptr[0 .. dim];
     }
 
     auto result = __allocateInnerArray(dims);
@@ -580,6 +573,21 @@ unittest
     }
 }
 
+// Test 3-level array allocation (this uses different code paths).
+unittest
+{
+    int[][][] a = _d_newarraymTX!(int[][][], int)([3, 4, 5]);
+    int[5] zeros = 0;
+
+    assert(a.length == 3);
+    foreach(l2; a)
+    {
+        assert(l2.length == 4);
+        foreach(l3; l2)
+            assert(l3 == zeros[]);
+    }
+}
+
 // https://issues.dlang.org/show_bug.cgi?id=24436
 @system unittest
 {
index 54cfc26af5646850b4e9aadded351ca70c5a1e33..03d414471ad695a5e8b213c178da28b4230ffbea 100644 (file)
@@ -12,24 +12,8 @@ module core.internal.array.utils;
 import core.internal.traits : Parameters;
 import core.memory : GC;
 
-alias BlkInfo = GC.BlkInfo;
 alias BlkAttr = GC.BlkAttr;
 
-private
-{
-    enum : size_t
-    {
-        PAGESIZE = 4096,
-        BIGLENGTHMASK = ~(PAGESIZE - 1),
-        SMALLPAD = 1,
-        MEDPAD = ushort.sizeof,
-        LARGEPREFIX = 16, // 16 bytes padding at the front of the array
-        LARGEPAD = LARGEPREFIX + 1,
-        MAXSMALLSIZE = 256-SMALLPAD,
-        MAXMEDSIZE = (PAGESIZE / 2) - MEDPAD
-    }
-}
-
 auto gcStatsPure() nothrow pure
 {
     import core.memory : GC;
@@ -156,55 +140,21 @@ template isPostblitNoThrow(T) {
 }
 
 /**
- * Clear padding that might not be zeroed by the GC (it assumes it is within the
- * requested size from the start, but it is actually at the end of the allocated
- * block).
- *
- * Params:
- *  info = array allocation data
- *  arrSize = size of the array in bytes
- *  padSize = size of the padding in bytes
- */
-void __arrayClearPad()(ref BlkInfo info, size_t arrSize, size_t padSize) nothrow pure
-{
-    import core.stdc.string;
-    if (padSize > MEDPAD && !(info.attr & BlkAttr.NO_SCAN) && info.base)
-    {
-        if (info.size < PAGESIZE)
-            memset(info.base + arrSize, 0, padSize);
-        else
-            memset(info.base, 0, LARGEPREFIX);
-    }
-}
-
-/**
- * Allocate an array memory block by applying the proper padding and assigning
- * block attributes if not inherited from the existing block.
+ * Allocate a memory block with appendable capabilities for array usage.
  *
  * Params:
  *  arrSize = size of the allocated array in bytes
  * Returns:
- *  `BlkInfo` with allocation metadata
+ *  `void[]` matching requested size on success, `null` on failure.
  */
-BlkInfo __arrayAlloc(T)(size_t arrSize) @trusted
+void[] __arrayAlloc(T)(size_t arrSize) @trusted
 {
-    import core.checkedint;
     import core.lifetime : TypeInfoSize;
     import core.internal.traits : hasIndirections;
 
     enum typeInfoSize = TypeInfoSize!T;
     BlkAttr attr = BlkAttr.APPENDABLE;
 
-    size_t padSize = arrSize > MAXMEDSIZE ?
-        LARGEPAD :
-        ((arrSize > MAXSMALLSIZE ? MEDPAD : SMALLPAD) + typeInfoSize);
-
-    bool overflow;
-    auto paddedSize = addu(arrSize, padSize, overflow);
-
-    if (overflow)
-        return BlkInfo();
-
     /* `extern(C++)` classes don't have a classinfo pointer in their vtable,
      * so the GC can't finalize them.
      */
@@ -213,59 +163,8 @@ BlkInfo __arrayAlloc(T)(size_t arrSize) @trusted
     static if (!hasIndirections!T)
         attr |= BlkAttr.NO_SCAN;
 
-    auto bi = GC.qalloc(paddedSize, attr, typeid(T));
-    __arrayClearPad(bi, arrSize, padSize);
-    return bi;
-}
-
-/**
- * Get the start of the array for the given block.
- *
- * Params:
- *  info = array metadata
- * Returns:
- *  pointer to the start of the array
- */
-void *__arrayStart()(return scope BlkInfo info) nothrow pure
-{
-    return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0);
-}
-
-/**
- * Set the allocated length of the array block.  This is called when an array
- * is appended to or its length is set.
- *
- * The allocated block looks like this for blocks < PAGESIZE:
- * `|elem0|elem1|elem2|...|elemN-1|emptyspace|N*elemsize|`
- *
- * The size of the allocated length at the end depends on the block size:
- *      a block of 16 to 256 bytes has an 8-bit length.
- *      a block with 512 to pagesize/2 bytes has a 16-bit length.
- *
- * For blocks >= pagesize, the length is a size_t and is at the beginning of the
- * block.  The reason we have to do this is because the block can extend into
- * more pages, so we cannot trust the block length if it sits at the end of the
- * block, because it might have just been extended.  If we can prove in the
- * future that the block is unshared, we may be able to change this, but I'm not
- * sure it's important.
- *
- * In order to do put the length at the front, we have to provide 16 bytes
- * buffer space in case the block has to be aligned properly.  In x86, certain
- * SSE instructions will only work if the data is 16-byte aligned.  In addition,
- * we need the sentinel byte to prevent accidental pointers to the next block.
- * Because of the extra overhead, we only do this for page size and above, where
- * the overhead is minimal compared to the block size.
- *
- * So for those blocks, it looks like:
- * `|N*elemsize|padding|elem0|elem1|...|elemN-1|emptyspace|sentinelbyte|``
- *
- * where `elem0` starts 16 bytes after the first byte.
- */
-bool __setArrayAllocLength(T)(ref BlkInfo info, size_t newLength, bool isShared, size_t oldLength = ~0)
-{
-    import core.lifetime : TypeInfoSize;
-    import core.internal.gc.blockmeta : __setArrayAllocLengthImpl, __setBlockFinalizerInfo;
-    static if (TypeInfoSize!T)
-        __setBlockFinalizerInfo(info, typeid(T));
-    return __setArrayAllocLengthImpl(info, newLength, isShared, oldLength, TypeInfoSize!T);
+    auto ptr = GC.malloc(arrSize, attr, typeid(T));
+    if (ptr)
+        return ptr[0 .. arrSize];
+    return null;
 }
index 9d959d54721d6d40427ab28dcb157ec741de2513..768dcd76ba3041e99acdb0fac620cdd46f43189d 100644 (file)
@@ -69,12 +69,11 @@ size_t structTypeInfoSize(const TypeInfo ti) pure nothrow @nogc
 
   where elem0 starts 16 bytes after the first byte.
   */
-bool __setArrayAllocLength(ref BlkInfo info, size_t newlength, bool isshared, const TypeInfo tinext, size_t oldlength = ~0) pure nothrow
+bool __setArrayAllocLength(ref BlkInfo info, size_t newlength, bool isshared, const TypeInfo tinext, size_t oldlength = size_t.max) pure nothrow
 {
-    size_t typeInfoSize = (info.attr & BlkAttr.STRUCTFINAL) ? size_t.sizeof : 0;
-    if (typeInfoSize)
-        __setBlockFinalizerInfo(info, tinext);
+    __setBlockFinalizerInfo(info, tinext);
 
+    size_t typeInfoSize = (info.attr & BlkAttr.STRUCTFINAL) ? size_t.sizeof : 0;
     return __setArrayAllocLengthImpl(info, newlength, isshared, oldlength, typeInfoSize);
 }
 
@@ -97,7 +96,7 @@ bool __setArrayAllocLengthImpl(ref BlkInfo info, size_t newlength, bool isshared
             return false;
 
         auto length = cast(ubyte *)(info.base + info.size - typeInfoSize - SMALLPAD);
-        if (oldlength != ~0)
+        if (oldlength != size_t.max)
         {
             if (isshared)
             {
@@ -123,7 +122,7 @@ bool __setArrayAllocLengthImpl(ref BlkInfo info, size_t newlength, bool isshared
             // new size does not fit inside block
             return false;
         auto length = cast(ushort *)(info.base + info.size - typeInfoSize - MEDPAD);
-        if (oldlength != ~0)
+        if (oldlength != size_t.max)
         {
             if (isshared)
             {
@@ -149,7 +148,7 @@ bool __setArrayAllocLengthImpl(ref BlkInfo info, size_t newlength, bool isshared
             // new size does not fit inside block
             return false;
         auto length = cast(size_t *)(info.base);
-        if (oldlength != ~0)
+        if (oldlength != size_t.max)
         {
             if (isshared)
             {
@@ -176,24 +175,49 @@ bool __setArrayAllocLengthImpl(ref BlkInfo info, size_t newlength, bool isshared
   The block finalizer info is set separately from the array length, as that is
   only needed on the initial setup of the block. No shared is needed, since
   this should only happen when the block is new.
+  If the STRUCTFINAL bit is not set, no finalizer is stored (but if needed the
+  slot is zeroed)
   */
 void __setBlockFinalizerInfo(ref BlkInfo info, const TypeInfo ti) pure nothrow
 {
     if ((info.attr & BlkAttr.APPENDABLE) && info.size >= PAGESIZE)
     {
+        // if the structfinal bit is not set, we don't have a finalizer. But we
+        // should still zero out the finalizer slot.
+        auto context = (info.attr & BlkAttr.STRUCTFINAL) ? cast(void*)ti : null;
+
         // array used size goes at the beginning. We can stuff the typeinfo
         // right after it, as we need to use 16 bytes anyway.
-        auto typeInfo = cast(TypeInfo*)(info.base + size_t.sizeof);
-        *typeInfo = cast() ti;
+        //
+        auto typeInfo = cast(void**)info.base + 1;
+        *typeInfo = context;
+        version (D_LP64) {} else
+        {
+            // zero out the extra padding
+            (cast(size_t*)info.base)[2 .. 4] = 0;
+        }
     }
-    else
+    else if(info.attr & BlkAttr.STRUCTFINAL)
     {
         // all other cases the typeinfo gets put at the end of the block
-        auto typeInfo = cast(TypeInfo*)(info.base + info.size - size_t.sizeof);
-        *typeInfo = cast() ti;
+        auto typeInfo = cast(void**)(info.base + info.size) - 1;
+        *typeInfo = cast(void*) ti;
     }
 }
 
+/**
+  Get the finalizer info from the block (typeinfo).
+  Must be called on a block with STRUCTFINAL set.
+  */
+const(TypeInfo) __getBlockFinalizerInfo(ref BlkInfo info) pure nothrow
+{
+    bool isLargeArray = (info.attr & BlkAttr.APPENDABLE) && info.size >= PAGESIZE;
+    auto typeInfo = isLargeArray ?
+        info.base + size_t.sizeof :
+        info.base + info.size - size_t.sizeof;
+    return *cast(TypeInfo*)typeInfo;
+}
+
 /**
   get the used size of the array for the given block
   */
@@ -251,3 +275,34 @@ size_t __arrayPad(size_t size, const TypeInfo tinext) nothrow pure @trusted
 {
     return size > MAXMEDSIZE ? LARGEPAD : ((size > MAXSMALLSIZE ? MEDPAD : SMALLPAD) + structTypeInfoSize(tinext));
 }
+
+/**
+  get the padding required to allocate size bytes, use the bits to determine
+  which metadata must be stored.
+  */
+size_t __allocPad(size_t size, uint bits) nothrow pure @trusted
+{
+    auto finalizerSize = (bits & BlkAttr.STRUCTFINAL) ? (void*).sizeof : 0;
+    if (bits & BlkAttr.APPENDABLE)
+    {
+        if (size > MAXMEDSIZE - finalizerSize)
+            return LARGEPAD;
+        auto pad = (size > MAXSMALLSIZE - finalizerSize) ? MEDPAD : SMALLPAD;
+        return pad + finalizerSize;
+    }
+
+    return finalizerSize;
+}
+
+/**
+ * Get the start of the array for the given block.
+ *
+ * Params:
+ *  info = array metadata
+ * Returns:
+ *  pointer to the start of the array
+ */
+void *__arrayStart()(return scope BlkInfo info) nothrow pure
+{
+    return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0);
+}
index 40e361c50f1ce4e8ac5c3ef4f68798414ca68397..b5d9802db3f04c8241cf5096d21d06d6fd398577 100644 (file)
@@ -475,23 +475,39 @@ class ConservativeGC : GC
      */
     void *malloc(size_t size, uint bits = 0, const TypeInfo ti = null) nothrow
     {
-        if (!size)
+        import core.internal.gc.blockmeta;
+
+        if (size == 0)
+        {
+            return null;
+        }
+
+        adjustAttrs(bits, ti);
+
+        immutable padding = __allocPad(size, bits);
+
+        bool overflow;
+        import core.checkedint : addu;
+        immutable needed = addu(size, padding, overflow);
+        if (overflow)
         {
             return null;
         }
 
         size_t localAllocSize = void;
 
-        auto p = runLocked!(mallocNoSync, mallocTime, numMallocs)(size, bits, localAllocSize, ti);
+        auto p = runLocked!(mallocNoSync, mallocTime, numMallocs)(needed, bits, localAllocSize, ti);
 
         invalidate(p[0 .. localAllocSize], 0xF0, true);
 
+        auto ret = setupMetadata(p[0 .. localAllocSize], bits, padding, size, ti);
+
         if (!(bits & BlkAttr.NO_SCAN))
         {
-            memset(p + size, 0, localAllocSize - size);
+            memset(ret.ptr + size, 0, ret.length - size);
         }
 
-        return p;
+        return ret.ptr;
     }
 
 
@@ -527,6 +543,8 @@ class ConservativeGC : GC
 
     BlkInfo qalloc( size_t size, uint bits, const scope TypeInfo ti) nothrow
     {
+        // qalloc should not be used for building metadata-containing blocks,
+        // so avoid all the checking for bits and array padding.
 
         if (!size)
         {
@@ -564,25 +582,45 @@ class ConservativeGC : GC
      */
     void *calloc(size_t size, uint bits = 0, const TypeInfo ti = null) nothrow
     {
+        import core.internal.gc.blockmeta;
+
         if (!size)
         {
             return null;
         }
 
+        adjustAttrs(bits, ti);
+
+        immutable padding = __allocPad(size, bits);
+        bool overflow;
+        import core.checkedint : addu;
+        immutable needed = addu(size, padding, overflow);
+        if (overflow)
+        {
+            return null;
+        }
+
+
         size_t localAllocSize = void;
 
-        auto p = runLocked!(mallocNoSync, mallocTime, numMallocs)(size, bits, localAllocSize, ti);
+        auto p = runLocked!(mallocNoSync, mallocTime, numMallocs)(needed, bits, localAllocSize, ti);
 
         debug (VALGRIND) makeMemUndefined(p[0..size]);
-        invalidate((p + size)[0 .. localAllocSize - size], 0xF0, true);
 
-        memset(p, 0, size);
-        if (!(bits & BlkAttr.NO_SCAN))
+        auto ret = setupMetadata(p[0 .. localAllocSize], bits, padding, size, ti);
+
+        invalidate((ret.ptr + size)[0 .. ret.length - size], 0xF0, true);
+
+        if (bits & BlkAttr.NO_SCAN)
         {
-            memset(p + size, 0, localAllocSize - size);
+            memset(ret.ptr, 0, size);
+        }
+        else
+        {
+            memset(ret.ptr, 0, ret.length);
         }
 
-        return p;
+        return ret.ptr;
     }
 
     /**
@@ -595,7 +633,8 @@ class ConservativeGC : GC
      * Params:
      *  p = A pointer to the root of a valid memory block or to null.
      *  size = The desired allocation size in bytes.
-     *  bits = A bitmask of the attributes to set on this block.
+     *  bits = A bitmask of the attributes to set on this block. APPENDABLE and
+     *         FINALIZE are not allowed for realloc.
      *  ti = TypeInfo to describe the memory.
      *
      * Returns:
@@ -607,14 +646,28 @@ class ConservativeGC : GC
      */
     void *realloc(void *p, size_t size, uint bits = 0, const TypeInfo ti = null) nothrow
     {
+        if (bits & (BlkAttr.APPENDABLE | BlkAttr.FINALIZE))
+            // these bits are not allowed. We can't properly manage
+            // reallocation of such blocks.
+            onInvalidMemoryOperationError();
+
         size_t localAllocSize = void;
         auto oldp = p;
 
         p = runLocked!(reallocNoSync, mallocTime, numMallocs)(p, size, bits, localAllocSize, ti);
 
-        if (p && !(bits & BlkAttr.NO_SCAN))
+        if (p)
         {
-            memset(p + size, 0, localAllocSize - size);
+            // invalidate any block info cache we have for the old allocation.
+            import core.internal.gc.blkcache;
+            if (auto bic = __getBlkInfo(oldp)) {
+                *bic = BlkInfo.init;
+            }
+
+            if (!(bits & BlkAttr.NO_SCAN))
+            {
+                memset(p + size, 0, localAllocSize - size);
+            }
         }
 
         return p;
@@ -662,7 +715,8 @@ class ConservativeGC : GC
         void* doMalloc()
         {
             if (!bits)
-                bits = pool.getBits(biti);
+                bits = pool.getBits(biti) &
+                    ~(BlkAttr.APPENDABLE | BlkAttr.FINALIZE | BlkAttr.STRUCTFINAL);
 
             void* p2 = mallocNoSync(size, bits, alloc_size, ti);
             debug (SENTINEL)
@@ -759,7 +813,16 @@ class ConservativeGC : GC
 
     size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow
     {
-        return runLocked!(extendNoSync, extendTime, numExtends)(p, minsize, maxsize, ti);
+        auto result = runLocked!(extendNoSync, extendTime, numExtends)(p, minsize, maxsize, ti);
+        if (result != 0) {
+            // invalidate any block info cache we have for the old allocation.
+            import core.internal.gc.blkcache;
+            if (auto bic = __getBlkInfo(p)) {
+                *bic = BlkInfo.init;
+            }
+        }
+
+        return result;
     }
 
 
@@ -867,14 +930,22 @@ class ConservativeGC : GC
             return;
         }
 
-        return runLocked!(freeNoSync, freeTime, numFrees)(p);
+        auto didFree = runLocked!(freeNoSync, freeTime, numFrees)(p);
+
+        if (didFree) {
+            // invalidate any block info cache we have for the old allocation.
+            import core.internal.gc.blkcache;
+            if (auto bic = __getBlkInfo(p)) {
+                *bic = BlkInfo.init;
+            }
+        }
     }
 
 
     //
     // Implementation of free.
     //
-    private void freeNoSync(void *p) nothrow @nogc
+    private bool freeNoSync(void *p) nothrow @nogc
     {
         debug(PRINTF) printf("Freeing %#zx\n", cast(size_t) p);
         assert (p);
@@ -887,7 +958,7 @@ class ConservativeGC : GC
         // Find which page it is in
         pool = gcx.findPool(p);
         if (!pool)                              // if not one of ours
-            return;                             // ignore
+            return false;                       // ignore
 
         pagenum = pool.pagenumOf(p);
 
@@ -899,11 +970,11 @@ class ConservativeGC : GC
         // Verify that the pointer is at the beginning of a block,
         //  no action should be taken if p is an interior pointer
         if (bin > Bins.B_PAGE) // B_PAGEPLUS or B_FREE
-            return;
+            return false;
         size_t off = (sentinel_sub(p) - pool.baseAddr);
         size_t base = baseOffset(off, bin);
         if (off != base)
-            return;
+            return false;
 
         sentinel_Invariant(p);
         auto q = p;
@@ -928,7 +999,7 @@ class ConservativeGC : GC
         {
             biti = cast(size_t)(p - pool.baseAddr) >> pool.ShiftBy.Small;
             if (pool.freebits.test (biti))
-                return;
+                return false;
             // Add to free list
             List *list = cast(List*)p;
 
@@ -948,6 +1019,8 @@ class ConservativeGC : GC
         pool.clrBits(biti, ~BlkAttr.NONE);
 
         gcx.leakDetector.log_free(sentinel_add(p), ssize);
+
+        return true;
     }
 
 
@@ -5325,3 +5398,42 @@ void undefinedWrite(T)(ref T var, T value) nothrow
     else
         var = value;
 }
+
+private void adjustAttrs(ref uint attrs, const TypeInfo ti) nothrow
+{
+    bool hasContext = ti !is null;
+    if((attrs & BlkAttr.FINALIZE) && hasContext && typeid(ti) is typeid(TypeInfo_Struct))
+        attrs |= BlkAttr.STRUCTFINAL;
+    else
+        // STRUCTFINAL now just means "has a context pointer added to the block"
+        attrs &= ~BlkAttr.STRUCTFINAL;
+}
+
+// sets up the array/context pointer metadata based on the block allocated.
+// This is called on any block *creation*, and not on updating the array
+// metadata.
+//
+// The return value is the true data that the user can use.
+private void[] setupMetadata(void[] block, uint bits, size_t padding, size_t used, const TypeInfo ti) nothrow
+{
+    import core.internal.gc.blockmeta;
+    import core.internal.array.utils;
+
+    BlkInfo info = BlkInfo(
+            base: block.ptr,
+            attr: bits,
+            size: block.length
+    );
+
+
+    __setBlockFinalizerInfo(info, ti);
+
+    if (bits & BlkAttr.APPENDABLE) {
+        auto typeInfoSize = (bits & BlkAttr.STRUCTFINAL) ? (void*).sizeof : 0;
+        auto success = __setArrayAllocLengthImpl(info, used, false, size_t.max, typeInfoSize);
+        assert(success);
+        return __arrayStart(info)[0 .. block.length - padding];
+    }
+
+    return block.ptr[0 .. block.length - padding];
+}
index 84ffdde7a2cbdb45802778cf324aa31922962665..695f9bc84e74cc8a8a88a501d0dde43cebc3e8fa 100644 (file)
@@ -2348,7 +2348,7 @@ pure nothrow @nogc @system unittest
 
 debug(PRINTF)
 {
-    import core.stdc.stdio;
+    import core.stdc.stdio : printf;
 }
 
 /// Implementation of `_d_delstruct` and `_d_delstructTrace`
index 63a3c2e04c8035bb30f4df23adf94001cf599173..3b3cb8e6a66f002d6895e75422dc5a0188dd1b8a 100644 (file)
@@ -1167,7 +1167,7 @@ extern (C) private @system @nogc nothrow
 {
     ref int fakePureErrnoImpl()
     {
-        import core.stdc.errno;
+        import core.stdc.errno : errno;
         return errno();
     }
 }
index dc765e7ecadfe7220ba76fb068552b34ccd845eb..ff1df7ffad13bfd42bfbf1f0014b0180a5f39eec 100644 (file)
@@ -669,7 +669,7 @@ extern (C) UnitTestResult runModuleUnitTests()
                 if (moduleName.length && e.file.length > moduleName.length
                     && e.file[0 .. moduleName.length] == moduleName)
                 {
-                    import core.stdc.stdio;
+                    import core.stdc.stdio : printf;
                     printf("%.*s(%llu): [unittest] %.*s\n",
                         cast(int) e.file.length, e.file.ptr, cast(ulong) e.line,
                         cast(int) e.message.length, e.message.ptr);
@@ -798,7 +798,7 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) // @nogc
 unittest
 {
     import core.runtime;
-    import core.stdc.stdio;
+    import core.stdc.stdio : printf;
 
     void main()
     {
index 51ab7b5aa31b33c7bad0ed86c55a4f01c30eeb93..3acee7a7f4562e46be0723c3462667d18fff6858 100644 (file)
@@ -35,7 +35,7 @@ version (Windows)
 }
 else version (Posix)
 {
-    import core.stdc.errno;
+    import core.stdc.errno : EAGAIN, ETIMEDOUT;
     import core.sync.config;
     import core.sys.posix.pthread : pthread_cond_broadcast, pthread_cond_destroy, pthread_cond_init,
         pthread_cond_signal, pthread_cond_t, pthread_cond_timedwait, pthread_cond_wait;
index a4dae042ee3b73d456f93847c20b0d313cec51ef..44465669b7e75a8b86f320e40c6551cfea3a85a0 100644 (file)
@@ -37,7 +37,7 @@ version (Windows)
 }
 else version (Darwin)
 {
-    import core.stdc.errno;
+    import core.stdc.errno : EINTR, errno;
     import core.sync.config;
     import core.sys.darwin.mach.kern_return : KERN_ABORTED, KERN_OPERATION_TIMED_OUT;
     import core.sys.darwin.mach.semaphore : mach_task_self, mach_timespec_t, semaphore_create, semaphore_destroy,
@@ -45,7 +45,7 @@ else version (Darwin)
 }
 else version (Posix)
 {
-    import core.stdc.errno;
+    import core.stdc.errno : EAGAIN, EINTR, errno, ETIMEDOUT;
     import core.sync.config;
     import core.sys.posix.semaphore : sem_destroy, sem_init, sem_post, sem_t, sem_timedwait, sem_trywait, sem_wait;
     import core.sys.posix.time : clock_gettime, CLOCK_REALTIME, timespec;
index e0a0c99514cb8284016a87941a6c282d825de0bd..0ad072974d5c527a6f7b09feb1318eb57ddc9e69 100644 (file)
@@ -516,8 +516,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 0U) & 1U));
         }
 
-        enum ulong disabled_min = cast(ulong) 0U;
-        enum ulong disabled_max = cast(ulong) 1U;
+        enum ulong disabled_min = 0UL;
+        enum ulong disabled_max = 1UL;
         ///
         @property ulong inherit() @safe pure nothrow @nogc const
         {
@@ -536,8 +536,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 1U) & 2U));
         }
 
-        enum ulong inherit_min = cast(ulong) 0U;
-        enum ulong inherit_max = cast(ulong) 1U;
+        enum ulong inherit_min = 0UL;
+        enum ulong inherit_max = 1UL;
         ///
         @property ulong pinned() @safe pure nothrow @nogc const
         {
@@ -556,8 +556,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 2U) & 4U));
         }
 
-        enum ulong pinned_min = cast(ulong) 0U;
-        enum ulong pinned_max = cast(ulong) 1U;
+        enum ulong pinned_min = 0UL;
+        enum ulong pinned_max = 1UL;
         ///
         @property ulong exclusive() @safe pure nothrow @nogc const
         {
@@ -576,8 +576,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 3U) & 8U));
         }
 
-        enum ulong exclusive_min = cast(ulong) 0U;
-        enum ulong exclusive_max = cast(ulong) 1U;
+        enum ulong exclusive_min = 0UL;
+        enum ulong exclusive_max = 1UL;
         ///
         @property ulong exclude_user() @safe pure nothrow @nogc const
         {
@@ -596,8 +596,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 4U) & 16U));
         }
 
-        enum ulong exclude_user_min = cast(ulong) 0U;
-        enum ulong exclude_user_max = cast(ulong) 1U;
+        enum ulong exclude_user_min = 0UL;
+        enum ulong exclude_user_max = 1UL;
         ///
         @property ulong exclude_kernel() @safe pure nothrow @nogc const
         {
@@ -616,8 +616,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 5U) & 32U));
         }
 
-        enum ulong exclude_kernel_min = cast(ulong) 0U;
-        enum ulong exclude_kernel_max = cast(ulong) 1U;
+        enum ulong exclude_kernel_min = 0UL;
+        enum ulong exclude_kernel_max = 1UL;
         ///
         @property ulong exclude_hv() @safe pure nothrow @nogc const
         {
@@ -636,8 +636,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 6U) & 64U));
         }
 
-        enum ulong exclude_hv_min = cast(ulong) 0U;
-        enum ulong exclude_hv_max = cast(ulong) 1U;
+        enum ulong exclude_hv_min = 0UL;
+        enum ulong exclude_hv_max = 1UL;
         ///
         @property ulong exclude_idle() @safe pure nothrow @nogc const
         {
@@ -656,8 +656,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 7U) & 128U));
         }
 
-        enum ulong exclude_idle_min = cast(ulong) 0U;
-        enum ulong exclude_idle_max = cast(ulong) 1U;
+        enum ulong exclude_idle_min = 0UL;
+        enum ulong exclude_idle_max = 1UL;
         ///
         @property ulong mmap() @safe pure nothrow @nogc const
         {
@@ -674,8 +674,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 8U) & 256U));
         }
 
-        enum ulong mmap_min = cast(ulong) 0U;
-        enum ulong mmap_max = cast(ulong) 1U;
+        enum ulong mmap_min = 0UL;
+        enum ulong mmap_max = 1UL;
         ///
         @property ulong comm() @safe pure nothrow @nogc const
         {
@@ -692,8 +692,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 9U) & 512U));
         }
 
-        enum ulong comm_min = cast(ulong) 0U;
-        enum ulong comm_max = cast(ulong) 1U;
+        enum ulong comm_min = 0UL;
+        enum ulong comm_max = 1UL;
         ///
         @property ulong freq() @safe pure nothrow @nogc const
         {
@@ -710,8 +710,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 10U) & 1024U));
         }
 
-        enum ulong freq_min = cast(ulong) 0U;
-        enum ulong freq_max = cast(ulong) 1U;
+        enum ulong freq_min = 0UL;
+        enum ulong freq_max = 1UL;
         ///
         @property ulong inherit_stat() @safe pure nothrow @nogc const
         {
@@ -730,8 +730,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 11U) & 2048U));
         }
 
-        enum ulong inherit_stat_min = cast(ulong) 0U;
-        enum ulong inherit_stat_max = cast(ulong) 1U;
+        enum ulong inherit_stat_min = 0UL;
+        enum ulong inherit_stat_max = 1UL;
         ///
         @property ulong enable_on_exec() @safe pure nothrow @nogc const
         {
@@ -750,8 +750,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 12U) & 4096U));
         }
 
-        enum ulong enable_on_exec_min = cast(ulong) 0U;
-        enum ulong enable_on_exec_max = cast(ulong) 1U;
+        enum ulong enable_on_exec_min = 0UL;
+        enum ulong enable_on_exec_max = 1UL;
         ///
         @property ulong task() @safe pure nothrow @nogc const
         {
@@ -768,8 +768,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 13U) & 8192U));
         }
 
-        enum ulong task_min = cast(ulong) 0U;
-        enum ulong task_max = cast(ulong) 1U;
+        enum ulong task_min = 0UL;
+        enum ulong task_max = 1UL;
         ///
         @property ulong watermark() @safe pure nothrow @nogc const
         {
@@ -788,8 +788,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 14U) & 16384U));
         }
 
-        enum ulong watermark_min = cast(ulong) 0U;
-        enum ulong watermark_max = cast(ulong) 1U;
+        enum ulong watermark_min = 0UL;
+        enum ulong watermark_max = 1UL;
         ///
         @property ulong precise_ip() @safe pure nothrow @nogc const
         {
@@ -808,8 +808,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 15U) & 98304U));
         }
 
-        enum ulong precise_ip_min = cast(ulong) 0U;
-        enum ulong precise_ip_max = cast(ulong) 3U;
+        enum ulong precise_ip_min = 0UL;
+        enum ulong precise_ip_max = 3UL;
         ///
         @property ulong mmap_data() @safe pure nothrow @nogc const
         {
@@ -828,8 +828,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 17U) & 131072U));
         }
 
-        enum ulong mmap_data_min = cast(ulong) 0U;
-        enum ulong mmap_data_max = cast(ulong) 1U;
+        enum ulong mmap_data_min = 0UL;
+        enum ulong mmap_data_max = 1UL;
         ///
         @property ulong sample_id_all() @safe pure nothrow @nogc const
         {
@@ -848,8 +848,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 18U) & 262144U));
         }
 
-        enum ulong sample_id_all_min = cast(ulong) 0U;
-        enum ulong sample_id_all_max = cast(ulong) 1U;
+        enum ulong sample_id_all_min = 0UL;
+        enum ulong sample_id_all_max = 1UL;
         ///
         @property ulong exclude_host() @safe pure nothrow @nogc const
         {
@@ -868,8 +868,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 19U) & 524288U));
         }
 
-        enum ulong exclude_host_min = cast(ulong) 0U;
-        enum ulong exclude_host_max = cast(ulong) 1U;
+        enum ulong exclude_host_min = 0UL;
+        enum ulong exclude_host_max = 1UL;
         ///
         @property ulong exclude_guest() @safe pure nothrow @nogc const
         {
@@ -888,8 +888,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 20U) & 1048576U));
         }
 
-        enum ulong exclude_guest_min = cast(ulong) 0U;
-        enum ulong exclude_guest_max = cast(ulong) 1U;
+        enum ulong exclude_guest_min = 0UL;
+        enum ulong exclude_guest_max = 1UL;
         ///
         @property ulong exclude_callchain_kernel() @safe pure nothrow @nogc const
         {
@@ -908,8 +908,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 21U) & 2097152U));
         }
 
-        enum ulong exclude_callchain_kernel_min = cast(ulong) 0U;
-        enum ulong exclude_callchain_kernel_max = cast(ulong) 1U;
+        enum ulong exclude_callchain_kernel_min = 0UL;
+        enum ulong exclude_callchain_kernel_max = 1UL;
         ///
         @property ulong exclude_callchain_user() @safe pure nothrow @nogc const
         {
@@ -928,8 +928,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 22U) & 4194304U));
         }
 
-        enum ulong exclude_callchain_user_min = cast(ulong) 0U;
-        enum ulong exclude_callchain_user_max = cast(ulong) 1U;
+        enum ulong exclude_callchain_user_min = 0UL;
+        enum ulong exclude_callchain_user_max = 1UL;
         ///
         @property ulong mmap2() @safe pure nothrow @nogc const
         {
@@ -948,8 +948,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 23U) & 8388608U));
         }
 
-        enum ulong mmap2_min = cast(ulong) 0U;
-        enum ulong mmap2_max = cast(ulong) 1U;
+        enum ulong mmap2_min = 0UL;
+        enum ulong mmap2_max = 1UL;
         ///
         @property ulong comm_exec() @safe pure nothrow @nogc const
         {
@@ -968,8 +968,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 24U) & 16777216U));
         }
 
-        enum ulong comm_exec_min = cast(ulong) 0U;
-        enum ulong comm_exec_max = cast(ulong) 1U;
+        enum ulong comm_exec_min = 0UL;
+        enum ulong comm_exec_max = 1UL;
         ///
         @property ulong use_clockid() @safe pure nothrow @nogc const
         {
@@ -988,8 +988,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 25U) & 33554432U));
         }
 
-        enum ulong use_clockid_min = cast(ulong) 0U;
-        enum ulong use_clockid_max = cast(ulong) 1U;
+        enum ulong use_clockid_min = 0UL;
+        enum ulong use_clockid_max = 1UL;
         ///
         @property ulong context_switch() @safe pure nothrow @nogc const
         {
@@ -1008,8 +1008,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 26U) & 67108864U));
         }
 
-        enum ulong context_switch_min = cast(ulong) 0U;
-        enum ulong context_switch_max = cast(ulong) 1U;
+        enum ulong context_switch_min = 0UL;
+        enum ulong context_switch_max = 1UL;
         ///
         @property ulong write_backward() @safe pure nothrow @nogc const
         {
@@ -1028,8 +1028,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 27U) & 134217728U));
         }
 
-        enum ulong write_backward_min = cast(ulong) 0U;
-        enum ulong write_backward_max = cast(ulong) 1U;
+        enum ulong write_backward_min = 0UL;
+        enum ulong write_backward_max = 1UL;
         ///
         @property ulong namespaces() @safe pure nothrow @nogc const
         {
@@ -1048,8 +1048,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 28U) & 268435456U));
         }
 
-        enum ulong namespaces_min = cast(ulong) 0U;
-        enum ulong namespaces_max = cast(ulong) 1U;
+        enum ulong namespaces_min = 0UL;
+        enum ulong namespaces_max = 1UL;
         ///
         @property ulong __reserved_1() @safe pure nothrow @nogc const
         {
@@ -1069,8 +1069,8 @@ struct perf_event_attr
                                 (cast(typeof(perf_event_attr_bitmanip)) v << 29U) & 18446744073172680704UL));
         }
 
-        enum ulong __reserved_1_min = cast(ulong) 0U;
-        enum ulong __reserved_1_max = cast(ulong) 34359738367UL;
+        enum ulong __reserved_1_min = 0UL;
+        enum ulong __reserved_1_max = 34359738367UL;
         ///
         union
         {
@@ -1242,8 +1242,8 @@ struct perf_event_mmap_page
                                                 (cast(typeof(mmap_page_bitmanip)) v << 0U) & 1U));
                         }
 
-                        enum ulong cap_bit0_min = cast(ulong) 0U;
-                        enum ulong cap_bit0_max = cast(ulong) 1U;
+                        enum ulong cap_bit0_min = 0UL;
+                        enum ulong cap_bit0_max = 1UL;
                         ///
                         @property ulong cap_bit0_is_deprecated() @safe pure nothrow @nogc const
                         {
@@ -1262,8 +1262,8 @@ struct perf_event_mmap_page
                                                 (cast(typeof(mmap_page_bitmanip)) v << 1U) & 2U));
                         }
 
-                        enum ulong cap_bit0_is_deprecated_min = cast(ulong) 0U;
-                        enum ulong cap_bit0_is_deprecated_max = cast(ulong) 1U;
+                        enum ulong cap_bit0_is_deprecated_min = 0UL;
+                        enum ulong cap_bit0_is_deprecated_max = 1UL;
                         ///
                         @property ulong cap_user_rdpmc() @safe pure nothrow @nogc const
                         {
@@ -1282,8 +1282,8 @@ struct perf_event_mmap_page
                                                 (cast(typeof(mmap_page_bitmanip)) v << 2U) & 4U));
                         }
 
-                        enum ulong cap_user_rdpmc_min = cast(ulong) 0U;
-                        enum ulong cap_user_rdpmc_max = cast(ulong) 1U;
+                        enum ulong cap_user_rdpmc_min = 0UL;
+                        enum ulong cap_user_rdpmc_max = 1UL;
                         ///
                         @property ulong cap_user_time() @safe pure nothrow @nogc const
                         {
@@ -1302,8 +1302,8 @@ struct perf_event_mmap_page
                                                 (cast(typeof(mmap_page_bitmanip)) v << 3U) & 8U));
                         }
 
-                        enum ulong cap_user_time_min = cast(ulong) 0U;
-                        enum ulong cap_user_time_max = cast(ulong) 1U;
+                        enum ulong cap_user_time_min = 0UL;
+                        enum ulong cap_user_time_max = 1UL;
                         ///
                         @property ulong cap_user_time_zero() @safe pure nothrow @nogc const
                         {
@@ -1322,8 +1322,8 @@ struct perf_event_mmap_page
                                                 (cast(typeof(mmap_page_bitmanip)) v << 4U) & 16U));
                         }
 
-                        enum ulong cap_user_time_zero_min = cast(ulong) 0U;
-                        enum ulong cap_user_time_zero_max = cast(ulong) 1U;
+                        enum ulong cap_user_time_zero_min = 0UL;
+                        enum ulong cap_user_time_zero_max = 1UL;
                         ///
                         @property ulong cap_____res() @safe pure nothrow @nogc const
                         {
@@ -1342,8 +1342,8 @@ struct perf_event_mmap_page
                                                 (cast(typeof(mmap_page_bitmanip)) v << 5U) & 18446744073709551584UL));
                         }
 
-                        enum ulong cap_____res_min = cast(ulong) 0U;
-                        enum ulong cap_____res_max = cast(ulong) 576460752303423487UL;
+                        enum ulong cap_____res_min = 0UL;
+                        enum ulong cap_____res_max = 576460752303423487UL;
                 }
         }
 
@@ -1891,8 +1891,8 @@ version (LittleEndian)
                                                 (cast(typeof(perf_mem_data_src_bitmanip)) v << 0U) & 31U));
                         }
 
-                        enum ulong mem_op_min = cast(ulong) 0U;
-                        enum ulong mem_op_max = cast(ulong) 31U;
+                        enum ulong mem_op_min = 0UL;
+                        enum ulong mem_op_max = 31UL;
                         ///
                         @property ulong mem_lvl() @safe pure nothrow @nogc const
                         {
@@ -1912,8 +1912,8 @@ version (LittleEndian)
                                                 (cast(typeof(perf_mem_data_src_bitmanip)) v << 5U) & 524256U));
                         }
 
-                        enum ulong mem_lvl_min = cast(ulong) 0U;
-                        enum ulong mem_lvl_max = cast(ulong) 16383U;
+                        enum ulong mem_lvl_min = 0UL;
+                        enum ulong mem_lvl_max = 16383UL;
                         ///
                         @property ulong mem_snoop() @safe pure nothrow @nogc const
                         {
@@ -1933,8 +1933,8 @@ version (LittleEndian)
                                                 (cast(typeof(perf_mem_data_src_bitmanip)) v << 19U) & 16252928U));
                         }
 
-                        enum ulong mem_snoop_min = cast(ulong) 0U;
-                        enum ulong mem_snoop_max = cast(ulong) 31U;
+                        enum ulong mem_snoop_min = 0UL;
+                        enum ulong mem_snoop_max = 31UL;
                         ///
                         @property ulong mem_lock() @safe pure nothrow @nogc const
                         {
@@ -1954,8 +1954,8 @@ version (LittleEndian)
                                                 (cast(typeof(perf_mem_data_src_bitmanip)) v << 24U) & 50331648U));
                         }
 
-                        enum ulong mem_lock_min = cast(ulong) 0U;
-                        enum ulong mem_lock_max = cast(ulong) 3U;
+                        enum ulong mem_lock_min = 0UL;
+                        enum ulong mem_lock_max = 3UL;
                         ///
                         @property ulong mem_dtlb() @safe pure nothrow @nogc const
                         {
@@ -1975,8 +1975,8 @@ version (LittleEndian)
                                                 (cast(typeof(perf_mem_data_src_bitmanip)) v << 26U) & 8522825728UL));
                         }
 
-                        enum ulong mem_dtlb_min = cast(ulong) 0U;
-                        enum ulong mem_dtlb_max = cast(ulong) 127U;
+                        enum ulong mem_dtlb_min = 0UL;
+                        enum ulong mem_dtlb_max = 127UL;
                         ///
                         @property ulong mem_lvl_num() @safe pure nothrow @nogc const
                         {
@@ -1996,8 +1996,8 @@ version (LittleEndian)
                                                 (cast(typeof(perf_mem_data_src_bitmanip)) v << 33U) & 128849018880UL));
                         }
 
-                        enum ulong mem_lvl_num_min = cast(ulong) 0U;
-                        enum ulong mem_lvl_num_max = cast(ulong) 15U;
+                        enum ulong mem_lvl_num_min = 0UL;
+                        enum ulong mem_lvl_num_max = 15UL;
                         ///
                         @property ulong mem_remote() @safe pure nothrow @nogc const
                         {
@@ -2017,8 +2017,8 @@ version (LittleEndian)
                                                 (cast(typeof(perf_mem_data_src_bitmanip)) v << 37U) & 137438953472UL));
                         }
 
-                        enum ulong mem_remote_min = cast(ulong) 0U;
-                        enum ulong mem_remote_max = cast(ulong) 1U;
+                        enum ulong mem_remote_min = 0UL;
+                        enum ulong mem_remote_max = 1UL;
                         ///
                         @property ulong mem_snoopx() @safe pure nothrow @nogc const
                         {
@@ -2038,8 +2038,8 @@ version (LittleEndian)
                                                 (cast(typeof(perf_mem_data_src_bitmanip)) v << 38U) & 824633720832UL));
                         }
 
-                        enum ulong mem_snoopx_min = cast(ulong) 0U;
-                        enum ulong mem_snoopx_max = cast(ulong) 3U;
+                        enum ulong mem_snoopx_min = 0UL;
+                        enum ulong mem_snoopx_max = 3UL;
                         ///
                         @property ulong mem_rsvd() @safe pure nothrow @nogc const
                         {
@@ -2060,8 +2060,8 @@ version (LittleEndian)
                                                 (cast(typeof(perf_mem_data_src_bitmanip)) v << 40U) & 18446742974197923840UL));
                         }
 
-                        enum ulong mem_rsvd_min = cast(ulong) 0U;
-                        enum ulong mem_rsvd_max = cast(ulong) 16777215U;
+                        enum ulong mem_rsvd_min = 0UL;
+                        enum ulong mem_rsvd_max = 16777215UL;
 
                 }
         }
@@ -2099,8 +2099,8 @@ else
                                                 (cast(typeof(perf_mem_data_src)) v << 0U) & 16777215U));
                         }
 
-                        enum ulong mem_rsvd_min = cast(ulong) 0U;
-                        enum ulong mem_rsvd_max = cast(ulong) 16777215U;
+                        enum ulong mem_rsvd_min = 0UL;
+                        enum ulong mem_rsvd_max = 16777215UL;
                         ///
                         @property ulong mem_snoopx() @safe pure nothrow @nogc const
                         {
@@ -2119,8 +2119,8 @@ else
                                                 (cast(typeof(perf_mem_data_src)) v << 24U) & 50331648U));
                         }
 
-                        enum ulong mem_snoopx_min = cast(ulong) 0U;
-                        enum ulong mem_snoopx_max = cast(ulong) 3U;
+                        enum ulong mem_snoopx_min = 0UL;
+                        enum ulong mem_snoopx_max = 3UL;
                         ///
                         @property ulong mem_remote() @safe pure nothrow @nogc const
                         {
@@ -2139,8 +2139,8 @@ else
                                                 (cast(typeof(perf_mem_data_src)) v << 26U) & 67108864U));
                         }
 
-                        enum ulong mem_remote_min = cast(ulong) 0U;
-                        enum ulong mem_remote_max = cast(ulong) 1U;
+                        enum ulong mem_remote_min = 0UL;
+                        enum ulong mem_remote_max = 1UL;
                         ///
                         @property ulong mem_lvl_num() @safe pure nothrow @nogc const
                         {
@@ -2159,8 +2159,8 @@ else
                                                 (cast(typeof(perf_mem_data_src)) v << 27U) & 2013265920U));
                         }
 
-                        enum ulong mem_lvl_num_min = cast(ulong) 0U;
-                        enum ulong mem_lvl_num_max = cast(ulong) 15U;
+                        enum ulong mem_lvl_num_min = 0UL;
+                        enum ulong mem_lvl_num_max = 15UL;
                         ///
                         @property ulong mem_dtlb() @safe pure nothrow @nogc const
                         {
@@ -2179,8 +2179,8 @@ else
                                                 (cast(typeof(perf_mem_data_src)) v << 31U) & 272730423296UL));
                         }
 
-                        enum ulong mem_dtlb_min = cast(ulong) 0U;
-                        enum ulong mem_dtlb_max = cast(ulong) 127U;
+                        enum ulong mem_dtlb_min = 0UL;
+                        enum ulong mem_dtlb_max = 127UL;
                         ///
                         @property ulong mem_lock() @safe pure nothrow @nogc const
                         {
@@ -2199,8 +2199,8 @@ else
                                                 (cast(typeof(perf_mem_data_src)) v << 38U) & 824633720832UL));
                         }
 
-                        enum ulong mem_lock_min = cast(ulong) 0U;
-                        enum ulong mem_lock_max = cast(ulong) 3U;
+                        enum ulong mem_lock_min = 0UL;
+                        enum ulong mem_lock_max = 3UL;
                         ///
                         @property ulong mem_snoop() @safe pure nothrow @nogc const
                         {
@@ -2219,8 +2219,8 @@ else
                                                 (cast(typeof(perf_mem_data_src)) v << 40U) & 34084860461056UL));
                         }
 
-                        enum ulong mem_snoop_min = cast(ulong) 0U;
-                        enum ulong mem_snoop_max = cast(ulong) 31U;
+                        enum ulong mem_snoop_min = 0UL;
+                        enum ulong mem_snoop_max = 31UL;
                         ///
                         @property ulong mem_lvl() @safe pure nothrow @nogc const
                         {
@@ -2239,8 +2239,8 @@ else
                                                 (cast(typeof(perf_mem_data_src)) v << 45U) & 576425567931334656UL));
                         }
 
-                        enum ulong mem_lvl_min = cast(ulong) 0U;
-                        enum ulong mem_lvl_max = cast(ulong) 16383U;
+                        enum ulong mem_lvl_min = 0UL;
+                        enum ulong mem_lvl_max = 16383UL;
                         ///
                         @property ulong mem_op() @safe pure nothrow @nogc const
                         {
@@ -2259,8 +2259,8 @@ else
                                                 (cast(typeof(perf_mem_data_src)) v << 59U) & 17870283321406128128UL));
                         }
 
-                        enum ulong mem_op_min = cast(ulong) 0U;
-                        enum ulong mem_op_max = cast(ulong) 31U;
+                        enum ulong mem_op_min = 0UL;
+                        enum ulong mem_op_max = 31UL;
                 }
         }
 }
@@ -2392,8 +2392,8 @@ struct perf_branch_entry
                                 (cast(typeof(perf_branch_entry_bitmanip)) v << 0U) & 1U));
         }
 
-        enum ulong mispred_min = cast(ulong) 0U;
-        enum ulong mispred_max = cast(ulong) 1U;
+        enum ulong mispred_min = 0UL;
+        enum ulong mispred_max = 1UL;
         ///
         @property ulong predicted() @safe pure nothrow @nogc const
         {
@@ -2412,8 +2412,8 @@ struct perf_branch_entry
                                 (cast(typeof(perf_branch_entry_bitmanip)) v << 1U) & 2U));
         }
 
-        enum ulong predicted_min = cast(ulong) 0U;
-        enum ulong predicted_max = cast(ulong) 1U;
+        enum ulong predicted_min = 0UL;
+        enum ulong predicted_max = 1UL;
         ///
         @property ulong in_tx() @safe pure nothrow @nogc const
         {
@@ -2432,8 +2432,8 @@ struct perf_branch_entry
                                 (cast(typeof(perf_branch_entry_bitmanip)) v << 2U) & 4U));
         }
 
-        enum ulong in_tx_min = cast(ulong) 0U;
-        enum ulong in_tx_max = cast(ulong) 1U;
+        enum ulong in_tx_min = 0UL;
+        enum ulong in_tx_max = 1UL;
         ///
         @property ulong abort() @safe pure nothrow @nogc const
         {
@@ -2452,8 +2452,8 @@ struct perf_branch_entry
                                 (cast(typeof(perf_branch_entry_bitmanip)) v << 3U) & 8U));
         }
 
-        enum ulong abort_min = cast(ulong) 0U;
-        enum ulong abort_max = cast(ulong) 1U;
+        enum ulong abort_min = 0UL;
+        enum ulong abort_max = 1UL;
         ///
         @property ulong cycles() @safe pure nothrow @nogc const
         {
@@ -2472,8 +2472,8 @@ struct perf_branch_entry
                                 (cast(typeof(perf_branch_entry_bitmanip)) v << 4U) & 1048560U));
         }
 
-        enum ulong cycles_min = cast(ulong) 0U;
-        enum ulong cycles_max = cast(ulong) 65535U;
+        enum ulong cycles_min = 0UL;
+        enum ulong cycles_max = 65535UL;
         ///
         @property ulong type() @safe pure nothrow @nogc const
         {
@@ -2490,8 +2490,8 @@ struct perf_branch_entry
                                 (cast(typeof(perf_branch_entry_bitmanip)) v << 20U) & 15728640U));
         }
 
-        enum ulong type_min = cast(ulong) 0U;
-        enum ulong type_max = cast(ulong) 15U;
+        enum ulong type_min = 0UL;
+        enum ulong type_max = 15UL;
         ///
         @property ulong reserved() @safe pure nothrow @nogc const
         {
@@ -2511,6 +2511,6 @@ struct perf_branch_entry
                                 (cast(typeof(perf_branch_entry_bitmanip)) v << 24U) & 18446744073692774400UL));
         }
 
-        enum ulong reserved_min = cast(ulong) 0U;
-        enum ulong reserved_max = cast(ulong) 1099511627775UL;
+        enum ulong reserved_min = 0UL;
+        enum ulong reserved_max = 1099511627775UL;
 }
index e5f0cadbbf2d3542b07413859aa637c35fc03e5a..e08e4a113eb4543edd7ec9b81736572bb1f9d31c 100644 (file)
@@ -59,72 +59,11 @@ else version (D_InlineAsm_X86_64)
         version = AsmX86_64_Posix;
     }
 }
-else version (X86)
-{
-    version (CET) {} else
-    {
-        version = AsmExternal;
-    }
-}
-else version (X86_64)
-{
-    version (CET)   {} else
-    version (D_X32) {} else
-    {
-        version = AsmExternal;
-    }
-}
-else version (PPC)
-{
-    version (Posix)
-    {
-        version = AsmExternal;
-    }
-}
-else version (MIPS_O32)
-{
-    version (Posix)
-    {
-        version = AsmExternal;
-    }
-}
-else version (AArch64)
-{
-    version (Posix)
-    {
-        version = AsmExternal;
-    }
-}
-else version (ARM)
-{
-    version (Posix)
-    {
-        version = AsmExternal;
-    }
-}
-
-version (Posix)
-{
-    version (AsmX86_Windows)    {} else
-    version (AsmX86_Posix)      {} else
-    version (AsmX86_64_Windows) {} else
-    version (AsmX86_64_Posix)   {} else
-    version (AsmExternal)       {} else
-    {
-        // NOTE: The ucontext implementation requires architecture specific
-        //       data definitions to operate so testing for it must be done
-        //       by checking for the existence of ucontext_t rather than by
-        //       a version identifier.  Please note that this is considered
-        //       an obsolescent feature according to the POSIX spec, so a
-        //       custom solution is still preferred.
-        static import core.sys.posix.ucontext;
-    }
-}
 
 version (Windows)
 {
     import core.stdc.stdint : uintptr_t; // for _beginthreadex decl below
-    import core.stdc.stdlib;             // for malloc, atexit
+    import core.stdc.stdlib : free, malloc, realloc;
     import core.sys.windows.basetsd /+: HANDLE+/;
     import core.sys.windows.threadaux /+: getThreadStackBottom, impersonate_thread, OpenThreadHandle+/;
     import core.sys.windows.winbase /+: CloseHandle, CREATE_SUSPENDED, DuplicateHandle, GetCurrentThread,
@@ -142,7 +81,7 @@ else version (Posix)
 {
     static import core.sys.posix.pthread;
     static import core.sys.posix.signal;
-    import core.stdc.errno;
+    import core.stdc.errno : EINTR, errno;
     import core.sys.posix.pthread : pthread_atfork, pthread_attr_destroy, pthread_attr_getstack, pthread_attr_init,
         pthread_attr_setstacksize, pthread_create, pthread_detach, pthread_getschedparam, pthread_join, pthread_self,
         pthread_setschedparam, sched_get_priority_max, sched_get_priority_min, sched_param, sched_yield;
@@ -157,9 +96,34 @@ else version (Posix)
     {
         import core.sys.darwin.mach.kern_return : KERN_SUCCESS;
         import core.sys.darwin.mach.port : mach_port_t;
-        import core.sys.darwin.mach.thread_act : mach_msg_type_number_t, thread_get_state, thread_resume,
-            thread_suspend, x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT, x86_thread_state64_t;
+        import core.sys.darwin.mach.thread_act : mach_msg_type_number_t,
+            thread_get_state, thread_resume, thread_suspend;
         import core.sys.darwin.pthread : pthread_mach_thread_np;
+        version (X86)
+        {
+            import core.sys.darwin.mach.thread_act :
+             x86_THREAD_STATE32, x86_THREAD_STATE32_COUNT, x86_thread_state32_t;
+        }
+        else version (X86_64)
+        {
+            import core.sys.darwin.mach.thread_act :
+             x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT, x86_thread_state64_t;
+        }
+        else version (AArch64)
+        {
+            import core.sys.darwin.mach.thread_act :
+             ARM_THREAD_STATE64, ARM_THREAD_STATE64_COUNT, arm_thread_state64_t;
+        }
+        else version (PPC)
+        {
+            import core.sys.darwin.mach.thread_act :
+             PPC_THREAD_STATE32, PPC_THREAD_STATE32_COUNT, ppc_thread_state32_t;
+        }
+        else version (PPC64)
+        {
+            import core.sys.darwin.mach.thread_act :
+             PPC_THREAD_STATE64, PPC_THREAD_STATE64_COUNT, ppc_thread_state64_t;
+        }
     }
 }
 
index 53a0533f25e3b809015df5340446c6c3d882cf3b..8189e67f8af116a1d68a821912475a5656417d97 100644 (file)
@@ -67,8 +67,7 @@ module core.time;
 
 import core.exception;
 import core.internal.string;
-import core.stdc.stdio;
-import core.stdc.time;
+import core.stdc.time : time;
 
 version (OSX)
     version = Darwin;
@@ -94,6 +93,8 @@ else version (Posix)
     import core.sys.posix.time : clock_getres, clock_gettime, CLOCK_MONOTONIC, timespec;
 }
 
+version (unittest) import core.stdc.stdio : printf;
+
 
 //This probably should be moved somewhere else in druntime which
 //is Darwin-specific.
@@ -2700,7 +2701,7 @@ unittest
 
     // It would be too expensive to cover a large range of possible values for
     // ticks, so we use random values in an attempt to get reasonable coverage.
-    import core.stdc.stdlib;
+    import core.stdc.stdlib : rand, srand;
     immutable seed = cast(int)time(null);
     srand(seed);
     scope(failure) printf("seed %d\n", seed);
@@ -2714,7 +2715,7 @@ unittest
     // than or equal to freq5, which at one point was considered for MonoTime's
     // ticksPerSecond rather than using the system's actual clock frequency, so
     // it seemed like a good test case to have.
-    import core.stdc.math;
+    import core.stdc.math : floor, log10, pow;
     immutable numDigitsMinus1 = cast(int)floor(log10(freq5));
     auto freq6 = cast(long)pow(10, numDigitsMinus1);
     if (freq5 > freq6)
index be416c47906a7103da54c377ba18a5b63f2915cb..a1ddba513957bc6e61e0d4a5fd03e1172afc21a2 100644 (file)
@@ -471,6 +471,13 @@ private extern (C) int _d_run_main2(char[][] args, size_t totalArgsLength, MainF
             useExceptionTrap = false;
     }
 
+    version (none)
+    {
+        // Causes test failures related to Fibers, not enabled by default yet
+        import etc.linux.memoryerror;
+        cast(void) registerMemoryAssertHandler();
+    }
+
     void tryExec(scope void delegate() dg)
     {
         if (useExceptionTrap)
@@ -627,10 +634,7 @@ extern (C) void _d_print_throwable(Throwable t)
 
         HANDLE windowsHandle(int fd)
         {
-            version (CRuntime_Microsoft)
-                return cast(HANDLE)_get_osfhandle(fd);
-            else
-                return _fdToHandle(fd);
+            return cast(HANDLE)_get_osfhandle(fd);
         }
 
         // ensure the exception is shown at the beginning of the line, while also
index dbdfcb0b1f06dbfd18391703ef6e3ea2de50ac38..71ed51bf05c0c0095c6e036668dcd90719627694 100644 (file)
 module rt.lifetime;
 
 import core.attribute : weak;
-import core.internal.array.utils : __arrayStart, __arrayClearPad;
 import core.memory;
-import core.internal.gc.blkcache;
-import core.internal.gc.blockmeta;
+import core.internal.gc.blockmeta : PAGESIZE;
 debug(PRINTF) import core.stdc.stdio;
 static import rt.tlsgc;
 
@@ -210,43 +208,22 @@ inout(TypeInfo) unqualify(return scope inout(TypeInfo) cti) pure nothrow @nogc
     return ti;
 }
 
-/**
-  allocate an array memory block by applying the proper padding and
-  assigning block attributes if not inherited from the existing block
-  */
-private BlkInfo __arrayAlloc(size_t arrsize, const scope TypeInfo ti, const TypeInfo tinext) nothrow pure
+private uint __typeAttrs(const scope TypeInfo ti, void *copyAttrsFrom = null) pure nothrow
 {
-    import core.checkedint;
-
-    return __arrayAlloc(arrsize, null, ti, tinext);
-}
-
-private BlkInfo __arrayAlloc(size_t arrsize, void* copyAttrsFrom, const scope TypeInfo ti, const TypeInfo tinext) nothrow pure
-{
-    import core.checkedint;
-
-    immutable padsize = __arrayPad(arrsize, tinext);
-    bool overflow;
-    auto padded_size = addu(arrsize, padsize, overflow);
-    if (overflow)
-    {
-        return BlkInfo();
-    }
-
-    uint attr = (!(tinext.flags & 1) ? BlkAttr.NO_SCAN : 0);
     if (copyAttrsFrom)
     {
         // try to copy attrs from the given block
         auto info = GC.query(copyAttrsFrom);
         if (info.base)
-            attr = info.attr;
+            return info.attr;
     }
-    // always make sure the appendable attr is set.
-    attr |= BlkAttr.APPENDABLE;
-
-    auto bi = GC.qalloc(padded_size, attr, tinext);
-    __arrayClearPad(bi, arrsize, padsize);
-    return bi;
+    uint attrs = !(ti.flags & 1) ? BlkAttr.NO_SCAN : 0;
+    if (typeid(ti) is typeid(TypeInfo_Struct)) {
+        auto sti = cast(TypeInfo_Struct)cast(void*)ti;
+        if (sti.xdtor)
+            attrs |= BlkAttr.STRUCTFINAL | BlkAttr.FINALIZE;
+    }
+    return attrs;
 }
 
 /**
@@ -417,37 +394,38 @@ Lcontinue:
 
     // step 2, if reserving in-place doesn't work, allocate a new array with at
     // least the requested allocated size.
-    auto info = __arrayAlloc(reqsize, (*p).ptr, ti, tinext);
-    if (info.base is null)
+    auto attrs = __typeAttrs(tinext, (*p).ptr) | BlkAttr.APPENDABLE;
+    auto ptr = GC.malloc(reqsize, attrs, tinext);
+    if (ptr is null)
         goto Loverflow;
+
     // copy the data over.
     // note that malloc will have initialized the data we did not request to 0.
-    auto tgt = __arrayStart(info);
-    memcpy(tgt, (*p).ptr, datasize);
+    memcpy(ptr, (*p).ptr, datasize);
 
     // handle postblit
-    __doPostblit(tgt, datasize, tinext);
+    __doPostblit(ptr, datasize, tinext);
 
-    if (!(info.attr & BlkAttr.NO_SCAN))
+    if (!(attrs & BlkAttr.NO_SCAN))
     {
         // need to memset the newly requested data, except for the data that
         // malloc returned that we didn't request.
-        void *endptr = tgt + reqsize;
-        void *begptr = tgt + datasize;
+        void *endptr = ptr + reqsize;
+        void *begptr = ptr + datasize;
 
         // sanity check
         assert(endptr >= begptr);
         memset(begptr, 0, endptr - begptr);
     }
 
-    // set up the correct length
-    __setArrayAllocLength(info, datasize, isshared, tinext);
-    if (!isshared)
-        __insertBlkInfoCache(info, null);
+    *p = ptr[0 .. (*p).length];
 
-    *p = (cast(void*)tgt)[0 .. (*p).length];
+    // set up the correct length. Note that we need to do this here, because
+    // the GC malloc will automatically set the used size to what we requested.
+    gc_shrinkArrayUsed(ptr[0 .. datasize], reqsize, isshared);
 
-    curCapacity = __arrayAllocCapacity(info);
+    curCapacity = gc_reserveArrayCapacity(ptr[0 .. datasize], 0, isshared);
+    assert(curCapacity);
     return curCapacity / size;
 }
 
@@ -509,15 +487,11 @@ Loverflow:
     assert(0);
 Lcontinue:
 
-    auto info = __arrayAlloc(size, ti, tinext);
-    if (!info.base)
+    auto ptr = GC.malloc(size, __typeAttrs(tinext) | BlkAttr.APPENDABLE, tinext);
+    if (!ptr)
         goto Loverflow;
-    debug(PRINTF) printf(" p = %p\n", info.base);
-    // update the length of the array
-    auto arrstart = __arrayStart(info);
-    auto isshared = typeid(ti) is typeid(TypeInfo_Shared);
-    __setArrayAllocLength(info, size, isshared, tinext);
-    return arrstart[0..length];
+    debug(PRINTF) printf(" p = %p\n", ptr);
+    return ptr[0 .. length];
 }
 
 /// ditto
@@ -580,24 +554,9 @@ Returns:
 extern (C) void* _d_newitemU(scope const TypeInfo _ti) pure nothrow @weak
 {
     auto ti = unqualify(_ti);
-    auto flags = !(ti.flags & 1) ? BlkAttr.NO_SCAN : 0;
-    immutable tiSize = structTypeInfoSize(ti);
-    immutable itemSize = ti.tsize;
-    immutable size = itemSize + tiSize;
-    if (tiSize)
-        flags |= BlkAttr.STRUCTFINAL | BlkAttr.FINALIZE;
-
-    auto blkInf = GC.qalloc(size, flags, ti);
-    auto p = blkInf.base;
-
-    if (tiSize)
-    {
-        // the GC might not have cleared the padding area in the block
-        *cast(TypeInfo*)(p + (itemSize & ~(size_t.sizeof - 1))) = null;
-        __setBlockFinalizerInfo(blkInf, cast() ti);
-    }
+    auto flags = __typeAttrs(ti);
 
-    return p;
+    return GC.malloc(ti.tsize, flags, ti);
 }
 
 /**
@@ -659,16 +618,25 @@ extern (C) CollectHandler rt_getCollectHandler()
  */
 extern (C) int rt_hasFinalizerInSegment(void* p, size_t size, uint attr, scope const(void)[] segment) nothrow
 {
+    if (!p)
+        return false;
+
     if (attr & BlkAttr.STRUCTFINAL)
     {
-        if (attr & BlkAttr.APPENDABLE)
-            return hasArrayFinalizerInSegment(p, size, segment);
-        return hasStructFinalizerInSegment(p, size, segment);
+        import core.internal.gc.blockmeta;
+        auto info = BlkInfo(
+            base: p,
+            size: size,
+            attr: attr
+        );
+
+        auto ti = cast(TypeInfo_Struct)cast(void*)__getBlockFinalizerInfo(info);
+        return cast(size_t)(cast(void*)ti.xdtor - segment.ptr) < segment.length;
     }
 
     // otherwise class
     auto ppv = cast(void**) p;
-    if (!p || !*ppv)
+    if (!*ppv)
         return false;
 
     auto c = *cast(ClassInfo*)*ppv;
@@ -682,68 +650,8 @@ extern (C) int rt_hasFinalizerInSegment(void* p, size_t size, uint attr, scope c
     return false;
 }
 
-int hasStructFinalizerInSegment(void* p, size_t size, in void[] segment) nothrow
-{
-    if (!p)
-        return false;
-
-    auto ti = *cast(TypeInfo_Struct*)(p + size - size_t.sizeof);
-    return cast(size_t)(cast(void*)ti.xdtor - segment.ptr) < segment.length;
-}
-
-int hasArrayFinalizerInSegment(void* p, size_t size, in void[] segment) nothrow
-{
-    if (!p)
-        return false;
-
-    TypeInfo_Struct si = void;
-    if (size < PAGESIZE)
-        si = *cast(TypeInfo_Struct*)(p + size - size_t.sizeof);
-    else
-        si = *cast(TypeInfo_Struct*)(p + size_t.sizeof);
-
-    return cast(size_t)(cast(void*)si.xdtor - segment.ptr) < segment.length;
-}
-
 debug (VALGRIND) import etc.valgrind.valgrind;
 
-// called by the GC
-void finalize_array2(void* p, size_t size) nothrow
-{
-    debug(PRINTF) printf("rt_finalize_array2(p = %p)\n", p);
-
-    // construct a BlkInfo to match the array API
-    auto info = BlkInfo(
-            base: p,
-            size: size,
-            attr: BlkAttr.APPENDABLE | BlkAttr.STRUCTFINAL
-    );
-    auto usedsize = __arrayAllocLength(info);
-    auto arrptr = __arrayStart(info);
-
-    debug (VALGRIND)
-    {
-        auto block = p[0..size];
-        disableAddrReportingInRange(block);
-    }
-
-    TypeInfo_Struct si = size < PAGESIZE ?
-        *cast(TypeInfo_Struct*)(p + size - size_t.sizeof) : // small
-        *cast(TypeInfo_Struct*)(p + size_t.sizeof); // large
-
-    debug (VALGRIND) enableAddrReportingInRange(block);
-
-    try
-    {
-        finalize_array(arrptr, usedsize, si);
-    }
-    catch (Exception e)
-    {
-        import core.exception : onFinalizeError;
-        onFinalizeError(si, e);
-    }
-}
-
 void finalize_array(void* p, size_t size, const TypeInfo_Struct si)
 {
     // Due to the fact that the delete operator calls destructors
@@ -758,11 +666,10 @@ void finalize_array(void* p, size_t size, const TypeInfo_Struct si)
 }
 
 // called by the GC
-void finalize_struct(void* p, size_t size) nothrow
+void finalize_struct(void* p, TypeInfo_Struct ti) nothrow
 {
     debug(PRINTF) printf("finalize_struct(p = %p)\n", p);
 
-    auto ti = *cast(TypeInfo_Struct*)(p + size - size_t.sizeof);
     try
     {
         ti.destroy(p); // call destructor
@@ -828,12 +735,37 @@ extern (C) void rt_finalize(void* p, bool det = true) nothrow
 extern (C) void rt_finalizeFromGC(void* p, size_t size, uint attr) nothrow
 {
     // to verify: reset memory necessary?
-    if (!(attr & BlkAttr.STRUCTFINAL))
+    if (!(attr & BlkAttr.STRUCTFINAL)) {
         rt_finalize2(p, false, false); // class
-    else if (attr & BlkAttr.APPENDABLE)
-        finalize_array2(p, size); // array of structs
+        return;
+    }
+
+    // get the struct typeinfo from the block, and the used size.
+    import core.internal.gc.blockmeta;
+    auto info = BlkInfo(
+            base: p,
+            size: size,
+            attr: attr
+    );
+
+    auto si = cast(TypeInfo_Struct)cast(void*)__getBlockFinalizerInfo(info);
+
+    if (attr & BlkAttr.APPENDABLE)
+    {
+        auto usedsize = __arrayAllocLength(info);
+        auto arrptr = __arrayStart(info);
+        try
+        {
+            finalize_array(arrptr, usedsize, si);
+        }
+        catch (Exception e)
+        {
+            import core.exception : onFinalizeError;
+            onFinalizeError(si, e);
+        }
+    }
     else
-        finalize_struct(p, size); // struct
+        finalize_struct(p, si); // struct
 }
 
 
@@ -927,28 +859,23 @@ do
 
     debug(PRINTF) printf("newsize = %zx, newlength = %zx\n", newsize, newlength);
 
-    const isshared = typeid(ti) is typeid(TypeInfo_Shared);
-
     if (!(*p).ptr)
     {
         assert((*p).length == 0);
         // pointer was null, need to allocate
-        auto info = __arrayAlloc(newsize, ti, tinext);
-        if (info.base is null)
+        auto ptr = GC.malloc(newsize, __typeAttrs(tinext) | BlkAttr.APPENDABLE, tinext);
+        if (ptr is null)
         {
             onOutOfMemoryError();
             assert(0);
         }
-        __setArrayAllocLength(info, newsize, isshared, tinext);
-        if (!isshared)
-            __insertBlkInfoCache(info, null);
-        void* newdata = cast(byte *)__arrayStart(info);
-        memset(newdata, 0, newsize);
-        *p = newdata[0 .. newlength];
+        memset(ptr, 0, newsize);
+        *p = ptr[0 .. newlength];
         return *p;
     }
 
     const size_t size = (*p).length * sizeelem;
+    const isshared = typeid(ti) is typeid(TypeInfo_Shared);
 
     /* Attempt to extend past the end of the existing array.
      * If not possible, allocate new space for entire array and copy.
@@ -956,24 +883,17 @@ do
     void* newdata = (*p).ptr;
     if (!gc_expandArrayUsed(newdata[0 .. size], newsize, isshared))
     {
-        auto info = __arrayAlloc(newsize, (*p).ptr, ti, tinext);
-        if (info.base is null)
+        newdata = GC.malloc(newsize, __typeAttrs(tinext, (*p).ptr) | BlkAttr.APPENDABLE, tinext);
+        if (newdata is null)
         {
             onOutOfMemoryError();
             assert(0);
         }
 
-        newdata = __arrayStart(info);
         newdata[0 .. size] = (*p).ptr[0 .. size];
 
-        __setArrayAllocLength(info, newsize, isshared, tinext);
-
         // Do postblit processing, as we are making a copy.
         __doPostblit(newdata, size, tinext);
-
-        // this hasn't been added to the cache yet.
-        if (!isshared)
-            __insertBlkInfoCache(info, null);
     }
 
     // Zero the unused portion of the newly allocated space
@@ -1049,8 +969,6 @@ do
 
     debug(PRINTF) printf("newsize = %zx, newlength = %zx\n", newsize, newlength);
 
-    const isshared = typeid(ti) is typeid(TypeInfo_Shared);
-
     static void doInitialize(void *start, void *end, const void[] initializer)
     {
         if (initializer.length == 1)
@@ -1072,22 +990,19 @@ do
     {
         assert((*p).length == 0);
         // pointer was null, need to allocate
-        auto info = __arrayAlloc(newsize, ti, tinext);
-        if (info.base is null)
+        auto ptr = GC.malloc(newsize, __typeAttrs(tinext) | BlkAttr.APPENDABLE, tinext);
+        if (ptr is null)
         {
             onOutOfMemoryError();
             assert(0);
         }
-        __setArrayAllocLength(info, newsize, isshared, tinext);
-        if (!isshared)
-            __insertBlkInfoCache(info, null);
-        void* newdata = cast(byte *)__arrayStart(info);
-        doInitialize(newdata, newdata + newsize, tinext.initializer);
-        *p = newdata[0 .. newlength];
+        doInitialize(ptr, ptr + newsize, tinext.initializer);
+        *p = ptr[0 .. newlength];
         return *p;
     }
 
     const size_t size = (*p).length * sizeelem;
+    const isshared = typeid(ti) is typeid(TypeInfo_Shared);
 
     /* Attempt to extend past the end of the existing array.
      * If not possible, allocate new space for entire array and copy.
@@ -1095,24 +1010,17 @@ do
     void* newdata = (*p).ptr;
     if (!gc_expandArrayUsed(newdata[0 .. size], newsize, isshared))
     {
-        auto info = __arrayAlloc(newsize, (*p).ptr, ti, tinext);
-        if (info.base is null)
+        newdata = GC.malloc(newsize, __typeAttrs(tinext, (*p).ptr) | BlkAttr.APPENDABLE, tinext);
+        if (newdata is null)
         {
             onOutOfMemoryError();
             assert(0);
         }
 
-        newdata = __arrayStart(info);
         newdata[0 .. size] = (*p).ptr[0 .. size];
 
-        __setArrayAllocLength(info, newsize, isshared, tinext);
-
         // Do postblit processing, as we are making a copy.
         __doPostblit(newdata, size, tinext);
-
-        // this hasn't been added to the cache yet.
-        if (!isshared)
-            __insertBlkInfoCache(info, null);
     }
 
     // Initialize the unused portion of the newly allocated space
@@ -1207,6 +1115,11 @@ byte[] _d_arrayappendcTX(const TypeInfo ti, return scope ref byte[] px, size_t n
     import core.exception : onOutOfMemoryError;
     // This is a cut&paste job from _d_arrayappendT(). Should be refactored.
 
+    // Short circuit if no data is being appended.
+    if (n == 0)
+        return px;
+
+
     // only optimize array append where ti is not a shared type
     auto tinext = unqualify(ti.next);
     auto sizeelem = tinext.tsize;              // array element size
@@ -1220,32 +1133,33 @@ byte[] _d_arrayappendcTX(const TypeInfo ti, return scope ref byte[] px, size_t n
     {
         // could not set the size, we must reallocate.
         auto newcap = newCapacity(newlength, sizeelem);
-        auto info = __arrayAlloc(newcap, px.ptr, ti, tinext);
-        if (info.base is null)
+        auto attrs = __typeAttrs(tinext, px.ptr) | BlkAttr.APPENDABLE;
+        auto ptr = cast(byte*) GC.malloc(newcap, attrs, tinext);
+        if (ptr is null)
         {
             onOutOfMemoryError();
             assert(0);
         }
 
-        __setArrayAllocLength(info, newsize, isshared, tinext);
-        if (!isshared)
-            __insertBlkInfoCache(info, null);
-
-        auto newdata = cast(byte*)__arrayStart(info);
-        memcpy(newdata, px.ptr, size);
-
+        if (newsize != newcap)
+        {
+            // For small blocks that are always fully scanned, if we allocated more
+            // capacity than was requested, we are responsible for zeroing that
+            // memory.
+            // TODO: should let the GC figure this out, as this property may
+            // not always hold.
+            if (!(attrs & BlkAttr.NO_SCAN) && newcap < PAGESIZE)
+                memset(ptr + newsize, 0, newcap - newsize);
+
+            gc_shrinkArrayUsed(ptr[0 .. newsize], newcap, isshared);
+        }
 
-        // For small blocks that are always fully scanned, if we allocated more
-        // capacity than was requested, we are responsible for zeroing that
-        // memory.
-        // large blocks are only scanned up to the used size.
-        if (!(info.attr & BlkAttr.NO_SCAN) && newcap > newcap && info.size < PAGESIZE)
-            memset(newdata + newsize, 0, newcap - newsize);
+        memcpy(ptr, px.ptr, size);
 
         // do potsblit processing.
-        __doPostblit(newdata, size, tinext);
+        __doPostblit(ptr, size, tinext);
 
-        px = newdata[0 .. newlength];
+        px = ptr[0 .. newlength];
         return px;
     }
 
@@ -1428,16 +1342,12 @@ void* _d_arrayliteralTX(const TypeInfo ti, size_t length) @weak
 
     debug(PRINTF) printf("_d_arrayliteralTX(sizeelem = %zd, length = %zd)\n", sizeelem, length);
     if (length == 0 || sizeelem == 0)
-        result = null;
+        return null;
     else
     {
         auto allocsize = length * sizeelem;
-        auto info = __arrayAlloc(allocsize, ti, tinext);
-        auto isshared = typeid(ti) is typeid(TypeInfo_Shared);
-        __setArrayAllocLength(info, allocsize, isshared, tinext);
-        result = __arrayStart(info);
+        return GC.malloc(allocsize, __typeAttrs(tinext) | BlkAttr.APPENDABLE, tinext);
     }
-    return result;
 }
 
 
@@ -1804,6 +1714,7 @@ unittest
     GC.free(larr1);
 
     auto larr2 = new S[255];
+    import core.internal.gc.blockmeta : LARGEPREFIX;
     if (cast(void*)larr1 is cast(void*)larr2.ptr - LARGEPREFIX) // reusage not guaranteed
     {
         auto ptr = cast(S**)larr1;
index fdcc058c9035e7d89ffd647d063d9ca5fee074ef..9603e65aa4235d2a2f0235f9e9e7938cc461e750 100644 (file)
@@ -1,4 +1,4 @@
-336bed6d8ffec74d117b755866c5bd22e3d610a1
+1b242048c9db88c52cb0df6cd50c2b7455bedc01
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/phobos repository.
index ea1a1b290dc23e42563275cdd87ea02fbd8cd470..8a45ecb81319b7d8c1dc61560e22adfe8a99c861 100644 (file)
@@ -2885,6 +2885,17 @@ if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs))))
     {
         if (&lhs != &rhs)
         {
+            static if (__traits(compiles, lhs.tupleof = rhs.tupleof))
+            {
+                if (__ctfe)
+                {
+                    // can't reinterpret cast
+                    foreach (i, ref e; lhs.tupleof)
+                        swap(e, rhs.tupleof[i]);
+                    return;
+                }
+            }
+
             // For structs with non-trivial assignment, move memory directly
             ubyte[T.sizeof] t = void;
             auto a = (cast(ubyte*) &lhs)[0 .. T.sizeof];
@@ -3128,6 +3139,18 @@ if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs))))
     swap(a3, a4);
 }
 
+// https://issues.dlang.org/show_bug.cgi?id=21429
+@safe unittest
+{
+    enum e = (){
+        Tuple!int a = 5, b = 6;
+        swap(a, b);
+        assert(a[0] == 6);
+        assert(b[0] == 5);
+        return 0;
+    }();
+}
+
 /**
 Swaps two elements in-place of a range `r`,
 specified by their indices `i1` and `i2`.
index b4413f68f3d3b8be159bb5fde0ab3dfcd5172fb4..4734c1b7165829c8d3f3a0e41550a0d889ed906a 100644 (file)
@@ -2169,13 +2169,13 @@ Allows to directly use range operations on lines of a file.
     private struct ByLineImpl(Char, Terminator)
     {
     private:
-        import std.typecons : RefCounted, RefCountedAutoInitialize;
+        import std.typecons : borrow, RefCountedAutoInitialize, SafeRefCounted;
 
         /* Ref-counting stops the source range's Impl
          * from getting out of sync after the range is copied, e.g.
          * when accessing range.front, then using std.range.take,
          * then accessing range.front again. */
-        alias PImpl = RefCounted!(Impl, RefCountedAutoInitialize.no);
+        alias PImpl = SafeRefCounted!(Impl, RefCountedAutoInitialize.no);
         PImpl impl;
 
         static if (isScalarType!Terminator)
@@ -2190,19 +2190,24 @@ Allows to directly use range operations on lines of a file.
             impl = PImpl(f, kt, terminator);
         }
 
-        @property bool empty()
+        /* Verifiably `@safe` when built with -preview=DIP1000. */
+        @property bool empty() @trusted
         {
-            return impl.refCountedPayload.empty;
+            // Using `ref` is actually necessary here.
+            return impl.borrow!((ref i) => i.empty);
         }
 
-        @property Char[] front()
+        /* Verifiably `@safe` when built with -preview=DIP1000. */
+        @property Char[] front() @trusted
         {
-            return impl.refCountedPayload.front;
+            // Using `ref` is likely optional here.
+            return impl.borrow!((ref i) => i.front);
         }
 
-        void popFront()
+        /* Verifiably `@safe` when built with -preview=DIP1000. */
+        void popFront() @trusted
         {
-            impl.refCountedPayload.popFront();
+            return impl.borrow!((ref i) => i.popFront());
         }
 
     private:
@@ -2216,6 +2221,7 @@ Allows to directly use range operations on lines of a file.
             KeepTerminator keepTerminator;
             bool haveLine;
 
+        @safe:
         public:
             this(File f, KeepTerminator kt, Terminator terminator)
             {
@@ -2375,7 +2381,7 @@ void main()
         return ByLineImpl!(Char, Terminator)(this, keepTerminator, terminator);
     }
 
-    @system unittest
+    @safe unittest
     {
         static import std.file;
         auto deleteme = testFilename();
@@ -2393,7 +2399,7 @@ void main()
     }
 
     // https://issues.dlang.org/show_bug.cgi?id=19980
-    @system unittest
+    @safe unittest
     {
         static import std.file;
         auto deleteme = testFilename();
@@ -2541,12 +2547,11 @@ $(REF readText, std,file)
             is(typeof(File("").byLineCopy!(char, char).front) == char[]));
     }
 
-    @system unittest
+    @safe unittest
     {
         import std.algorithm.comparison : equal;
         static import std.file;
 
-        scope(failure) printf("Failed test at line %d\n", __LINE__);
         auto deleteme = testFilename();
         std.file.write(deleteme, "");
         scope(success) std.file.remove(deleteme);
@@ -2620,7 +2625,7 @@ $(REF readText, std,file)
         test("sue\r", ["sue\r"], kt, '\r');
     }
 
-    @system unittest
+    @safe unittest
     {
         import std.algorithm.comparison : equal;
         import std.range : drop, take;
@@ -4765,6 +4770,15 @@ struct lines
         foreach (line; myByLineCopy)
             continue;
     }
+
+    {
+        auto f = File(deleteMe, "r");
+        scope(exit) { f.close(); }
+
+        auto myByLine = f.byLine;
+        foreach (line; myByLine)
+            continue;
+    }
 }
 
 @system unittest
index a841e4720b2cad94153e3798afbb374bae66ebe7..989ccba042ccaa30049f7af18af59db9d23ce704 100644 (file)
@@ -980,24 +980,35 @@ if (distinctFieldNames!(Specs))
         {
             import std.algorithm.mutation : swap;
 
-            static if (is(R == Tuple!Types) && !__traits(isRef, rhs) && isTuple!R)
+            /*
+                This optimization caused compilation failures with no error message available:
+
+                > Error: unknown, please file report on issues.dlang.org
+                > std/sumtype.d(1262): Error: template instance `std.sumtype.SumType!(Flag, Tuple!(This*))` error instantiating
+            */
+            version (none)
             {
-                if (__ctfe)
+                static if (is(R == Tuple!Types) && !__traits(isRef, rhs) && isTuple!R)
                 {
-                    // Cannot use swap at compile time
-                    field[] = rhs.field[];
+                    if (__ctfe)
+                    {
+                        // Cannot use swap at compile time
+                        field[] = rhs.field[];
+                    }
+                    else
+                    {
+                        // Use swap-and-destroy to optimize rvalue assignment
+                        swap!(Tuple!Types)(this, rhs);
+                    }
                 }
                 else
                 {
-                    // Use swap-and-destroy to optimize rvalue assignment
-                    swap!(Tuple!Types)(this, rhs);
+                    // Do not swap; opAssign should be called on the fields.
+                    field[] = rhs.field[];
                 }
             }
-            else
-            {
-                // Do not swap; opAssign should be called on the fields.
-                field[] = rhs.field[];
-            }
+
+            field[] = rhs.field[];
             return this;
         }