d: Merge upstream dmd, druntime d115713410, phobos 1b242048c.

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.
This commit is contained in:
Iain Buclaw 2025-01-18 17:35:27 +01:00
parent 20a4306793
commit 2ead01297c
65 changed files with 851 additions and 952 deletions

View 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.

View 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_;
}

View 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();
}
}

View 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;
}
}

View 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

View 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);
}
/***************************************

View 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;

View 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());

View 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();
}
}

View 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;

View 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;

View 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++)

View 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())
{

View 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());

View 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;

View 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);
}

View 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

View 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;
}

View 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

View 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();

View 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)
{

View 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" }
}

View 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
---
*/

View 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

View 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`
---
*/

View 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`
---
*/

View 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`
---
*/

View 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 = "";
}

View 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`
---
*/

View 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
---
*/

View 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`
---
*/

View 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`
---
*/

View 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`
---
*/

View 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, /+

View 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()

View 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)

View 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

View 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`
---
*/

View 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;
}

View 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`
---
*/

View File

@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/test23170.d(10): Error: array literal in `@nogc` delegate `test23170.__lambda_L10_C15` may cause a GC allocation
fail_compilation/test23170.d(10): Error: this array literal causes a GC allocation in `@nogc` delegate `__lambda_L10_C15`
---
*/
// https://issues.dlang.org/show_bug.cgi?id=23170

View 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`
---
*/

View 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;
/*********************************************************/

View 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).");

View 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.

View 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;

View File

@ -794,7 +794,7 @@ version (unittest)
{
version (none)
{
import core.stdc.stdio;
import core.stdc.stdio : printf;
@trusted
void print(Cent c)

View 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
{

View 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;
}

View 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);
}

View 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;
}
size_t localAllocSize = void;
adjustAttrs(bits, ti);
auto p = runLocked!(mallocNoSync, mallocTime, numMallocs)(size, 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))
immutable padding = __allocPad(size, bits);
bool overflow;
import core.checkedint : addu;
immutable needed = addu(size, padding, overflow);
if (overflow)
{
memset(p + size, 0, localAllocSize - size);
return null;
}
return p;
size_t localAllocSize = void;
auto p = runLocked!(mallocNoSync, mallocTime, numMallocs)(needed, bits, localAllocSize, ti);
debug (VALGRIND) makeMemUndefined(p[0..size]);
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(ret.ptr, 0, size);
}
else
{
memset(ret.ptr, 0, ret.length);
}
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];
}

View 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`

View 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();
}
}

View 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()
{

View 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;

View 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;

View 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;
}

View 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;
}
}
}

View 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)

View 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

View File

@ -13,10 +13,8 @@
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 flags = __typeAttrs(ti);
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);
}
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);
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);
auto newdata = cast(byte*)__arrayStart(info);
memcpy(newdata, px.ptr, size);
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;

View 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.

View 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`.

View 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

View 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;
}