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