aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-06-13 10:41:57 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2022-06-13 11:38:10 +0200
commitec486b739b83ffdbe40c5ececb20d16c94d6b0d0 (patch)
tree9a3c04628df45a6dca9288e2c44b089c957e426d
parent13ea4a6e830da1f245136601e636dec62e74d1a7 (diff)
downloadgcc-ec486b739b83ffdbe40c5ececb20d16c94d6b0d0.zip
gcc-ec486b739b83ffdbe40c5ececb20d16c94d6b0d0.tar.gz
gcc-ec486b739b83ffdbe40c5ececb20d16c94d6b0d0.tar.bz2
d: Merge upstream dmd 821ed393d, druntime 454471d8, phobos 1206fc94f.
D front-end changes: - Import latest bug fixes to mainline. D runtime changes: - Fix duplicate Elf64_Dyn definitions on Solaris. - _d_newThrowable has been converted to a template. Phobos changes: - Import latest bug fixes to mainline. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 821ed393d. * expr.cc (ExprVisitor::visit (NewExp *)): Remove handled of allocating `@nogc' throwable object. * runtime.def (NEWTHROW): Remove. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 454471d8. * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add core/sync/package.d. * libdruntime/Makefile.in: Regenerate. * src/MERGE: Merge upstream phobos 1206fc94f.
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/attrib.d6
-rw-r--r--gcc/d/dmd/cparse.d88
-rw-r--r--gcc/d/dmd/cppmangle.d2
-rw-r--r--gcc/d/dmd/dcast.d4
-rw-r--r--gcc/d/dmd/dinterpret.d38
-rw-r--r--gcc/d/dmd/dscope.d17
-rw-r--r--gcc/d/dmd/dsymbol.d18
-rw-r--r--gcc/d/dmd/dsymbol.h2
-rw-r--r--gcc/d/dmd/dsymbolsem.d7
-rw-r--r--gcc/d/dmd/dtemplate.d8
-rw-r--r--gcc/d/dmd/expressionsem.d100
-rw-r--r--gcc/d/dmd/func.d4
-rw-r--r--gcc/d/dmd/id.d1
-rw-r--r--gcc/d/dmd/mtype.d13
-rw-r--r--gcc/d/dmd/mtype.h11
-rw-r--r--gcc/d/dmd/parse.d2
-rw-r--r--gcc/d/dmd/scope.h1
-rw-r--r--gcc/d/dmd/statement.d2
-rw-r--r--gcc/d/dmd/statementsem.d25
-rw-r--r--gcc/d/dmd/typesem.d471
-rw-r--r--gcc/d/dmd/typinf.d9
-rw-r--r--gcc/d/expr.cc10
-rw-r--r--gcc/d/runtime.def1
-rw-r--r--gcc/testsuite/gdc.test/compilable/imports/defines.c28
-rw-r--r--gcc/testsuite/gdc.test/compilable/nogc.d9
-rw-r--r--gcc/testsuite/gdc.test/compilable/test22626.d23
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23076.d38
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23142.d19
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23174.d58
-rw-r--r--gcc/testsuite/gdc.test/compilable/testdefines.d14
-rw-r--r--gcc/testsuite/gdc.test/compilable/testdip1008.d19
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/mixin_template.d10
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/noreturn.d18
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/template_decl.d9
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test21477.d16
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test23159.d22
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/traits.d18
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/Makefile.am6
-rw-r--r--libphobos/libdruntime/Makefile.in30
-rw-r--r--libphobos/libdruntime/core/attribute.d18
-rw-r--r--libphobos/libdruntime/core/internal/array/equality.d33
-rw-r--r--libphobos/libdruntime/core/lifetime.d40
-rw-r--r--libphobos/libdruntime/core/stdcpp/xutility.d15
-rw-r--r--libphobos/libdruntime/core/sys/dragonflybsd/sys/elf32.d10
-rw-r--r--libphobos/libdruntime/core/sys/dragonflybsd/sys/elf64.d10
-rw-r--r--libphobos/libdruntime/core/sys/elf/package.d20
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/elf32.d10
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/elf64.d10
-rw-r--r--libphobos/libdruntime/core/sys/linux/elf.d20
-rw-r--r--libphobos/libdruntime/core/sys/netbsd/sys/elf32.d10
-rw-r--r--libphobos/libdruntime/core/sys/netbsd/sys/elf64.d10
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/sys/elf32.d10
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/sys/elf64.d10
-rw-r--r--libphobos/libdruntime/core/sys/solaris/sys/elftypes.d18
-rw-r--r--libphobos/libdruntime/core/sys/solaris/sys/link.d235
-rw-r--r--libphobos/libdruntime/core/thread/threadbase.d2
-rw-r--r--libphobos/libdruntime/rt/ehalloc.d45
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/mmfile.d10
-rw-r--r--libphobos/src/std/sumtype.d22
62 files changed, 1029 insertions, 712 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index c37da05..d39658a 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-4d07f22f29d098869ad937f0499d8895df089a71
+821ed393d428c7db5a48623e77d43f5647d5c6a2
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index 1e84b55..b569a9c 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -1274,14 +1274,14 @@ extern (C++) final class StaticForeachDeclaration : AttribDeclaration
* declarations.
*/
-extern(C++) final class ForwardingAttribDeclaration: AttribDeclaration
+extern(C++) final class ForwardingAttribDeclaration : AttribDeclaration
{
ForwardingScopeDsymbol sym = null;
this(Dsymbols* decl)
{
super(decl);
- sym = new ForwardingScopeDsymbol(null);
+ sym = new ForwardingScopeDsymbol();
sym.symtab = new DsymbolTable();
}
@@ -1298,7 +1298,7 @@ extern(C++) final class ForwardingAttribDeclaration: AttribDeclaration
*/
override void addMember(Scope* sc, ScopeDsymbol sds)
{
- parent = sym.parent = sym.forward = sds;
+ sym.parent = sds;
return super.addMember(sc, sym);
}
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index 344933a..62ba889 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -5156,26 +5156,80 @@ final class CParser(AST) : Parser!AST
{
auto id = n.ident;
scan(&n);
- if (n.value == TOK.endOfLine) // #define identifier
- {
- nextDefineLine();
- continue;
- }
- if (n.value == TOK.int32Literal)
+
+ AST.Type t;
+
+ switch (n.value)
{
- const value = n.intvalue;
- scan(&n);
- if (n.value == TOK.endOfLine)
- {
- /* Declare manifest constant:
- * enum id = value;
- */
- AST.Expression e = new AST.IntegerExp(scanloc, value, AST.Type.tint32);
- auto v = new AST.VarDeclaration(scanloc, AST.Type.tint32, id, new AST.ExpInitializer(scanloc, e), STC.manifest);
- symbols.push(v);
+ case TOK.endOfLine: // #define identifier
nextDefineLine();
continue;
- }
+
+ case TOK.int32Literal:
+ case TOK.charLiteral: t = AST.Type.tint32; goto Linteger;
+ case TOK.uns32Literal: t = AST.Type.tuns32; goto Linteger;
+ case TOK.int64Literal: t = AST.Type.tint64; goto Linteger;
+ case TOK.uns64Literal: t = AST.Type.tuns64; goto Linteger;
+
+ Linteger:
+ const intvalue = n.intvalue;
+ scan(&n);
+ if (n.value == TOK.endOfLine)
+ {
+ /* Declare manifest constant:
+ * enum id = intvalue;
+ */
+ AST.Expression e = new AST.IntegerExp(scanloc, intvalue, t);
+ auto v = new AST.VarDeclaration(scanloc, t, id, new AST.ExpInitializer(scanloc, e), STC.manifest);
+ symbols.push(v);
+ nextDefineLine();
+ continue;
+ }
+ break;
+
+ case TOK.float32Literal: t = AST.Type.tfloat32; goto Lfloat;
+ case TOK.float64Literal: t = AST.Type.tfloat64; goto Lfloat;
+ case TOK.float80Literal: t = AST.Type.tfloat80; goto Lfloat;
+ case TOK.imaginary32Literal: t = AST.Type.timaginary32; goto Lfloat;
+ case TOK.imaginary64Literal: t = AST.Type.timaginary64; goto Lfloat;
+ case TOK.imaginary80Literal: t = AST.Type.timaginary80; goto Lfloat;
+
+ Lfloat:
+ const floatvalue = n.floatvalue;
+ scan(&n);
+ if (n.value == TOK.endOfLine)
+ {
+ /* Declare manifest constant:
+ * enum id = floatvalue;
+ */
+ AST.Expression e = new AST.RealExp(scanloc, floatvalue, t);
+ auto v = new AST.VarDeclaration(scanloc, t, id, new AST.ExpInitializer(scanloc, e), STC.manifest);
+ symbols.push(v);
+ nextDefineLine();
+ continue;
+ }
+ break;
+
+ case TOK.string_:
+ const str = n.ustring;
+ const len = n.len;
+ const postfix = n.postfix;
+ scan(&n);
+ if (n.value == TOK.endOfLine)
+ {
+ /* Declare manifest constant:
+ * enum id = "string";
+ */
+ AST.Expression e = new AST.StringExp(scanloc, str[0 .. len], len, 1, postfix);
+ auto v = new AST.VarDeclaration(scanloc, null, id, new AST.ExpInitializer(scanloc, e), STC.manifest);
+ symbols.push(v);
+ nextDefineLine();
+ continue;
+ }
+ break;
+
+ default:
+ break;
}
}
skipToNextLine();
diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d
index 6235342a..fed83b8 100644
--- a/gcc/d/dmd/cppmangle.d
+++ b/gcc/d/dmd/cppmangle.d
@@ -1318,7 +1318,7 @@ private final class CppMangleVisitor : Visitor
Type t = fparam.type.merge2();
if (fparam.isReference())
t = t.referenceTo();
- else if (fparam.storageClass & STC.lazy_)
+ else if (fparam.isLazy())
{
// Mangle as delegate
auto tf = new TypeFunction(ParameterList(), t, LINK.d);
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index 4607d6f..12051d9 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -916,7 +916,7 @@ MATCH implicitConvTo(Expression e, Type t)
if (i - j < nparams)
{
Parameter fparam = tf.parameterList[i - j];
- if (fparam.storageClass & STC.lazy_)
+ if (fparam.isLazy())
return result; // not sure what to do with this
Type tparam = fparam.type;
if (!tparam)
@@ -1224,7 +1224,7 @@ MATCH implicitConvTo(Expression e, Type t)
if (i - j < nparams)
{
Parameter fparam = tf.parameterList[i - j];
- if (fparam.storageClass & STC.lazy_)
+ if (fparam.isLazy())
return MATCH.nomatch; // not sure what to do with this
Type tparam = fparam.type;
if (!tparam)
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index 5e7527d..bb25210 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -492,7 +492,7 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta
if (CTFEExp.isCantExp(earg))
return earg;
}
- else if (fparam.storageClass & STC.lazy_)
+ else if (fparam.isLazy())
{
}
else
@@ -5000,6 +5000,27 @@ public:
printf("%s CommaExp::interpret() %s\n", e.loc.toChars(), e.toChars());
}
+ bool isNewThrowableHook()
+ {
+ auto de = e.e1.isDeclarationExp();
+ if (de is null)
+ return false;
+
+ auto vd = de.declaration.isVarDeclaration();
+ if (vd is null)
+ return false;
+
+ auto ei = vd._init.isExpInitializer();
+ if (ei is null)
+ return false;
+
+ auto ce = ei.exp.isConstructExp();
+ if (ce is null)
+ return false;
+
+ return isRuntimeHook(ce.e2, Id._d_newThrowable) !is null;
+ }
+
if (auto ce = isRuntimeHook(e.e1, Id._d_arrayappendcTX))
{
// In expressionsem.d `arr ~= elem` was lowered to
@@ -5018,6 +5039,21 @@ public:
result = interpret(cae, istate);
return;
}
+ else if (isNewThrowableHook())
+ {
+ // In expressionsem.d `throw new Exception(args)` was lowered to
+ // `throw (tmp = _d_newThrowable!Exception(), tmp.ctor(args), tmp)`.
+ // The following code will rewrite it back to `throw new Exception(args)`
+ // and then interpret this expression instead.
+ auto ce = e.e2.isCallExp();
+ assert(ce);
+
+ auto ne = new NewExp(e.loc, null, e.type, ce.arguments);
+ ne.type = e.e1.type;
+
+ result = interpret(ne, istate);
+ return;
+ }
// If it creates a variable, and there's no context for
// the variable to be created in, we need to create one now.
diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d
index b546e37..9c30978 100644
--- a/gcc/d/dmd/dscope.d
+++ b/gcc/d/dmd/dscope.d
@@ -754,7 +754,6 @@ struct Scope
// assert(0);
}
}
-
/******************************
*/
structalign_t alignment()
@@ -771,13 +770,13 @@ struct Scope
return sa;
}
}
-
+ @safe @nogc pure nothrow const:
/**********************************
* Checks whether the current scope (or any of its parents) is deprecated.
*
* Returns: `true` if this or any parent scope is deprecated, `false` otherwise`
*/
- extern(C++) bool isDeprecated() @safe @nogc pure nothrow const
+ extern(C++) bool isDeprecated()
{
for (const(Dsymbol)* sp = &(this.parent); *sp; sp = &(sp.parent))
{
@@ -799,4 +798,16 @@ struct Scope
}
return false;
}
+ /**
+ * dmd relies on mutation of state during semantic analysis, however
+ * sometimes semantic is being performed in a speculative context that should
+ * not have any visible effect on the rest of the compilation: for example when compiling
+ * a typeof() or __traits(compiles).
+ *
+ * Returns: `true` if this `Scope` is known to be from one of these speculative contexts
+ */
+ extern(C++) bool isFromSpeculativeSemanticContext() scope
+ {
+ return this.intypeof || this.flags & SCOPE.compile;
+ }
}
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index 3b3a527..2b608f6 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -2184,20 +2184,13 @@ extern (C++) final class OverloadSet : Dsymbol
*/
extern (C++) final class ForwardingScopeDsymbol : ScopeDsymbol
{
- /*************************
- * Symbol to forward insertions to.
- * Can be `null` before being lazily initialized.
- */
- ScopeDsymbol forward;
- extern (D) this(ScopeDsymbol forward) nothrow
+ extern (D) this() nothrow
{
- super(null);
- this.forward = forward;
+ super();
}
override Dsymbol symtabInsert(Dsymbol s) nothrow
{
- assert(forward);
if (auto d = s.isDeclaration())
{
if (d.storage_class & STC.local)
@@ -2212,6 +2205,8 @@ extern (C++) final class ForwardingScopeDsymbol : ScopeDsymbol
return super.symtabInsert(s); // insert locally
}
}
+ auto forward = parent.isScopeDsymbol();
+ assert(forward);
if (!forward.symtab)
{
forward.symtab = new DsymbolTable();
@@ -2228,7 +2223,6 @@ extern (C++) final class ForwardingScopeDsymbol : ScopeDsymbol
*/
override Dsymbol symtabLookup(Dsymbol s, Identifier id) nothrow
{
- assert(forward);
// correctly diagnose clashing foreach loop variables.
if (auto d = s.isDeclaration())
{
@@ -2243,6 +2237,8 @@ extern (C++) final class ForwardingScopeDsymbol : ScopeDsymbol
}
// Declarations within `static foreach` do not clash with
// `static foreach` loop variables.
+ auto forward = parent.isScopeDsymbol();
+ assert(forward);
if (!forward.symtab)
{
forward.symtab = new DsymbolTable();
@@ -2252,6 +2248,8 @@ extern (C++) final class ForwardingScopeDsymbol : ScopeDsymbol
override void importScope(Dsymbol s, Visibility visibility)
{
+ auto forward = parent.isScopeDsymbol();
+ assert(forward);
forward.importScope(s, visibility);
}
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index 23a2c77..bea4b77 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -391,8 +391,6 @@ public:
class ForwardingScopeDsymbol final : public ScopeDsymbol
{
public:
- ScopeDsymbol *forward;
-
Dsymbol *symtabInsert(Dsymbol *s) override;
Dsymbol *symtabLookup(Dsymbol *s, Identifier *id) override;
void importScope(Dsymbol *s, Visibility visibility) override;
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index e491272..6dbc129 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -3276,13 +3276,6 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if ((funcdecl.storage_class & STC.auto_) && !f.isref && !funcdecl.inferRetType)
funcdecl.error("storage class `auto` has no effect if return type is not inferred");
- /* Functions can only be 'scope' if they have a 'this'
- */
- if (f.isScopeQual && !funcdecl.isNested() && !ad)
- {
- funcdecl.error("functions cannot be `scope`");
- }
-
if (f.isreturn && !funcdecl.needThis() && !funcdecl.isNested())
{
/* Non-static nested functions have a hidden 'this' pointer to which
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index a450ea5..c0a8e9f 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -1632,7 +1632,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (farg.op == EXP.error || farg.type.ty == Terror)
return nomatch();
- if (!(fparam.storageClass & STC.lazy_) && farg.type.ty == Tvoid)
+ if (!fparam.isLazy() && farg.type.ty == Tvoid)
return nomatch();
Type tt;
@@ -1837,7 +1837,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
}
Type argtype = farg.type;
- if (!(fparam.storageClass & STC.lazy_) && argtype.ty == Tvoid && farg.op != EXP.function_)
+ if (!fparam.isLazy() && argtype.ty == Tvoid && farg.op != EXP.function_)
return nomatch();
// https://issues.dlang.org/show_bug.cgi?id=12876
@@ -1958,7 +1958,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (!farg.type.isMutable()) // https://issues.dlang.org/show_bug.cgi?id=11916
return nomatch();
}
- if (m == MATCH.nomatch && (fparam.storageClass & STC.lazy_) && prmtype.ty == Tvoid && farg.type.ty != Tvoid)
+ if (m == MATCH.nomatch && fparam.isLazy() && prmtype.ty == Tvoid && farg.type.ty != Tvoid)
m = MATCH.convert;
if (m != MATCH.nomatch)
{
@@ -7723,7 +7723,7 @@ extern (C++) final class TemplateMixin : TemplateInstance
}
if (!tempdecl)
{
- error("`%s` isn't a template", s.toChars());
+ error("- `%s` is a %s, not a template", s.toChars(), s.kind());
return false;
}
}
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index cb72027..dcc5b50 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -443,7 +443,7 @@ private Expression searchUFCS(Scope* sc, UnaExp ue, Identifier ident)
}
if (!s)
- return ue.e1.type.Type.getProperty(sc, loc, ident, 0);
+ return ue.e1.type.getProperty(sc, loc, ident, 0);
FuncDeclaration f = s.isFuncDeclaration();
if (f)
@@ -1856,7 +1856,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
}
L1:
- if (!(p.storageClass & STC.lazy_ && p.type.ty == Tvoid))
+ if (!(p.isLazy() && p.type.ty == Tvoid))
{
if (ubyte wm = arg.type.deduceWild(p.type, p.isReference()))
{
@@ -1953,7 +1953,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
Type targ = arg.type; // keep original type for isCopyable() because alias this
// resolution may hide an uncopyable type
- if (!(p.storageClass & STC.lazy_ && p.type.ty == Tvoid))
+ if (!(p.isLazy() && p.type.ty == Tvoid))
{
Type tprm = p.type.hasWild()
? p.type.substWildTo(wildmatch)
@@ -2018,7 +2018,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
}
arg = arg.toLvalue(sc, arg);
}
- else if (p.storageClass & STC.lazy_)
+ else if (p.isLazy())
{
// Convert lazy argument to a delegate
auto t = (p.type.ty == Tvoid) ? p.type : arg.type;
@@ -2050,7 +2050,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
// Turning heap allocations into stack allocations is dangerous without dip1000, since `scope` inference
// may be unreliable when scope violations only manifest as deprecation warnings.
// However, existing `@nogc` code may rely on it, so still do it when the parameter is explicitly marked `scope`
- const explicitScope = (p.storageClass & STC.lazy_) ||
+ const explicitScope = p.isLazy() ||
((p.storageClass & STC.scope_) && !(p.storageClass & STC.scopeinferred));
if ((pStc & (STC.scope_ | STC.lazy_)) &&
((global.params.useDIP1000 == FeatureState.enabled) || explicitScope) &&
@@ -2261,7 +2261,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
if (arg.type.needsDestruction())
{
Parameter p = (i >= nparams ? null : tf.parameterList[i]);
- if (!(p && (p.storageClass & (STC.lazy_ | STC.ref_ | STC.out_))))
+ if (!(p && (p.isLazy() || p.isReference())))
{
if (firstdtor == -1)
firstdtor = i;
@@ -2302,7 +2302,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
Parameter parameter = (i >= nparams ? null : tf.parameterList[i]);
const bool isRef = parameter && parameter.isReference();
- const bool isLazy = (parameter && (parameter.storageClass & STC.lazy_));
+ const bool isLazy = parameter && parameter.isLazy();
/* Skip lazy parameters
*/
@@ -3722,6 +3722,36 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
}
}
+
+ // When using `@nogc` exception handling, lower `throw new E(args)` to
+ // `throw (__tmp = _d_newThrowable!E(), __tmp.__ctor(args), __tmp)`.
+ if (global.params.ehnogc && exp.thrownew &&
+ !cd.isCOMclass() && !cd.isCPPclass())
+ {
+ assert(cd.ctor);
+
+ Expression id = new IdentifierExp(exp.loc, Id.empty);
+ id = new DotIdExp(exp.loc, id, Id.object);
+
+ auto tiargs = new Objects();
+ tiargs.push(exp.newtype);
+ id = new DotTemplateInstanceExp(exp.loc, id, Id._d_newThrowable, tiargs);
+ id = new CallExp(exp.loc, id).expressionSemantic(sc);
+
+ Expression idVal;
+ Expression tmp = extractSideEffect(sc, "__tmpThrowable", idVal, id, true);
+ // auto castTmp = new CastExp(exp.loc, tmp, exp.type);
+
+ auto ctor = new DotIdExp(exp.loc, tmp, Id.ctor).expressionSemantic(sc);
+ auto ctorCall = new CallExp(exp.loc, ctor, exp.arguments);
+
+ id = Expression.combine(idVal, exp.argprefix).expressionSemantic(sc);
+ id = Expression.combine(id, ctorCall).expressionSemantic(sc);
+ // id = Expression.combine(id, castTmp).expressionSemantic(sc);
+
+ result = id.expressionSemantic(sc);
+ return;
+ }
}
else if (auto ts = tb.isTypeStruct())
{
@@ -6582,6 +6612,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
result = e;
return;
}
+ else if (auto ad = exp.var.isAliasDeclaration())
+ {
+ if (auto t = ad.getType())
+ {
+ result = new TypeExp(exp.loc, t).expressionSemantic(sc);
+ return;
+ }
+ }
exp.e1 = exp.e1.addDtorHook(sc);
@@ -7006,9 +7044,19 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
/* Because nested functions cannot be overloaded,
* mark here that we took its address because castTo()
* may not be called with an exact match.
+ *
+ * https://issues.dlang.org/show_bug.cgi?id=19285 :
+ * We also need to make sure we aren't inside a typeof. Ideally the compiler
+ * would do typeof(...) semantic analysis speculatively then collect information
+ * about what it used rather than relying on what are effectively semantically-global
+ * variables but it doesn't.
*/
- if (!ve.hasOverloads || (f.isNested() && !f.needThis()))
+ if (!sc.isFromSpeculativeSemanticContext() && (!ve.hasOverloads || (f.isNested() && !f.needThis())))
+ {
+ // TODO: Refactor to use a proper interface that can keep track of causes.
f.tookAddressOf++;
+ }
+
if (f.isNested() && !f.needThis())
{
if (f.isFuncLiteralDeclaration())
@@ -12855,11 +12903,8 @@ Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag)
if (Declaration v = exp.ti.toAlias().isDeclaration())
{
- if (v.isFuncDeclaration() || v.isVarDeclaration())
- {
- return new DotVarExp(exp.loc, exp.e1, v)
- .expressionSemantic(sc);
- }
+ return new DotVarExp(exp.loc, exp.e1, v)
+ .expressionSemantic(sc);
}
return new DotExp(exp.loc, exp.e1, new ScopeExp(exp.loc, exp.ti))
.expressionSemantic(sc);
@@ -12966,8 +13011,19 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
bool visitVar(VarExp e)
{
- if (!allowRef && e.var.type.isShared())
+ // https://issues.dlang.org/show_bug.cgi?id=22626
+ // Synchronized functions don't need to use core.atomic
+ // when accessing `this`.
+ if (sc.func && sc.func.isSynchronized())
+ {
+ if (e.var.isThisDeclaration())
+ return false;
+ else
+ return sharedError(e);
+ }
+ else if (!allowRef && e.var.type.isShared())
return sharedError(e);
+
return false;
}
@@ -12987,15 +13043,22 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
return check(e.e1, false);
}
+ bool visitThis(ThisExp e)
+ {
+ if (sc.func && sc.func.isSynchronized())
+ return false;
+
+ return sharedError(e);
+ }
+
bool visitDotVar(DotVarExp e)
{
+ //printf("dotvarexp = %s\n", e.toChars());
auto fd = e.var.isFuncDeclaration();
const sharedFunc = fd && fd.type.isShared;
-
- if (!allowRef && e.type.isShared() && !sharedFunc)
- return sharedError(e);
-
// Allow using `DotVarExp` within value types
+ if (!allowRef && e.type.isShared() && !sharedFunc && !(sc.func && sc.func.isSynchronized()))
+ return sharedError(e);
if (e.e1.type.isTypeSArray() || e.e1.type.isTypeStruct())
return check(e.e1, allowRef);
@@ -13044,6 +13107,7 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
case EXP.star: return visitPtr(e.isPtrExp());
case EXP.dotVariable: return visitDotVar(e.isDotVarExp());
case EXP.index: return visitIndex(e.isIndexExp());
+ case EXP.this_: return visitThis(e.isThisExp());
}
}
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 0403948..d429259 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -1773,7 +1773,7 @@ extern (C++) class FuncDeclaration : Declaration
if (!tp)
continue;
- if (fparam.storageClass & (STC.lazy_ | STC.out_ | STC.ref_))
+ if (fparam.isLazy() || fparam.isReference())
{
if (!traverseIndirections(tp, t))
return false;
@@ -2528,7 +2528,7 @@ extern (C++) class FuncDeclaration : Declaration
foreach (n, p; parameterList)
{
p = p.syntaxCopy();
- if (!(p.storageClass & STC.lazy_))
+ if (!p.isLazy())
p.storageClass = (p.storageClass | STC.ref_) & ~STC.out_;
p.defaultArg = null; // won't be the same with ref
result.push(p);
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index 4993a9e..5142daa 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -311,6 +311,7 @@ immutable Msgtable[] msgtable =
{ "__ArrayPostblit" },
{ "__ArrayDtor" },
{ "_d_delThrowable" },
+ { "_d_newThrowable" },
{ "_d_assert_fail" },
{ "dup" },
{ "_aaApply" },
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index 052c23d..6b5389d 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -529,7 +529,6 @@ extern (C++) abstract class Type : ASTNode
* Returns:
* An enum value of either `Covariant.yes` or a reason it's not covariant.
*/
- extern (D)
final Covariant covariant(Type t, StorageClass* pstc = null, bool cppCovariant = false)
{
version (none)
@@ -4361,7 +4360,7 @@ extern (C++) final class TypeFunction : TypeNext
{
foreach (i, fparam; parameterList)
{
- if (fparam.storageClass & STC.lazy_)
+ if (fparam.isLazy())
return true;
}
return false;
@@ -4675,7 +4674,7 @@ extern (C++) final class TypeFunction : TypeNext
Type tprm = p.type;
Type targ = arg.type;
- if (!(p.storageClass & STC.lazy_ && tprm.ty == Tvoid && targ.ty != Tvoid))
+ if (!(p.isLazy() && tprm.ty == Tvoid && targ.ty != Tvoid))
{
const isRef = p.isReference();
wildmatch |= targ.deduceWild(tprm, isRef);
@@ -4718,7 +4717,7 @@ extern (C++) final class TypeFunction : TypeNext
Type targ = arg.type;
Type tprm = wildmatch ? p.type.substWildTo(wildmatch) : p.type;
- if (p.storageClass & STC.lazy_ && tprm.ty == Tvoid && targ.ty != Tvoid)
+ if (p.isLazy() && tprm.ty == Tvoid && targ.ty != Tvoid)
m = MATCH.convert;
else
{
@@ -6825,6 +6824,12 @@ extern (C++) final class Parameter : ASTNode
return null;
}
+ /// Returns: Whether the function parameter is lazy
+ bool isLazy() const @safe pure nothrow @nogc
+ {
+ return (this.storageClass & (STC.lazy_)) != 0;
+ }
+
/// Returns: Whether the function parameter is a reference (out / ref)
bool isReference() const @safe pure nothrow @nogc
{
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 3565913..3e614d8 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -128,6 +128,14 @@ enum VarArgValues
};
typedef unsigned char VarArg;
+enum class Covariant
+{
+ distinct = 0, /// types are distinct
+ yes = 1, /// types are covariant
+ no = 2, /// arguments match as far as overloading goes, but types are not covariant
+ fwdref = 3, /// cannot determine covariance because of forward references
+};
+
class Type : public ASTNode
{
public:
@@ -218,6 +226,7 @@ public:
// kludge for template.isType()
DYNCAST dyncast() const override final { return DYNCAST_TYPE; }
size_t getUniqueID() const;
+ Covariant covariant(Type *, StorageClass * = NULL, bool = false);
const char *toChars() const override;
char *toPrettyChars(bool QualifyTypes = false);
static void _init();
@@ -560,6 +569,8 @@ public:
Expression *defaultArg, UserAttributeDeclaration *userAttribDecl);
Parameter *syntaxCopy();
Type *isLazyArray();
+ bool isLazy() const;
+ bool isReference() const;
// kludge for template.isType()
DYNCAST dyncast() const override { return DYNCAST_PARAMETER; }
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 15b7658..89f8ae3 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -1460,7 +1460,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (token.value != TOK.leftCurly)
{
- error("members of template declaration expected");
+ error("`{` expected after template parameter list, not `%s`", token.toChars());
goto Lerr;
}
decldefs = parseBlock(null);
diff --git a/gcc/d/dmd/scope.h b/gcc/d/dmd/scope.h
index a163e75..b29c599 100644
--- a/gcc/d/dmd/scope.h
+++ b/gcc/d/dmd/scope.h
@@ -147,4 +147,5 @@ struct Scope
structalign_t alignment();
bool isDeprecated() const;
+ bool isFromSpeculativeSemanticContext() const;
};
diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d
index 0654625..a519f3b 100644
--- a/gcc/d/dmd/statement.d
+++ b/gcc/d/dmd/statement.d
@@ -761,7 +761,7 @@ extern (C++) final class ForwardingStatement : Statement
extern (D) this(const ref Loc loc, Statement statement)
{
- auto sym = new ForwardingScopeDsymbol(null);
+ auto sym = new ForwardingScopeDsymbol();
sym.symtab = new DsymbolTable();
this(loc, sym, statement);
}
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index ed47b91..06e28a4 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -502,10 +502,10 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
override void visit(ForwardingStatement ss)
{
assert(ss.sym);
- for (Scope* csc = sc; !ss.sym.forward; csc = csc.enclosing)
+ for (Scope* csc = sc; !ss.sym.parent; csc = csc.enclosing)
{
assert(csc);
- ss.sym.forward = csc.scopesym;
+ ss.sym.parent = csc.scopesym;
}
sc = sc.push(ss.sym);
sc.sbreak = ss;
@@ -2891,7 +2891,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
/* Void-return function can have void / noreturn typed expression
* on return statement.
*/
- const convToVoid = rs.exp.type.ty == Tvoid || rs.exp.type.ty == Tnoreturn;
+ auto texp = rs.exp.type;
+ const convToVoid = texp.ty == Tvoid || texp.ty == Tnoreturn;
if (tbret && tbret.ty == Tvoid || convToVoid)
{
@@ -2903,6 +2904,15 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
rs.exp = rs.exp.expressionSemantic(sc);
}
+ // https://issues.dlang.org/show_bug.cgi?id=23063
+ if (texp.isTypeNoreturn() && !rs.exp.isAssertExp() && !rs.exp.isThrowExp() && !rs.exp.isCallExp())
+ {
+ auto msg = new StringExp(rs.exp.loc, "Accessed expression of type `noreturn`");
+ msg.type = Type.tstring;
+ rs.exp = new AssertExp(rs.loc, IntegerExp.literal!0, msg);
+ rs.exp.type = texp;
+ }
+
/* Replace:
* return exp;
* with:
@@ -3698,6 +3708,13 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
if (oss.tok != TOK.onScopeExit)
{
+ // https://issues.dlang.org/show_bug.cgi?id=23159
+ if (!global.params.useExceptions)
+ {
+ oss.error("`%s` cannot be used with -betterC", Token.toChars(oss.tok));
+ return setError();
+ }
+
// scope(success) and scope(failure) are rewritten to try-catch(-finally) statement,
// so the generated catch block cannot be placed in finally block.
// See also Catch::semantic.
@@ -4312,7 +4329,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
if (!skip && dim == 2)
{
// Declare key
- if (p.storageClass & (STC.out_ | STC.ref_ | STC.lazy_))
+ if (p.isReference() || p.isLazy())
{
fs.error("no storage class for key `%s`", p.ident.toChars());
return returnEarly();
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index 4c9ca28f..31ecbd2 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -64,48 +64,6 @@ import dmd.sideeffect;
import dmd.target;
import dmd.tokens;
-/**************************
- * This evaluates exp while setting length to be the number
- * of elements in the tuple t.
- */
-private Expression semanticLength(Scope* sc, Type t, Expression exp)
-{
- if (auto tt = t.isTypeTuple())
- {
- ScopeDsymbol sym = new ArrayScopeSymbol(sc, tt);
- sym.parent = sc.scopesym;
- sc = sc.push(sym);
- sc = sc.startCTFE();
- exp = exp.expressionSemantic(sc);
- exp = resolveProperties(sc, exp);
- sc = sc.endCTFE();
- sc.pop();
- }
- else
- {
- sc = sc.startCTFE();
- exp = exp.expressionSemantic(sc);
- exp = resolveProperties(sc, exp);
- sc = sc.endCTFE();
- }
- return exp;
-}
-
-private Expression semanticLength(Scope* sc, TupleDeclaration tup, Expression exp)
-{
- ScopeDsymbol sym = new ArrayScopeSymbol(sc, tup);
- sym.parent = sc.scopesym;
-
- sc = sc.push(sym);
- sc = sc.startCTFE();
- exp = exp.expressionSemantic(sc);
- exp = resolveProperties(sc, exp);
- sc = sc.endCTFE();
- sc.pop();
-
- return exp;
-}
-
/*************************************
* Resolve a tuple index, `s[oindex]`, by figuring out what `s[oindex]` represents.
* Setting one of pe/pt/ps.
@@ -452,101 +410,6 @@ private void resolveHelper(TypeQualified mt, const ref Loc loc, Scope* sc, Dsymb
pt = t.merge();
}
-/************************************
- * Transitively search a type for all function types.
- * If any function types with parameters are found that have parameter identifiers
- * or default arguments, remove those and create a new type stripped of those.
- * This is used to determine the "canonical" version of a type which is useful for
- * comparisons.
- * Params:
- * t = type to scan
- * Returns:
- * `t` if no parameter identifiers or default arguments found, otherwise a new type that is
- * the same as t but with no parameter identifiers or default arguments.
- */
-private Type stripDefaultArgs(Type t)
-{
- static Parameters* stripParams(Parameters* parameters)
- {
- static Parameter stripParameter(Parameter p)
- {
- Type t = stripDefaultArgs(p.type);
- return (t != p.type || p.defaultArg || p.ident || p.userAttribDecl)
- ? new Parameter(p.storageClass, t, null, null, null)
- : null;
- }
-
- if (parameters)
- {
- foreach (i, p; *parameters)
- {
- Parameter ps = stripParameter(p);
- if (ps)
- {
- // Replace params with a copy we can modify
- Parameters* nparams = new Parameters(parameters.dim);
-
- foreach (j, ref np; *nparams)
- {
- Parameter pj = (*parameters)[j];
- if (j < i)
- np = pj;
- else if (j == i)
- np = ps;
- else
- {
- Parameter nps = stripParameter(pj);
- np = nps ? nps : pj;
- }
- }
- return nparams;
- }
- }
- }
- return parameters;
- }
-
- if (t is null)
- return t;
-
- if (auto tf = t.isTypeFunction())
- {
- Type tret = stripDefaultArgs(tf.next);
- Parameters* params = stripParams(tf.parameterList.parameters);
- if (tret == tf.next && params == tf.parameterList.parameters)
- return t;
- TypeFunction tr = tf.copy().isTypeFunction();
- tr.parameterList.parameters = params;
- tr.next = tret;
- //printf("strip %s\n <- %s\n", tr.toChars(), t.toChars());
- return tr;
- }
- else if (auto tt = t.isTypeTuple())
- {
- Parameters* args = stripParams(tt.arguments);
- if (args == tt.arguments)
- return t;
- TypeTuple tr = t.copy().isTypeTuple();
- tr.arguments = args;
- return tr;
- }
- else if (t.ty == Tenum)
- {
- // TypeEnum::nextOf() may be != NULL, but it's not necessary here.
- return t;
- }
- else
- {
- Type tn = t.nextOf();
- Type n = stripDefaultArgs(tn);
- if (n == tn)
- return t;
- TypeNext tr = cast(TypeNext)t.copy();
- tr.next = n;
- return tr;
- }
-}
-
/******************************************
* We've mistakenly parsed `t` as a type.
* Redo `t` as an Expression only if there are no type modifiers.
@@ -603,53 +466,6 @@ Expression typeToExpression(Type t)
}
}
-/* Helper function for `typeToExpression`. Contains common code
- * for TypeQualified derived classes.
- */
-Expression typeToExpressionHelper(TypeQualified t, Expression e, size_t i = 0)
-{
- //printf("toExpressionHelper(e = %s %s)\n", EXPtoString(e.op).ptr, e.toChars());
- foreach (id; t.idents[i .. t.idents.dim])
- {
- //printf("\t[%d] e: '%s', id: '%s'\n", i, e.toChars(), id.toChars());
-
- final switch (id.dyncast())
- {
- // ... '. ident'
- case DYNCAST.identifier:
- e = new DotIdExp(e.loc, e, cast(Identifier)id);
- break;
-
- // ... '. name!(tiargs)'
- case DYNCAST.dsymbol:
- auto ti = (cast(Dsymbol)id).isTemplateInstance();
- assert(ti);
- e = new DotTemplateInstanceExp(e.loc, e, ti.name, ti.tiargs);
- break;
-
- // ... '[type]'
- case DYNCAST.type: // https://issues.dlang.org/show_bug.cgi?id=1215
- e = new ArrayExp(t.loc, e, new TypeExp(t.loc, cast(Type)id));
- break;
-
- // ... '[expr]'
- case DYNCAST.expression: // https://issues.dlang.org/show_bug.cgi?id=1215
- e = new ArrayExp(t.loc, e, cast(Expression)id);
- break;
-
- case DYNCAST.object:
- case DYNCAST.tuple:
- case DYNCAST.parameter:
- case DYNCAST.statement:
- case DYNCAST.condition:
- case DYNCAST.templateparameter:
- case DYNCAST.initializer:
- assert(0);
- }
- }
- return e;
-}
-
/******************************************
* Perform semantic analysis on a type.
* Params:
@@ -1431,7 +1247,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
errors = true;
}
}
- else if (!(fparam.storageClass & STC.lazy_) && t.ty == Tvoid)
+ else if (!fparam.isLazy() && t.ty == Tvoid)
{
.error(loc, "cannot have parameter of type `%s`", fparam.type.toChars());
errors = true;
@@ -2157,47 +1973,6 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
}
}
-/******************************************
- * Compile the MixinType, returning the type or expression AST.
- *
- * Doesn't run semantic() on the returned object.
- * Params:
- * tm = mixin to compile as a type or expression
- * loc = location for error messages
- * sc = context
- * Return:
- * null if error, else RootObject AST as parsed
- */
-RootObject compileTypeMixin(TypeMixin tm, Loc loc, Scope* sc)
-{
- OutBuffer buf;
- if (expressionsToString(buf, sc, tm.exps))
- return null;
-
- const errors = global.errors;
- const len = buf.length;
- buf.writeByte(0);
- const str = buf.extractSlice()[0 .. len];
- scope p = new Parser!ASTCodegen(loc, sc._module, str, false);
- p.nextToken();
- //printf("p.loc.linnum = %d\n", p.loc.linnum);
-
- auto o = p.parseTypeOrAssignExp(TOK.endOfFile);
- if (errors != global.errors)
- {
- assert(global.errors != errors); // should have caught all these cases
- return null;
- }
- if (p.token.value != TOK.endOfFile)
- {
- .error(loc, "incomplete mixin type `%s`", str.ptr);
- return null;
- }
-
- return o;
-}
-
-
/************************************
* If an identical type to `type` is in `type.stringtable`, return
* the latter one. Otherwise, add it to `type.stringtable`.
@@ -3243,6 +3018,7 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
{
pt = mt.obj.isType();
ps = mt.obj.isDsymbol();
+ pe = mt.obj.isExpression();
return;
}
@@ -3310,7 +3086,10 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
case EXP.overloadSet:
mt.obj = e.isOverExp().type;
break;
+ case EXP.error:
+ break;
default:
+ mt.obj = e;
break;
}
}
@@ -3318,14 +3097,19 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
if (mt.obj)
{
if (auto t = mt.obj.isType())
- returnType(t.addMod(mt.mod));
+ {
+ t = t.addMod(mt.mod);
+ mt.obj = t;
+ returnType(t);
+ }
else if (auto s = mt.obj.isDsymbol())
returnSymbol(s);
- else
- assert(0);
+ else if (auto e = mt.obj.isExpression())
+ returnExp(e);
}
else
{
+ assert(global.errors);
mt.obj = Type.terror;
return returnError();
}
@@ -4817,6 +4601,193 @@ extern (C++) Expression defaultInit(Type mt, const ref Loc loc, const bool isCfi
}
}
+/******************************* Private *****************************************/
+
+private:
+
+/* Helper function for `typeToExpression`. Contains common code
+ * for TypeQualified derived classes.
+ */
+Expression typeToExpressionHelper(TypeQualified t, Expression e, size_t i = 0)
+{
+ //printf("toExpressionHelper(e = %s %s)\n", EXPtoString(e.op).ptr, e.toChars());
+ foreach (id; t.idents[i .. t.idents.dim])
+ {
+ //printf("\t[%d] e: '%s', id: '%s'\n", i, e.toChars(), id.toChars());
+
+ final switch (id.dyncast())
+ {
+ // ... '. ident'
+ case DYNCAST.identifier:
+ e = new DotIdExp(e.loc, e, cast(Identifier)id);
+ break;
+
+ // ... '. name!(tiargs)'
+ case DYNCAST.dsymbol:
+ auto ti = (cast(Dsymbol)id).isTemplateInstance();
+ assert(ti);
+ e = new DotTemplateInstanceExp(e.loc, e, ti.name, ti.tiargs);
+ break;
+
+ // ... '[type]'
+ case DYNCAST.type: // https://issues.dlang.org/show_bug.cgi?id=1215
+ e = new ArrayExp(t.loc, e, new TypeExp(t.loc, cast(Type)id));
+ break;
+
+ // ... '[expr]'
+ case DYNCAST.expression: // https://issues.dlang.org/show_bug.cgi?id=1215
+ e = new ArrayExp(t.loc, e, cast(Expression)id);
+ break;
+
+ case DYNCAST.object:
+ case DYNCAST.tuple:
+ case DYNCAST.parameter:
+ case DYNCAST.statement:
+ case DYNCAST.condition:
+ case DYNCAST.templateparameter:
+ case DYNCAST.initializer:
+ assert(0);
+ }
+ }
+ return e;
+}
+
+/**************************
+ * This evaluates exp while setting length to be the number
+ * of elements in the tuple t.
+ */
+Expression semanticLength(Scope* sc, Type t, Expression exp)
+{
+ if (auto tt = t.isTypeTuple())
+ {
+ ScopeDsymbol sym = new ArrayScopeSymbol(sc, tt);
+ sym.parent = sc.scopesym;
+ sc = sc.push(sym);
+ sc = sc.startCTFE();
+ exp = exp.expressionSemantic(sc);
+ exp = resolveProperties(sc, exp);
+ sc = sc.endCTFE();
+ sc.pop();
+ }
+ else
+ {
+ sc = sc.startCTFE();
+ exp = exp.expressionSemantic(sc);
+ exp = resolveProperties(sc, exp);
+ sc = sc.endCTFE();
+ }
+ return exp;
+}
+
+Expression semanticLength(Scope* sc, TupleDeclaration tup, Expression exp)
+{
+ ScopeDsymbol sym = new ArrayScopeSymbol(sc, tup);
+ sym.parent = sc.scopesym;
+
+ sc = sc.push(sym);
+ sc = sc.startCTFE();
+ exp = exp.expressionSemantic(sc);
+ exp = resolveProperties(sc, exp);
+ sc = sc.endCTFE();
+ sc.pop();
+
+ return exp;
+}
+
+/************************************
+ * Transitively search a type for all function types.
+ * If any function types with parameters are found that have parameter identifiers
+ * or default arguments, remove those and create a new type stripped of those.
+ * This is used to determine the "canonical" version of a type which is useful for
+ * comparisons.
+ * Params:
+ * t = type to scan
+ * Returns:
+ * `t` if no parameter identifiers or default arguments found, otherwise a new type that is
+ * the same as t but with no parameter identifiers or default arguments.
+ */
+Type stripDefaultArgs(Type t)
+{
+ static Parameters* stripParams(Parameters* parameters)
+ {
+ static Parameter stripParameter(Parameter p)
+ {
+ Type t = stripDefaultArgs(p.type);
+ return (t != p.type || p.defaultArg || p.ident || p.userAttribDecl)
+ ? new Parameter(p.storageClass, t, null, null, null)
+ : null;
+ }
+
+ if (parameters)
+ {
+ foreach (i, p; *parameters)
+ {
+ Parameter ps = stripParameter(p);
+ if (ps)
+ {
+ // Replace params with a copy we can modify
+ Parameters* nparams = new Parameters(parameters.dim);
+
+ foreach (j, ref np; *nparams)
+ {
+ Parameter pj = (*parameters)[j];
+ if (j < i)
+ np = pj;
+ else if (j == i)
+ np = ps;
+ else
+ {
+ Parameter nps = stripParameter(pj);
+ np = nps ? nps : pj;
+ }
+ }
+ return nparams;
+ }
+ }
+ }
+ return parameters;
+ }
+
+ if (t is null)
+ return t;
+
+ if (auto tf = t.isTypeFunction())
+ {
+ Type tret = stripDefaultArgs(tf.next);
+ Parameters* params = stripParams(tf.parameterList.parameters);
+ if (tret == tf.next && params == tf.parameterList.parameters)
+ return t;
+ TypeFunction tr = tf.copy().isTypeFunction();
+ tr.parameterList.parameters = params;
+ tr.next = tret;
+ //printf("strip %s\n <- %s\n", tr.toChars(), t.toChars());
+ return tr;
+ }
+ else if (auto tt = t.isTypeTuple())
+ {
+ Parameters* args = stripParams(tt.arguments);
+ if (args == tt.arguments)
+ return t;
+ TypeTuple tr = t.copy().isTypeTuple();
+ tr.arguments = args;
+ return tr;
+ }
+ else if (t.ty == Tenum)
+ {
+ // TypeEnum::nextOf() may be != NULL, but it's not necessary here.
+ return t;
+ }
+ else
+ {
+ Type tn = t.nextOf();
+ Type n = stripDefaultArgs(tn);
+ if (n == tn)
+ return t;
+ TypeNext tr = cast(TypeNext)t.copy();
+ tr.next = n;
+ return tr;
+ }
+}
/******************************
* Get the value of the .max/.min property of `ed` as an Expression.
@@ -4829,7 +4800,7 @@ extern (C++) Expression defaultInit(Type mt, const ref Loc loc, const bool isCfi
* Returns:
* corresponding value of .max/.min
*/
-private Expression getMaxMinValue(EnumDeclaration ed, const ref Loc loc, Identifier id)
+Expression getMaxMinValue(EnumDeclaration ed, const ref Loc loc, Identifier id)
{
//printf("EnumDeclaration::getMaxValue()\n");
@@ -4935,3 +4906,43 @@ private Expression getMaxMinValue(EnumDeclaration ed, const ref Loc loc, Identif
}
return ed.errors ? errorReturn() : pvalToResult(*pval, loc);
}
+
+/******************************************
+ * Compile the MixinType, returning the type or expression AST.
+ *
+ * Doesn't run semantic() on the returned object.
+ * Params:
+ * tm = mixin to compile as a type or expression
+ * loc = location for error messages
+ * sc = context
+ * Return:
+ * null if error, else RootObject AST as parsed
+ */
+RootObject compileTypeMixin(TypeMixin tm, Loc loc, Scope* sc)
+{
+ OutBuffer buf;
+ if (expressionsToString(buf, sc, tm.exps))
+ return null;
+
+ const errors = global.errors;
+ const len = buf.length;
+ buf.writeByte(0);
+ const str = buf.extractSlice()[0 .. len];
+ scope p = new Parser!ASTCodegen(loc, sc._module, str, false);
+ p.nextToken();
+ //printf("p.loc.linnum = %d\n", p.loc.linnum);
+
+ auto o = p.parseTypeOrAssignExp(TOK.endOfFile);
+ if (errors != global.errors)
+ {
+ assert(global.errors != errors); // should have caught all these cases
+ return null;
+ }
+ if (p.token.value != TOK.endOfFile)
+ {
+ .error(loc, "incomplete mixin type `%s`", str.ptr);
+ return null;
+ }
+
+ return o;
+}
diff --git a/gcc/d/dmd/typinf.d b/gcc/d/dmd/typinf.d
index 21447ae..b701be3 100644
--- a/gcc/d/dmd/typinf.d
+++ b/gcc/d/dmd/typinf.d
@@ -18,6 +18,7 @@ import dmd.dscope;
import dmd.dclass;
import dmd.dstruct;
import dmd.errors;
+import dmd.expression;
import dmd.globals;
import dmd.gluelayer;
import dmd.mtype;
@@ -28,11 +29,12 @@ import core.stdc.stdio;
* Generates the `TypeInfo` object associated with `torig` if it
* hasn't already been generated
* Params:
+ * e = if not null, then expression for pretty-printing errors
* loc = the location for reporting line numbers in errors
* torig = the type to generate the `TypeInfo` object for
* sc = the scope
*/
-extern (C++) void genTypeInfo(const ref Loc loc, Type torig, Scope* sc)
+extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc)
{
// printf("genTypeInfo() %s\n", torig.toChars());
@@ -43,7 +45,10 @@ extern (C++) void genTypeInfo(const ref Loc loc, Type torig, Scope* sc)
{
if (!global.params.useTypeInfo)
{
- .error(loc, "`TypeInfo` cannot be used with -betterC");
+ if (e)
+ .error(loc, "expression `%s` uses the GC and cannot be used with switch `-betterC`", e.toChars());
+ else
+ .error(loc, "`TypeInfo` cannot be used with -betterC");
fatal();
}
}
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 7edcbc4..179f9a5 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -2238,13 +2238,17 @@ public:
new_call = build_nop (type, build_address (var));
setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
}
+ else if (global.params.ehnogc && e->thrownew)
+ {
+ /* Allocating a `@nogc' Exception with `_d_newThrowable' has already
+ been handled by the front-end. */
+ gcc_unreachable ();
+ }
else
{
/* Generate: _d_newclass() */
tree arg = build_address (get_classinfo_decl (cd));
- libcall_fn libcall = (global.params.ehnogc && e->thrownew)
- ? LIBCALL_NEWTHROW : LIBCALL_NEWCLASS;
- new_call = build_libcall (libcall, tb, 1, arg);
+ new_call = build_libcall (LIBCALL_NEWCLASS, tb, 1, arg);
}
/* Set the context pointer for nested classes. */
diff --git a/gcc/d/runtime.def b/gcc/d/runtime.def
index 1ad0369..459a283 100644
--- a/gcc/d/runtime.def
+++ b/gcc/d/runtime.def
@@ -61,7 +61,6 @@ DEF_D_RUNTIME (ARRAYBOUNDS_INDEXP, "_d_arraybounds_indexp", RT(VOID),
/* Used when calling new on a class. */
DEF_D_RUNTIME (NEWCLASS, "_d_newclass", RT(OBJECT), P1(CONST_CLASSINFO), 0)
-DEF_D_RUNTIME (NEWTHROW, "_d_newThrowable", RT(OBJECT), P1(CONST_CLASSINFO), 0)
/* Used when calling delete on a stack-allocated class or interface. */
DEF_D_RUNTIME (CALLFINALIZER, "_d_callfinalizer", RT(VOID), P1(VOIDPTR), 0)
diff --git a/gcc/testsuite/gdc.test/compilable/imports/defines.c b/gcc/testsuite/gdc.test/compilable/imports/defines.c
new file mode 100644
index 0000000..6bd0736
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/imports/defines.c
@@ -0,0 +1,28 @@
+/* */
+
+#define CC 'c'
+_Static_assert(CC == 'c', "1");
+
+#define I32 3
+_Static_assert(I32 == 3, "3");
+
+#define U32 4U
+_Static_assert(U32 == 4U, "4");
+
+#define I64 5L
+_Static_assert(I64 == 5U, "5");
+
+#define U64 6UL
+_Static_assert(U64 == 6UL, "6");
+
+#define F32 7.0f
+_Static_assert(F32 == 7.0f, "7");
+
+#define F64 8.0f
+_Static_assert(F64 == 8.0, "8");
+
+#define F80 9.0f
+_Static_assert(F80 == 9.0L, "9");
+
+#define SSS "hello"
+_Static_assert(SSS[0] == 'h', "10");
diff --git a/gcc/testsuite/gdc.test/compilable/nogc.d b/gcc/testsuite/gdc.test/compilable/nogc.d
index 2751801..6ce5094 100644
--- a/gcc/testsuite/gdc.test/compilable/nogc.d
+++ b/gcc/testsuite/gdc.test/compilable/nogc.d
@@ -109,3 +109,12 @@ auto foo13550() @nogc
}
return &bar;
}
+
+// https://issues.dlang.org/show_bug.cgi?id=19285
+
+void f(bool cond, string s) @nogc {
+ auto inner() { return s; }
+ alias Unused1 = typeof(inner); // OK
+ alias Unused2 = typeof(&inner); // (Does not) INFERS GC (anymore)
+ enum Unused3 = __traits(compiles , &inner);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22626.d b/gcc/testsuite/gdc.test/compilable/test22626.d
new file mode 100644
index 0000000..5f72eb6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22626.d
@@ -0,0 +1,23 @@
+// https://issues.dlang.org/show_bug.cgi?id=22626
+// REQUIRED_ARGS: -preview=nosharedaccess
+
+shared int k;
+
+class Oops
+{
+ shared int a;
+ shared int* pa;
+ synchronized void oops()
+ {
+ // this should compile since the function is synchronized
+ // and `a` is accessed through `this`.
+ a = 2;
+
+ // this shouldn't compile because synchronized guards
+ // only accesses to the first level of dereferencing
+ static assert (!__traits(compiles, *pa = 2));
+
+ // this shouldn't compile `k` is a field of class `Oops`
+ static assert (!__traits(compiles, k = 2));
+ }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23076.d b/gcc/testsuite/gdc.test/compilable/test23076.d
new file mode 100644
index 0000000..10a0c2f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23076.d
@@ -0,0 +1,38 @@
+/* REQUIRED_ARGS: -O -inline
+ */
+
+// https://issues.dlang.org/show_bug.cgi?id=23076
+
+struct S
+{
+ int depthLow = 0;
+ int depthHigh = 30000;
+
+ void fun(int* pixels)
+ {
+ float b = depthLow;
+ int depthA = cast(int)(b);
+ int depthB = cast(short)(cast(float)depthHigh * cast(float)depthLow);
+ pixels[depthA] = depthB;
+ }
+}
+
+/**********************/
+
+float mul3(float a, float b, float t)
+{
+ return t * b * a;
+}
+
+class A
+{
+ ushort depthLow = 0;
+ ushort depthHigh = 30000;
+
+ void fun(short* pixels)
+ {
+ short depthA = (cast(short)(mul3(depthHigh, depthLow, 0)));
+ short depthB = (cast(short)(mul3(depthLow, depthHigh, 0)));
+ pixels[depthA] = depthB;
+ }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23142.d b/gcc/testsuite/gdc.test/compilable/test23142.d
new file mode 100644
index 0000000..28bb691
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23142.d
@@ -0,0 +1,19 @@
+// https://issues.dlang.org/show_bug.cgi?id=23142
+
+struct Foo
+{
+ int x;
+
+scope:
+ void func()
+ {
+ }
+
+ unittest
+ {
+ }
+
+ static void func2()
+ {
+ }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23174.d b/gcc/testsuite/gdc.test/compilable/test23174.d
new file mode 100644
index 0000000..9047fd7
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23174.d
@@ -0,0 +1,58 @@
+// https://issues.dlang.org/show_bug.cgi?id=23174
+
+alias AliasSeq(T...) = T;
+
+template staticMap(alias fun, args...)
+{
+ alias staticMap = AliasSeq!();
+ static foreach(arg; args)
+ staticMap = AliasSeq!(staticMap, fun!arg);
+}
+
+template Filter(alias pred, args...)
+{
+ alias Filter = AliasSeq!();
+ static foreach (arg; args)
+ static if (pred!arg)
+ Filter = AliasSeq!(Filter, arg);
+}
+
+struct Fields(T)
+{
+ private static alias toField(alias e) = Field!(__traits(identifier, e));
+ alias fields = staticMap!(toField, T.tupleof);
+
+ static alias map(alias F) = staticMap!(F, fields);
+ static alias filter(alias pred) = Filter!(pred, fields);
+}
+
+struct Field(string n)
+{
+ enum name = n;
+}
+
+struct Foo
+{
+ int a;
+}
+
+void test23174()
+{
+ Foo value;
+
+ enum toName(alias e) = e.name;
+ enum pred(alias e) = true;
+
+ alias a = Fields!(Foo).filter!(pred); // works
+ static assert(is(a == AliasSeq!(Field!"a")));
+
+ alias b = Fields!(Foo).map!(toName); // works
+ static assert(b == AliasSeq!("a"));
+
+ alias c = Fields!(Foo).init.filter!(pred); // works
+ static assert(is(c == AliasSeq!(Field!"a")));
+
+ // OK <- Error: alias `d` cannot alias an expression `Fields().tuple("a")`
+ alias d = Fields!(Foo).init.map!(toName);
+ static assert(d == AliasSeq!("a"));
+}
diff --git a/gcc/testsuite/gdc.test/compilable/testdefines.d b/gcc/testsuite/gdc.test/compilable/testdefines.d
new file mode 100644
index 0000000..4507266
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/testdefines.d
@@ -0,0 +1,14 @@
+// EXTRA_FILES: imports/defines.c
+import imports.defines;
+
+static assert(CC == 'c');
+static assert(I32 == 3);
+static assert(U32 == 4);
+static assert(I64 == 5);
+static assert(U64 == 6);
+
+static assert(F32 == 7.0f);
+static assert(F64 == 8.0);
+static assert(F80 == 9.0L);
+
+static assert(SSS == "hello");
diff --git a/gcc/testsuite/gdc.test/compilable/testdip1008.d b/gcc/testsuite/gdc.test/compilable/testdip1008.d
index 5e024fe..54d404c 100644
--- a/gcc/testsuite/gdc.test/compilable/testdip1008.d
+++ b/gcc/testsuite/gdc.test/compilable/testdip1008.d
@@ -13,9 +13,28 @@ int bar()
}
}
+void throwQualifiers() @safe @nogc pure
+{
+ throw new Exception("baz");
+}
+
+bool testThrowQualifiers()
+{
+ try
+ {
+ throwQualifiers();
+ } catch (Exception e)
+ {
+ return true;
+ }
+
+ return false;
+}
void foo()
{
enum r = bar();
static assert(r == 7);
+
+ static assert(testThrowQualifiers());
}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/mixin_template.d b/gcc/testsuite/gdc.test/fail_compilation/mixin_template.d
new file mode 100644
index 0000000..b088da8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/mixin_template.d
@@ -0,0 +1,10 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/mixin_template.d(10): Error: mixin `mixin_template.f!1` - `f` is a function, not a template
+---
+*/
+string f() {
+ return "int i;";
+}
+mixin f!1;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/noreturn.d b/gcc/testsuite/gdc.test/fail_compilation/noreturn.d
index 696081a..d47d449 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/noreturn.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/noreturn.d
@@ -118,3 +118,21 @@ enum forceInClassRef = inClassRef();
*/
enum throwEnum = throw new Exception("");
+
+
+/*
+https://issues.dlang.org/show_bug.cgi?id=23063
+
+TEST_OUTPUT:
+---
+fail_compilation/noreturn.d(135): Error: `"Accessed expression of type `noreturn`"`
+fail_compilation/noreturn.d(138): called from here: `func()`
+---
+*/
+noreturn func()
+{
+ noreturn a;
+ return a;
+}
+
+enum f = func();
diff --git a/gcc/testsuite/gdc.test/fail_compilation/template_decl.d b/gcc/testsuite/gdc.test/fail_compilation/template_decl.d
new file mode 100644
index 0000000..d986dd6
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/template_decl.d
@@ -0,0 +1,9 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/template_decl.d(8): Error: `{` expected after template parameter list, not `(`
+fail_compilation/template_decl.d(8): Error: declaration expected, not `(`
+---
+*/
+template b(alias d)() {
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21477.d b/gcc/testsuite/gdc.test/fail_compilation/test21477.d
new file mode 100644
index 0000000..c9c7c7f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21477.d
@@ -0,0 +1,16 @@
+/* REQUIRED_ARGS: -betterC
+TEST_OUTPUT:
+---
+fail_compilation/test21477.d(103): Error: expression `[1]` uses the GC and cannot be used with switch `-betterC`
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=21477
+
+#line 100
+
+int test()
+{
+ int[] foo = [1];
+ return 0;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23159.d b/gcc/testsuite/gdc.test/fail_compilation/test23159.d
new file mode 100644
index 0000000..cdafc61
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23159.d
@@ -0,0 +1,22 @@
+// https://issues.dlang.org/show_bug.cgi?id=23159
+
+// REQUIRED_ARGS: -betterC
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test23159.d(14): Error: `scope(failure)` cannot be used with -betterC
+fail_compilation/test23159.d(18): Error: `scope(success)` cannot be used with -betterC
+---
+*/
+
+void main()
+{
+ scope(failure)
+ {
+ int a;
+ }
+ scope(success)
+ {
+ int a;
+ }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/traits.d b/gcc/testsuite/gdc.test/fail_compilation/traits.d
index 8c16afe..21f3f57 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/traits.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/traits.d
@@ -116,3 +116,21 @@ pragma(msg, __traits(hasCopyConstructor));
pragma(msg, __traits(hasCopyConstructor, S()));
pragma(msg, __traits(hasPostblit));
pragma(msg, __traits(hasPostblit, S()));
+
+/********************************************
+https://issues.dlang.org/show_bug.cgi?id=23178
+
+TEST_OUTPUT:
+---
+fail_compilation/traits.d(701): Error: alias `traits.a` cannot alias an expression `true`
+fail_compilation/traits.d(702): Error: alias `traits.b` cannot alias an expression `false`
+fail_compilation/traits.d(703): Error: alias `traits.c` cannot alias an expression `"Object"`
+fail_compilation/traits.d(704): while evaluating `pragma(msg, a)`
+---
+*/
+#line 700
+
+alias a = __traits(compiles, 1);
+alias b = __traits(isIntegral, 1.1);
+alias c = __traits(identifier, Object);
+pragma(msg, a, b, c);
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index d503bae..8b2839d 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-f89da31331ef5df50d3bc7a26efd1b7acdefde8c
+454471d8077d12ec6bf0ae8fcd9571aad1bce7be
The first line of this file holds the git revision number of the last
merge done from the dlang/druntime repository.
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 260bb63..d963aa9 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -200,9 +200,9 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/stdc/tgmath.d core/stdc/time.d core/stdc/wchar_.d \
core/stdc/wctype.d core/sync/barrier.d core/sync/condition.d \
core/sync/config.d core/sync/event.d core/sync/exception.d \
- core/sync/mutex.d core/sync/rwmutex.d core/sync/semaphore.d \
- core/thread/context.d core/thread/fiber.d core/thread/osthread.d \
- core/thread/package.d core/thread/threadbase.d \
+ core/sync/mutex.d core/sync/package.d core/sync/rwmutex.d \
+ core/sync/semaphore.d core/thread/context.d core/thread/fiber.d \
+ core/thread/osthread.d core/thread/package.d core/thread/threadbase.d \
core/thread/threadgroup.d core/thread/types.d core/time.d \
core/vararg.d core/volatile.d gcc/attribute.d gcc/attributes.d \
gcc/backtrace.d gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index b7e2f34..45e086a 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -226,17 +226,18 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
core/stdc/tgmath.lo core/stdc/time.lo core/stdc/wchar_.lo \
core/stdc/wctype.lo core/sync/barrier.lo \
core/sync/condition.lo core/sync/config.lo core/sync/event.lo \
- core/sync/exception.lo core/sync/mutex.lo core/sync/rwmutex.lo \
- core/sync/semaphore.lo core/thread/context.lo \
- core/thread/fiber.lo core/thread/osthread.lo \
- core/thread/package.lo core/thread/threadbase.lo \
- core/thread/threadgroup.lo core/thread/types.lo core/time.lo \
- core/vararg.lo core/volatile.lo gcc/attribute.lo \
- gcc/attributes.lo gcc/backtrace.lo gcc/builtins.lo gcc/deh.lo \
- gcc/emutls.lo gcc/gthread.lo gcc/sections/common.lo \
- gcc/sections/elf.lo gcc/sections/macho.lo \
- gcc/sections/package.lo gcc/sections/pecoff.lo \
- gcc/unwind/arm.lo gcc/unwind/arm_common.lo gcc/unwind/c6x.lo \
+ core/sync/exception.lo core/sync/mutex.lo core/sync/package.lo \
+ core/sync/rwmutex.lo core/sync/semaphore.lo \
+ core/thread/context.lo core/thread/fiber.lo \
+ core/thread/osthread.lo core/thread/package.lo \
+ core/thread/threadbase.lo core/thread/threadgroup.lo \
+ core/thread/types.lo core/time.lo core/vararg.lo \
+ core/volatile.lo gcc/attribute.lo gcc/attributes.lo \
+ gcc/backtrace.lo gcc/builtins.lo gcc/deh.lo gcc/emutls.lo \
+ gcc/gthread.lo gcc/sections/common.lo gcc/sections/elf.lo \
+ gcc/sections/macho.lo gcc/sections/package.lo \
+ gcc/sections/pecoff.lo gcc/unwind/arm.lo \
+ gcc/unwind/arm_common.lo gcc/unwind/c6x.lo \
gcc/unwind/generic.lo gcc/unwind/package.lo gcc/unwind/pe.lo \
object.lo rt/aApply.lo rt/aApplyR.lo rt/aaA.lo rt/adi.lo \
rt/arrayassign.lo rt/arraycat.lo rt/cast_.lo rt/config.lo \
@@ -866,9 +867,9 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/stdc/tgmath.d core/stdc/time.d core/stdc/wchar_.d \
core/stdc/wctype.d core/sync/barrier.d core/sync/condition.d \
core/sync/config.d core/sync/event.d core/sync/exception.d \
- core/sync/mutex.d core/sync/rwmutex.d core/sync/semaphore.d \
- core/thread/context.d core/thread/fiber.d core/thread/osthread.d \
- core/thread/package.d core/thread/threadbase.d \
+ core/sync/mutex.d core/sync/package.d core/sync/rwmutex.d \
+ core/sync/semaphore.d core/thread/context.d core/thread/fiber.d \
+ core/thread/osthread.d core/thread/package.d core/thread/threadbase.d \
core/thread/threadgroup.d core/thread/types.d core/time.d \
core/vararg.d core/volatile.d gcc/attribute.d gcc/attributes.d \
gcc/backtrace.d gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
@@ -1305,6 +1306,7 @@ core/sync/config.lo: core/sync/$(am__dirstamp)
core/sync/event.lo: core/sync/$(am__dirstamp)
core/sync/exception.lo: core/sync/$(am__dirstamp)
core/sync/mutex.lo: core/sync/$(am__dirstamp)
+core/sync/package.lo: core/sync/$(am__dirstamp)
core/sync/rwmutex.lo: core/sync/$(am__dirstamp)
core/sync/semaphore.lo: core/sync/$(am__dirstamp)
core/thread/$(am__dirstamp):
diff --git a/libphobos/libdruntime/core/attribute.d b/libphobos/libdruntime/core/attribute.d
index 69b20f0..8a1dc8a 100644
--- a/libphobos/libdruntime/core/attribute.d
+++ b/libphobos/libdruntime/core/attribute.d
@@ -76,14 +76,14 @@ else
* The attribute can only be attached to methods or constructors which
* have Objective-C linkage. That is, a method or a constructor in a
* class or interface declared as $(D_CODE extern(Objective-C)).
- * ),
+ * )
*
- * $(LI It cannot be attached to a method or constructor that is a template),
+ * $(LI It cannot be attached to a method or constructor that is a template)
*
* $(LI
* The number of colons in the string need to match the number of
* arguments the method accept.
- * ),
+ * )
*
* $(LI It can only be used once in a method declaration)
* )
@@ -181,21 +181,21 @@ version (UdaOptional)
* $(UL
* $(LI
* There can only be one such attribute per symbol.
- * ),
+ * )
* $(LI
* The attribute can only be attached to an `extern(C++)` symbol
* (`struct`, `class`, `enum`, function, and their templated counterparts).
- * ),
+ * )
* $(LI
* The attribute cannot be applied to C++ namespaces.
* This is to prevent confusion with the C++ semantic, which allows it to
* be applied to namespaces.
- * ),
+ * )
* $(LI
* The string arguments must only contain valid characters
* for C++ name mangling which currently include alphanumerics
* and the underscore character.
- * ),
+ * )
* )
*
* This UDA is not transitive, and inner scope do not inherit outer scopes'
@@ -252,11 +252,11 @@ version (UdaGNUAbiTag) struct gnuAbiTag
* $(LI
* the expression is the top-level expression in a statement or the
* left-hand expression in a comma expression, and
- * ),
+ * )
* $(LI
* the expression is not an assignment (`=`, `+=`, etc.), increment
* (`++`), or decrement (`--`) expression.
- * ),
+ * )
* )
*
* If the declaration of a `struct` or `union` type has the `@mustuse`
diff --git a/libphobos/libdruntime/core/internal/array/equality.d b/libphobos/libdruntime/core/internal/array/equality.d
index b12e2f2..d3fdd65 100644
--- a/libphobos/libdruntime/core/internal/array/equality.d
+++ b/libphobos/libdruntime/core/internal/array/equality.d
@@ -21,8 +21,7 @@ bool __equals(T1, T2)(scope const T1[] lhs, scope const T2[] rhs)
@nogc nothrow pure @trusted
if (__traits(isScalar, T1) && __traits(isScalar, T2))
{
- if (lhs.length != rhs.length)
- return false;
+ const length = lhs.length;
static if (T1.sizeof == T2.sizeof
// Signedness needs to match for types that promote to int.
@@ -31,20 +30,21 @@ if (__traits(isScalar, T1) && __traits(isScalar, T2))
&& (T1.sizeof >= 4 || __traits(isUnsigned, T1) == __traits(isUnsigned, T2))
&& !__traits(isFloating, T1) && !__traits(isFloating, T2))
{
- if (!__ctfe)
+ if (__ctfe)
+ return length == rhs.length && isEqual(lhs.ptr, rhs.ptr, length);
+ else
{
// This would improperly allow equality of integers and pointers
// but the CTFE branch will stop this function from compiling then.
import core.stdc.string : memcmp;
- return lhs.length == 0 ||
- 0 == memcmp(cast(const void*) lhs.ptr, cast(const void*) rhs.ptr, lhs.length * T1.sizeof);
+ return length == rhs.length &&
+ (!length || 0 == memcmp(cast(const void*) lhs.ptr, cast(const void*) rhs.ptr, length * T1.sizeof));
}
}
-
- foreach (const i; 0 .. lhs.length)
- if (lhs.ptr[i] != rhs.ptr[i])
- return false;
- return true;
+ else
+ {
+ return length == rhs.length && isEqual(lhs.ptr, rhs.ptr, length);
+ }
}
bool __equals(T1, T2)(scope T1[] lhs, scope T2[] rhs)
@@ -89,6 +89,19 @@ if (!__traits(isScalar, T1) || !__traits(isScalar, T2))
}
}
+/******************************
+ * Helper function for __equals().
+ * Outlined to enable __equals() to be inlined, as dmd cannot inline loops.
+ */
+private
+bool isEqual(T1, T2)(scope const T1* t1, scope const T2* t2, size_t length)
+{
+ foreach (const i; 0 .. length)
+ if (t1[i] != t2[i])
+ return false;
+ return true;
+}
+
@safe unittest
{
assert(__equals([], []));
diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d
index 6502e59..371308d 100644
--- a/libphobos/libdruntime/core/lifetime.d
+++ b/libphobos/libdruntime/core/lifetime.d
@@ -2648,16 +2648,19 @@ if (!Init.length ||
}
/**
- * Allocate an exception of type `T` from the exception pool and call its constructor.
- * It has the same interface as `rt.lifetime._d_newclass()`.
- * `T` must be Throwable or derived from it, must declare an explicit ctor
- * and cannot be a COM or C++ class.
+ * Allocate an exception of type `T` from the exception pool.
+ * `T` must be `Throwable` or derived from it and cannot be a COM or C++ class.
+ *
+ * Note:
+ * This function does not call the constructor of `T` because that would require
+ * `forward!args`, which causes errors with -dip1008. This inconvenience will be
+ * removed once -dip1008 works as intended.
+ *
* Returns:
- * constructed instance of the type
+ * allocated instance of type `T`
*/
-T _d_newThrowable(T, Args...)(auto ref Args args) @trusted
- if (is(T : Throwable) && is(typeof(T.__ctor(forward!args))) &&
- __traits(getLinkage, T) == "D")
+T _d_newThrowable(T)() @trusted
+ if (is(T : Throwable) && __traits(getLinkage, T) == "D")
{
debug(PRINTF) printf("_d_newThrowable(%s)\n", cast(char*) T.stringof);
@@ -2687,33 +2690,22 @@ T _d_newThrowable(T, Args...)(auto ref Args args) @trusted
(cast(Throwable) p).refcount() = 1;
- auto t = cast(T) p;
- t.__ctor(forward!args);
-
- return t;
+ return cast(T) p;
}
@system unittest
{
class E : Exception
{
- int x;
-
- this(int x, string msg = "", Throwable nextInChain = null)
+ this(string msg = "", Throwable nextInChain = null)
{
super(msg, nextInChain);
- this.x = x;
}
}
- auto exc = _d_newThrowable!Exception("Exception");
- assert(exc.refcount() == 1);
- assert(exc.msg == "Exception");
-
- static assert(!__traits(compiles, _d_newThrowable!E()));
+ Throwable exc = _d_newThrowable!Exception();
+ Throwable e = _d_newThrowable!E();
- auto e = _d_newThrowable!E(42, "E", null);
+ assert(exc.refcount() == 1);
assert(e.refcount() == 1);
- assert(e.x == 42);
- assert(e.msg == "E");
}
diff --git a/libphobos/libdruntime/core/stdcpp/xutility.d b/libphobos/libdruntime/core/stdcpp/xutility.d
index fa61701..0142d0b9 100644
--- a/libphobos/libdruntime/core/stdcpp/xutility.d
+++ b/libphobos/libdruntime/core/stdcpp/xutility.d
@@ -23,14 +23,27 @@ else
enum StdNamespace = "std";
}
+/**
+ * Possible values of the `__cplusplus` macro provided by C++ compilers
+ *
+ * For foolproofness, use ordering comparison, e.g. `__cplusplus >= CppStdRevision.cpp17`.
+ */
enum CppStdRevision : uint
{
cpp98 = 199711,
cpp11 = 201103,
cpp14 = 201402,
- cpp17 = 201703
+ cpp17 = 201703,
+ cpp20 = 202002,
}
+/**
+ * Returns the target C++ version, encoded as C++ compilers do
+ *
+ * C++ compilers provide a `__cplusplus` macro which returns an integer
+ * representing the targetted standard. This manifest provides the same
+ * interface, retrieved from the compiler via a `__traits`.
+ */
enum __cplusplus = __traits(getTargetInfo, "cppStd");
// wrangle C++ features
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/sys/elf32.d b/libphobos/libdruntime/core/sys/dragonflybsd/sys/elf32.d
index 2662fdb..c796cd8 100644
--- a/libphobos/libdruntime/core/sys/dragonflybsd/sys/elf32.d
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/sys/elf32.d
@@ -18,6 +18,16 @@ alias Elf32_Word Elf32_Hashelt;
alias Elf32_Word Elf32_Size;
alias Elf32_Sword Elf32_Ssize;
+struct Elf32_Dyn
+{
+ Elf32_Sword d_tag;
+ union _d_un
+ {
+ Elf32_Word d_val;
+ Elf32_Addr d_ptr;
+ } _d_un d_un;
+}
+
alias Elf_Note Elf32_Nhdr;
struct Elf32_Cap
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/sys/elf64.d b/libphobos/libdruntime/core/sys/dragonflybsd/sys/elf64.d
index 6431bd2..89e3ca3 100644
--- a/libphobos/libdruntime/core/sys/dragonflybsd/sys/elf64.d
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/sys/elf64.d
@@ -18,6 +18,16 @@ alias Elf64_Word Elf64_Hashelt;
alias Elf64_Xword Elf64_Size;
alias Elf64_Sxword Elf64_Ssize;
+struct Elf64_Dyn
+{
+ Elf64_Sxword d_tag;
+ union _d_un
+ {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } _d_un d_un;
+}
+
extern (D) pure
{
auto ELF64_R_TYPE_DATA(I)(I i) { return (cast(Elf64_Xword) i << 32) >> 40; }
diff --git a/libphobos/libdruntime/core/sys/elf/package.d b/libphobos/libdruntime/core/sys/elf/package.d
index 5de897a..69e5209 100644
--- a/libphobos/libdruntime/core/sys/elf/package.d
+++ b/libphobos/libdruntime/core/sys/elf/package.d
@@ -617,26 +617,6 @@ enum PF_R = (1 << 2);
enum PF_MASKOS = 0x0ff00000;
enum PF_MASKPROC = 0xf0000000;
-struct Elf32_Dyn
-{
- Elf32_Sword d_tag;
- union _d_un
- {
- Elf32_Word d_val;
- Elf32_Addr d_ptr;
- } _d_un d_un;
-}
-
-struct Elf64_Dyn
-{
- Elf64_Sxword d_tag;
- union _d_un
- {
- Elf64_Xword d_val;
- Elf64_Addr d_ptr;
- } _d_un d_un;
-}
-
enum DT_NULL = 0;
enum DT_NEEDED = 1;
enum DT_PLTRELSZ = 2;
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/elf32.d b/libphobos/libdruntime/core/sys/freebsd/sys/elf32.d
index 134cdf0..4e8ae28 100644
--- a/libphobos/libdruntime/core/sys/freebsd/sys/elf32.d
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/elf32.d
@@ -18,6 +18,16 @@ alias Elf32_Word Elf32_Hashelt;
alias Elf32_Word Elf32_Size;
alias Elf32_Sword Elf32_Ssize;
+struct Elf32_Dyn
+{
+ Elf32_Sword d_tag;
+ union _d_un
+ {
+ Elf32_Word d_val;
+ Elf32_Addr d_ptr;
+ } _d_un d_un;
+}
+
alias Elf_Note Elf32_Nhdr;
struct Elf32_Cap
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/elf64.d b/libphobos/libdruntime/core/sys/freebsd/sys/elf64.d
index 6952821..c56460c 100644
--- a/libphobos/libdruntime/core/sys/freebsd/sys/elf64.d
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/elf64.d
@@ -18,6 +18,16 @@ alias Elf64_Word Elf64_Hashelt;
alias Elf64_Xword Elf64_Size;
alias Elf64_Sxword Elf64_Ssize;
+struct Elf64_Dyn
+{
+ Elf64_Sxword d_tag;
+ union _d_un
+ {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } _d_un d_un;
+}
+
extern (D)
{
auto ELF64_R_TYPE_DATA(I)(I i) { return (cast(Elf64_Xword) i << 32) >> 40; }
diff --git a/libphobos/libdruntime/core/sys/linux/elf.d b/libphobos/libdruntime/core/sys/linux/elf.d
index 2cd93317..168b936 100644
--- a/libphobos/libdruntime/core/sys/linux/elf.d
+++ b/libphobos/libdruntime/core/sys/linux/elf.d
@@ -75,6 +75,26 @@ enum NT_ARM_HW_WATCH = 0x403;
enum NT_VERSION = 1;
+struct Elf32_Dyn
+{
+ Elf32_Sword d_tag;
+ union _d_un
+ {
+ Elf32_Word d_val;
+ Elf32_Addr d_ptr;
+ } _d_un d_un;
+}
+
+struct Elf64_Dyn
+{
+ Elf64_Sxword d_tag;
+ union _d_un
+ {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } _d_un d_un;
+}
+
enum NT_GNU_ABI_TAG = 1;
enum NT_GNU_HWCAP = 2;
enum NT_GNU_BUILD_ID = 3;
diff --git a/libphobos/libdruntime/core/sys/netbsd/sys/elf32.d b/libphobos/libdruntime/core/sys/netbsd/sys/elf32.d
index ce7d8ba..48386f6 100644
--- a/libphobos/libdruntime/core/sys/netbsd/sys/elf32.d
+++ b/libphobos/libdruntime/core/sys/netbsd/sys/elf32.d
@@ -18,6 +18,16 @@ alias Elf32_Word Elf32_Hashelt;
alias Elf32_Word Elf32_Size;
alias Elf32_Sword Elf32_Ssize;
+struct Elf32_Dyn
+{
+ Elf32_Sword d_tag;
+ union _d_un
+ {
+ Elf32_Word d_val;
+ Elf32_Addr d_ptr;
+ } _d_un d_un;
+}
+
alias Elf_Note Elf32_Nhdr;
struct Elf32_Cap
diff --git a/libphobos/libdruntime/core/sys/netbsd/sys/elf64.d b/libphobos/libdruntime/core/sys/netbsd/sys/elf64.d
index 7fa9a8b..3eeaa90 100644
--- a/libphobos/libdruntime/core/sys/netbsd/sys/elf64.d
+++ b/libphobos/libdruntime/core/sys/netbsd/sys/elf64.d
@@ -18,6 +18,16 @@ alias Elf64_Word Elf64_Hashelt;
alias Elf64_Xword Elf64_Size;
alias Elf64_Sxword Elf64_Ssize;
+struct Elf64_Dyn
+{
+ Elf64_Sxword d_tag;
+ union _d_un
+ {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } _d_un d_un;
+}
+
extern (D)
{
auto ELF64_R_TYPE_DATA(I)(I i) { return (cast(Elf64_Xword) i << 32) >> 40; }
diff --git a/libphobos/libdruntime/core/sys/openbsd/sys/elf32.d b/libphobos/libdruntime/core/sys/openbsd/sys/elf32.d
index 342282b..c561121 100644
--- a/libphobos/libdruntime/core/sys/openbsd/sys/elf32.d
+++ b/libphobos/libdruntime/core/sys/openbsd/sys/elf32.d
@@ -19,6 +19,16 @@ alias Elf32_Word Elf32_Hashelt;
alias Elf32_Word Elf32_Size;
alias Elf32_Sword Elf32_Ssize;
+struct Elf32_Dyn
+{
+ Elf32_Sword d_tag;
+ union _d_un
+ {
+ Elf32_Word d_val;
+ Elf32_Addr d_ptr;
+ } _d_un d_un;
+}
+
alias Elf_Note Elf32_Nhdr;
struct Elf32_Cap
diff --git a/libphobos/libdruntime/core/sys/openbsd/sys/elf64.d b/libphobos/libdruntime/core/sys/openbsd/sys/elf64.d
index b76d669..47f84d4 100644
--- a/libphobos/libdruntime/core/sys/openbsd/sys/elf64.d
+++ b/libphobos/libdruntime/core/sys/openbsd/sys/elf64.d
@@ -19,6 +19,16 @@ alias Elf64_Word Elf64_Hashelt;
alias Elf64_Xword Elf64_Size;
alias Elf64_Sxword Elf64_Ssize;
+struct Elf64_Dyn
+{
+ Elf64_Sxword d_tag;
+ union _d_un
+ {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } _d_un d_un;
+}
+
extern (D) pure
{
auto ELF64_R_TYPE_DATA(I)(I i) { return (cast(Elf64_Xword) i << 32) >> 40; }
diff --git a/libphobos/libdruntime/core/sys/solaris/sys/elftypes.d b/libphobos/libdruntime/core/sys/solaris/sys/elftypes.d
index a43cc5a..fe8cfef 100644
--- a/libphobos/libdruntime/core/sys/solaris/sys/elftypes.d
+++ b/libphobos/libdruntime/core/sys/solaris/sys/elftypes.d
@@ -11,18 +11,12 @@ nothrow:
import core.stdc.stdint;
-alias uint32_t Elf32_Addr;
-alias uint16_t Elf32_Half;
-alias uint32_t Elf32_Off;
-alias int32_t Elf32_Sword;
-alias uint32_t Elf32_Word;
+public import core.sys.elf :
+ Elf32_Addr, Elf32_Half, Elf32_Off,
+ Elf32_Sword, Elf32_Word,
+ Elf64_Addr, Elf64_Half, Elf64_Off,
+ Elf64_Sword, Elf64_Sxword,
+ Elf64_Word, Elf64_Xword;
-alias uint64_t Elf64_Addr;
-alias uint16_t Elf64_Half;
-alias uint64_t Elf64_Off;
-alias int32_t Elf64_Sword;
-alias int64_t Elf64_Sxword;
-alias uint32_t Elf64_Word;
-alias uint64_t Elf64_Xword;
alias uint64_t Elf64_Lword;
alias uint64_t Elf32_Lword;
diff --git a/libphobos/libdruntime/core/sys/solaris/sys/link.d b/libphobos/libdruntime/core/sys/solaris/sys/link.d
index d9d47c0..9176b17 100644
--- a/libphobos/libdruntime/core/sys/solaris/sys/link.d
+++ b/libphobos/libdruntime/core/sys/solaris/sys/link.d
@@ -10,6 +10,7 @@ extern (C):
nothrow:
public import core.sys.solaris.sys.elftypes;
+public import core.sys.elf;
import core.stdc.config;
struct Elf32_Dyn
@@ -33,45 +34,8 @@ struct Elf64_Dyn
} _d_un d_un;
}
-enum DT_NULL = 0;
-enum DT_NEEDED = 1;
-enum DT_PLTRELSZ = 2;
-enum DT_PLTGOT = 3;
-enum DT_HASH = 4;
-enum DT_STRTAB = 5;
-enum DT_SYMTAB = 6;
-enum DT_RELA = 7;
-enum DT_RELASZ = 8;
-enum DT_RELAENT = 9;
-enum DT_STRSZ = 10;
-enum DT_SYMENT = 11;
-enum DT_INIT = 12;
-enum DT_FINI = 13;
-enum DT_SONAME = 14;
-enum DT_RPATH = 15;
-enum DT_SYMBOLIC = 16;
-enum DT_REL = 17;
-enum DT_RELSZ = 18;
-enum DT_RELENT = 19;
-enum DT_PLTREL = 20;
-enum DT_DEBUG = 21;
-enum DT_TEXTREL = 22;
-enum DT_JMPREL = 23;
-enum DT_BIND_NOW = 24;
-enum DT_INIT_ARRAY = 25;
-enum DT_FINI_ARRAY = 26;
-enum DT_INIT_ARRAYSZ = 27;
-enum DT_FINI_ARRAYSZ = 28;
-enum DT_RUNPATH = 29;
-enum DT_FLAGS = 30;
-
-enum DT_ENCODING = 32;
-enum DT_PREINIT_ARRAY = 32;
-enum DT_PREINIT_ARRAYSZ = 33;
-
enum DT_MAXPOSTAGS = 34;
-enum DT_LOOS = 0x6000000d;
enum DT_SUNW_AUXILIARY = 0x6000000d;
enum DT_SUNW_RTLDINF = 0x6000000e;
enum DT_SUNW_FILTER = 0x6000000f;
@@ -92,205 +56,15 @@ enum DT_SUNW_LDMACH = 0x6000001b;
enum DT_SUNW_CAPCHAINENT = 0x6000001d;
enum DT_SUNW_CAPCHAINSZ = 0x6000001f;
-enum DT_HIOS = 0x6ffff000;
-
enum DT_DEPRECATED_SPARC_REGISTER = 0x7000001;
-enum DT_VALRNGLO = 0x6ffffd00;
-
-enum DT_GNU_PRELINKED = 0x6ffffdf5;
-enum DT_GNU_CONFLICTSZ = 0x6ffffdf6;
-enum DT_GNU_LIBLISTSZ = 0x6ffffdf7;
-enum DT_CHECKSUM = 0x6ffffdf8;
-enum DT_PLTPADSZ = 0x6ffffdf9;
-enum DT_MOVEENT = 0x6ffffdfa;
-enum DT_MOVESZ = 0x6ffffdfb;
-enum DT_FEATURE_1 = 0x6ffffdfc;
-enum DT_POSFLAG_1 = 0x6ffffdfd;
-enum DT_SYMINSZ = 0x6ffffdfe;
-enum DT_SYMINENT = 0x6ffffdff;
-enum DT_VALRNGHI = 0x6ffffdff;
-
-enum DT_ADDRRNGLO = 0x6ffffe00;
-
-enum DT_GNU_HASH = 0x6ffffef5;
-enum DT_TLSDESC_PLT = 0x6ffffef6;
-enum DT_TLSDESC_GOT = 0x6ffffef7;
-enum DT_GNU_CONFLICT = 0x6ffffef8;
-enum DT_GNU_LIBLIST = 0x6ffffef9;
-
-enum DT_CONFIG = 0x6ffffefa;
-enum DT_DEPAUDIT = 0x6ffffefb;
-enum DT_AUDIT = 0x6ffffefc;
-enum DT_PLTPAD = 0x6ffffefd;
-enum DT_MOVETAB = 0x6ffffefe;
-enum DT_SYMINFO = 0x6ffffeff;
-enum DT_ADDRRNGHI = 0x6ffffeff;
-
-enum DT_VERSYM = 0x6ffffff0;
-
-enum DT_RELACOUNT = 0x6ffffff9;
-enum DT_RELCOUNT = 0x6ffffffa;
-enum DT_FLAGS_1 = 0x6ffffffb;
-enum DT_VERDEF = 0x6ffffffc;
-enum DT_VERDEFNUM = 0x6ffffffd;
-enum DT_VERNEED = 0x6ffffffe;
-enum DT_VERNEEDNUM = 0x6fffffff;
-
-enum DT_LOPROC = 0x70000000;
-enum DT_AUXILIARY = 0x7ffffffd;
enum DT_USED = 0x7ffffffe;
-enum DT_FILTER = 0x7fffffff;
-enum DT_HIPROC = 0x7fffffff;
-enum DF_ORIGIN = 0x00000001;
-enum DF_SYMBOLIC = 0x00000002;
-enum DF_TEXTREL = 0x00000004;
-enum DF_BIND_NOW = 0x00000008;
-enum DF_STATIC_TLS = 0x00000010;
-
-enum DF_P1_LAZYLOAD = 0x00000001;
-enum DF_P1_GROUPPERM = 0x00000002;
enum DF_P1_DEFERRED = 0x00000004;
-enum DF_1_NOW = 0x00000001;
-enum DF_1_GLOBAL = 0x00000002;
-enum DF_1_GROUP = 0x00000004;
-enum DF_1_NODELETE = 0x00000008;
-enum DF_1_LOADFLTR = 0x00000010;
-enum DF_1_INITFIRST = 0x00000020;
-enum DF_1_NOOPEN = 0x00000040;
-enum DF_1_ORIGIN = 0x00000080;
-enum DF_1_DIRECT = 0x00000100;
-enum DF_1_TRANS = 0x00000200;
-enum DF_1_INTERPOSE = 0x00000400;
-enum DF_1_NODEFLIB = 0x00000800;
-enum DF_1_NODUMP = 0x00001000;
-enum DF_1_CONFALT = 0x00002000;
-enum DF_1_ENDFILTEE = 0x00004000;
-enum DF_1_DISPRELDNE = 0x00008000;
-enum DF_1_DISPRELPND = 0x00010000;
-enum DF_1_NODIRECT = 0x00020000;
-enum DF_1_IGNMULDEF = 0x00040000;
-enum DF_1_NOKSYMS = 0x00080000;
-enum DF_1_NOHDR = 0x00100000;
-enum DF_1_EDITED = 0x00200000;
-enum DF_1_NORELOC = 0x00400000;
-enum DF_1_SYMINTPOSE = 0x00800000;
-enum DF_1_GLOBAUDIT = 0x01000000;
-enum DF_1_SINGLETON = 0x02000000;
-
-enum DTF_1_PARINIT = 0x00000001;
-enum DTF_1_CONFEXP = 0x00000002;
-
-struct Elf32_Verdef
-{
- Elf32_Half vd_version;
- Elf32_Half vd_flags;
- Elf32_Half vd_ndx;
- Elf32_Half vd_cnt;
- Elf32_Word vd_hash;
- Elf32_Word vd_aux;
- Elf32_Word vd_next;
-}
-
-struct Elf32_Verdaux
-{
- Elf32_Word vda_name;
- Elf32_Word vda_next;
-}
-
-struct Elf32_Verneed
-{
- Elf32_Half vn_version;
- Elf32_Half vn_cnt;
- Elf32_Word vn_file;
- Elf32_Word vn_aux;
- Elf32_Word vn_next;
-}
-
-struct Elf32_Vernaux
-{
- Elf32_Word vna_hash;
- Elf32_Half vna_flags;
- Elf32_Half vna_other;
- Elf32_Word vna_name;
- Elf32_Word vna_next;
-}
-
-alias Elf32_Half Elf32_Versym;
-
-struct Elf32_Syminfo
-{
- Elf32_Half si_boundto;
- Elf32_Half si_flags;
-}
-
-struct Elf64_Verdef
-{
- Elf64_Half vd_version;
- Elf64_Half vd_flags;
- Elf64_Half vd_ndx;
- Elf64_Half vd_cnt;
- Elf64_Word vd_hash;
- Elf64_Word vd_aux;
- Elf64_Word vd_next;
-}
-
-struct Elf64_Verdaux
-{
- Elf64_Word vda_name;
- Elf64_Word vda_next;
-}
-
-struct Elf64_Verneed
-{
- Elf64_Half vn_version;
- Elf64_Half vn_cnt;
- Elf64_Word vn_file;
- Elf64_Word vn_aux;
- Elf64_Word vn_next;
-}
-
-struct Elf64_Vernaux
-{
- Elf64_Word vna_hash;
- Elf64_Half vna_flags;
- Elf64_Half vna_other;
- Elf64_Word vna_name;
- Elf64_Word vna_next;
-}
-
-alias Elf64_Half Elf64_Versym;
-
-struct Elf64_Syminfo
-{
- Elf64_Half si_boundto;
- Elf64_Half si_flags;
-}
-
-enum VER_NDX_LOCAL = 0;
-enum VER_NDX_GLOBAL = 1;
-enum VER_NDX_LORESERVE = 0xff00;
-enum VER_NDX_ELIMINATE = 0xff01;
-
-enum VER_FLG_BASE = 0x1;
-enum VER_FLG_WEAK = 0x2;
enum VER_FLG_INFO = 0x4;
-enum VER_DEF_NONE = 0;
-enum VER_DEF_CURRENT = 1;
-enum VER_DEF_NUM = 2;
-
-enum VER_NEED_NONE = 0;
-enum VER_NEED_CURRENT = 1;
-enum VER_NEED_NUM = 2;
-
-enum SYMINFO_FLG_DIRECT = 0x0001;
enum SYMINFO_FLG_FILTER = 0x0002;
-enum SYMINFO_FLG_PASSTHRU = SYMINFO_FLG_FILTER;
-enum SYMINFO_FLG_COPY = 0x0004;
-enum SYMINFO_FLG_LAZYLOAD = 0x0008;
enum SYMINFO_FLG_DIRECTBIND = 0x0010;
enum SYMINFO_FLG_NOEXTDIRECT = 0x0020;
enum SYMINFO_FLG_AUXILIARY = 0x0040;
@@ -298,15 +72,8 @@ enum SYMINFO_FLG_INTERPOSE = 0x0080;
enum SYMINFO_FLG_CAP = 0x0100;
enum SYMINFO_FLG_DEFERRED = 0x0200;
-enum SYMINFO_BT_SELF = 0xffff;
-enum SYMINFO_BT_PARENT = 0xfffe;
enum SYMINFO_BT_NONE = 0xfffd;
enum SYMINFO_BT_EXTERN = 0xfffc;
-enum SYMINFO_BT_LOWRESERVE = 0xff00;
-
-enum SYMINFO_NONE = 0;
-enum SYMINFO_CURRENT = 1;
-enum SYMINFO_NUM = 2;
alias link_map Link_map;
diff --git a/libphobos/libdruntime/core/thread/threadbase.d b/libphobos/libdruntime/core/thread/threadbase.d
index 505be00..217a33a 100644
--- a/libphobos/libdruntime/core/thread/threadbase.d
+++ b/libphobos/libdruntime/core/thread/threadbase.d
@@ -109,7 +109,7 @@ class ThreadBase
}
this(void delegate() dg, size_t sz = 0) @trusted pure nothrow @nogc
- in( cast(void delegate() const) dg)
+ in( cast(const void delegate()) dg)
{
this(sz);
m_call = dg;
diff --git a/libphobos/libdruntime/rt/ehalloc.d b/libphobos/libdruntime/rt/ehalloc.d
index 1dcd69a..65f92e3 100644
--- a/libphobos/libdruntime/rt/ehalloc.d
+++ b/libphobos/libdruntime/rt/ehalloc.d
@@ -18,51 +18,6 @@ debug(PRINTF)
import core.stdc.stdio;
}
-/**********************************************
- * Allocate an exception of type `ci` from the exception pool.
- * It has the same interface as `rt.lifetime._d_newclass()`.
- * The class type must be Throwable or derived from it,
- * and cannot be a COM or C++ class. The compiler must enforce
- * this.
- * Returns:
- * default initialized instance of the type
- */
-
-extern (C) Throwable _d_newThrowable(const TypeInfo_Class ci)
-{
- debug(PRINTF) printf("_d_newThrowable(ci = %p, %s)\n", ci, cast(char *)ci.name);
-
- assert(!(ci.m_flags & TypeInfo_Class.ClassFlags.isCOMclass));
- assert(!(ci.m_flags & TypeInfo_Class.ClassFlags.isCPPclass));
-
- import core.stdc.stdlib : malloc;
- auto init = ci.initializer;
- void* p = malloc(init.length);
- if (!p)
- {
- import core.exception : onOutOfMemoryError;
- onOutOfMemoryError();
- }
-
- debug(PRINTF) printf(" p = %p\n", p);
-
- // initialize it
- p[0 .. init.length] = init[];
-
- if (!(ci.m_flags & TypeInfo_Class.ClassFlags.noPointers))
- {
- // Inform the GC about the pointers in the object instance
- import core.memory : GC;
-
- GC.addRange(p, init.length, ci);
- }
-
- debug(PRINTF) printf("initialization done\n");
- Throwable t = cast(Throwable)p;
- t.refcount() = 1;
- return t;
-}
-
/********************************************
* Delete exception instance `t` from the exception pool.
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index ddf730e..30e9e80 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-d46814c86392007ebb4fb73cb684ef9e8caa605a
+1206fc94f967b0183667a109049cbf596deaa696
The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository.
diff --git a/libphobos/src/std/mmfile.d b/libphobos/src/std/mmfile.d
index e4000d4..f8f8a90 100644
--- a/libphobos/src/std/mmfile.d
+++ b/libphobos/src/std/mmfile.d
@@ -71,13 +71,13 @@ class MmFile
* - On POSIX, $(REF ErrnoException, std, exception).
* - On Windows, $(REF WindowsException, std, windows, syserror).
*/
- this(string filename)
+ this(string filename) scope
{
this(filename, Mode.read, 0, null);
}
version (linux) this(File file, Mode mode = Mode.read, ulong size = 0,
- void* address = null, size_t window = 0)
+ void* address = null, size_t window = 0) scope
{
// Save a copy of the File to make sure the fd stays open.
this.file = file;
@@ -85,7 +85,7 @@ class MmFile
}
version (linux) private this(int fildes, Mode mode, ulong size,
- void* address, size_t window)
+ void* address, size_t window) scope
{
int oflag;
int fmode;
@@ -169,7 +169,7 @@ class MmFile
* - On Windows, $(REF WindowsException, std, windows, syserror).
*/
this(string filename, Mode mode, ulong size, void* address,
- size_t window = 0)
+ size_t window = 0) scope
{
this.filename = filename;
this.mMode = mode;
@@ -364,7 +364,7 @@ class MmFile
/**
* Flushes pending output and closes the memory mapped file.
*/
- ~this()
+ ~this() scope
{
debug (MMFILE) printf("MmFile.~this()\n");
unmap();
diff --git a/libphobos/src/std/sumtype.d b/libphobos/src/std/sumtype.d
index 869c36f..f3d3152 100644
--- a/libphobos/src/std/sumtype.d
+++ b/libphobos/src/std/sumtype.d
@@ -1313,6 +1313,7 @@ version (D_BetterC) {} else
// Types with invariants
// Disabled in BetterC due to use of exceptions
version (D_BetterC) {} else
+version (D_Invariants)
@system unittest
{
import std.exception : assertThrown;
@@ -1330,22 +1331,13 @@ version (D_BetterC) {} else
invariant { assert(i >= 0); }
}
- // Only run test if contract checking is enabled
- try
- {
- S probe = S(-1);
- assert(&probe);
- }
- catch (AssertError _)
- {
- SumType!S x;
- x.match!((ref v) { v.i = -1; });
- assertThrown!AssertError(assert(&x));
+ SumType!S x;
+ x.match!((ref v) { v.i = -1; });
+ assertThrown!AssertError(assert(&x));
- SumType!C y = new C();
- y.match!((ref v) { v.i = -1; });
- assertThrown!AssertError(assert(&y));
- }
+ SumType!C y = new C();
+ y.match!((ref v) { v.i = -1; });
+ assertThrown!AssertError(assert(&y));
}
// Calls value postblit on self-assignment