summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-07-26 18:13:54 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2022-07-26 23:43:13 +0200
commit81a0fa31ce96327618023b476ea121dbe2494b04 (patch)
tree7a92b40bb7124e7e2449fef9983e22db836a0f65
parent2009850b2b7042a678c385cd72e6ceb40caac8cd (diff)
d: Merge upstream dmd 76e3b41375, druntime 1462ebd1, phobos 5fef0d28f.
Updates D language version to v2.100.1. D front-end changes: - Fix delegate literal with inferred return value that requires following alias-this to not use class cast. - Fix internal error on variadic template type instantiated with two arrays of classes. - `scope(failure)' blocks that contain `return' statements are now deprecated. - Fix regression where wrong cast was inserted for ternary operator and non-int enums. - Fix internal error in code generation trying to reference _d_arraysetctor. - Fix memory corruption when array literal is passed to map in lambda, then returned from nested function. - Generate invariant id on the basis of location rather than a global counter. - Make `noreturn' conversions work. - Fix segfault when `.stringof' of template alias overloaded with function accessed by trait. - Empty array literal passed to scope param not 'falsey' anymore. Phobos changes: - Avoid copying ranges in std.algorithm.comparison.equal. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 76e3b41375. * dmd/VERSION: Bump version to v2.100.1. * decl.cc (DeclVisitor::visit (VarDeclaration *)): Evaluate RHS of noreturn declaration expressions first. * expr.cc (ExprVisitor::visit (AssignExp *)): Don't generate assignment for noreturn types. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 1462ebd1. * src/MERGE: Merge upstream phobos 5fef0d28f.
-rw-r--r--gcc/d/decl.cc7
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/VERSION2
-rw-r--r--gcc/d/dmd/dcast.d14
-rw-r--r--gcc/d/dmd/dsymbolsem.d3
-rw-r--r--gcc/d/dmd/expressionsem.d13
-rw-r--r--gcc/d/dmd/func.d14
-rw-r--r--gcc/d/dmd/impcnvtab.d55
-rw-r--r--gcc/d/dmd/mtype.d5
-rw-r--r--gcc/d/dmd/statementsem.d16
-rw-r--r--gcc/d/expr.cc11
-rw-r--r--gcc/testsuite/gdc.test/compilable/backendfloatoptim.d10
-rw-r--r--gcc/testsuite/gdc.test/compilable/noreturn1.d28
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23082.d17
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23166.d22
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23172.d33
-rw-r--r--gcc/testsuite/gdc.test/compilable/test23258.d21
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail23181.d16
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail6889.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail7848.d8
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test21443.d21
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test23170.d12
-rw-r--r--gcc/testsuite/gdc.test/runnable/noreturn1.d32
-rw-r--r--gcc/testsuite/gdc.test/runnable/test20734.d7
-rw-r--r--gcc/testsuite/gdc.test/runnable/test23181.d27
-rw-r--r--gcc/testsuite/gdc.test/runnable/test23234.d22
-rw-r--r--gcc/testsuite/gdc.test/runnable/warning1.d9
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/algorithm/comparison.d2
-rw-r--r--libphobos/src/std/typecons.d10
31 files changed, 408 insertions, 37 deletions
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index f5c21078aad..43c3d87cdd1 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -645,9 +645,12 @@ public:
if (!d->isDataseg () && !d->isMember ()
&& d->_init && !d->_init->isVoidInitializer ())
{
+ /* Evaluate RHS for side effects first. */
+ Expression *ie = initializerToExpression (d->_init);
+ add_stmt (build_expr (ie));
+
Expression *e = d->type->defaultInitLiteral (d->loc);
- tree exp = build_expr (e);
- add_stmt (exp);
+ add_stmt (build_expr (e));
}
return;
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index d538621ba83..d79ebfae806 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-a53934d18eecccbf677cd32a4febeff3bc0ee292
+76e3b41375e3e1cb4dbca692b587d8e916c0b49f
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/VERSION b/gcc/d/dmd/VERSION
index 5ea2ba0d8ec..83a14f57e16 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@
-v2.100.0
+v2.100.1
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index 83978391e42..6afa1c966b0 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -1107,9 +1107,14 @@ MATCH implicitConvTo(Expression e, Type t)
MATCH visitCond(CondExp e)
{
- auto result = visit(e);
- if (result != MATCH.nomatch)
- return result;
+ e.econd = e.econd.optimize(WANTvalue);
+ const opt = e.econd.toBool();
+ if (opt.isPresent())
+ {
+ auto result = visit(e);
+ if (result != MATCH.nomatch)
+ return result;
+ }
MATCH m1 = e.e1.implicitConvTo(t);
MATCH m2 = e.e2.implicitConvTo(t);
@@ -2954,6 +2959,9 @@ Lagain:
t1 = Type.basic[ty1];
t2 = Type.basic[ty2];
+
+ if (!(t1 && t2))
+ return null;
e1 = e1.castTo(sc, t1);
e2 = e2.castTo(sc, t2);
return Lret(Type.basic[ty]);
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index be8f9150903..c5766787bf0 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -4407,7 +4407,10 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
invd.semanticRun < PASS.semantic &&
!ad.isUnionDeclaration() // users are on their own with union fields
)
+ {
+ invd.fixupInvariantIdent(ad.invs.length);
ad.invs.push(invd);
+ }
if (!invd.type)
invd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, invd.storage_class);
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 717420910aa..0617b69ccc9 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -2048,7 +2048,8 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
if (global.params.useDIP1000 == FeatureState.enabled)
err |= checkParamArgumentEscape(sc, fd, p, arg, false, false);
}
- else if (!(pStc & STC.return_))
+ else if (!(pStc & STC.return_) &&
+ ((global.params.useDIP1000 == FeatureState.enabled) || !(p.storageClass & STC.scopeinferred)))
{
/* Argument value cannot escape from the called function.
*/
@@ -2058,10 +2059,10 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
ArrayLiteralExp ale;
if (p.type.toBasetype().ty == Tarray &&
- (ale = a.isArrayLiteralExp()) !is null)
+ (ale = a.isArrayLiteralExp()) !is null && ale.elements && ale.elements.length > 0)
{
// allocate the array literal as temporary static array on the stack
- ale.type = ale.type.nextOf().sarrayOf(ale.elements ? ale.elements.length : 0);
+ ale.type = ale.type.nextOf().sarrayOf(ale.elements.length);
auto tmp = copyToTemp(0, "__arrayliteral_on_stack", ale);
auto declareTmp = new DeclarationExp(ale.loc, tmp);
auto castToSlice = new CastExp(ale.loc, new VarExp(ale.loc, tmp),
@@ -9926,9 +9927,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
ae.e2.type.nextOf &&
ae.e1.type.nextOf.mutableOf.equals(ae.e2.type.nextOf.mutableOf);
+ /* Unlike isArrayCtor above, lower all Rvalues. If the RHS is a literal,
+ * then we do want to make a temporary for it and call its destructor.
+ */
const isArraySetCtor =
(ae.e1.isSliceExp || ae.e1.type.ty == Tsarray) &&
- ae.e2.isLvalue &&
(ae.e2.type.ty == Tstruct || ae.e2.type.ty == Tsarray) &&
ae.e1.type.nextOf &&
ae.e1.type.nextOf.equivalent(ae.e2.type);
@@ -12535,7 +12538,7 @@ Expression semanticY(DotIdExp exp, Scope* sc, int flag)
e = new CommaExp(exp.loc, eleft, e);
e.type = Type.tvoid; // ambiguous type?
}
- return e;
+ return e.expressionSemantic(sc);
}
if (auto o = s.isOverloadSet())
{
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 55abe4d52e7..aba5d62827a 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -3748,9 +3748,7 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration
{
Expression exp = s.exp;
if (exp && !exp.type.equals(tret))
- {
- s.exp = exp.castTo(sc, tret);
- }
+ s.exp = exp.implicitCastTo(sc, tret);
}
}
@@ -4150,6 +4148,7 @@ extern (C++) final class InvariantDeclaration : FuncDeclaration
{
extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Identifier id, Statement fbody)
{
+ // Make a unique invariant for now; we'll fix it up as we add it to the aggregate invariant list.
super(loc, endloc, id ? id : Identifier.generateId("__invariant"), stc, null);
this.fbody = fbody;
}
@@ -4186,6 +4185,15 @@ extern (C++) final class InvariantDeclaration : FuncDeclaration
{
v.visit(this);
}
+
+ extern (D) void fixupInvariantIdent(size_t offset)
+ {
+ OutBuffer idBuf;
+ idBuf.writestring("__invariant");
+ idBuf.print(offset);
+
+ ident = Identifier.idPool(idBuf[]);
+ }
}
diff --git a/gcc/d/dmd/impcnvtab.d b/gcc/d/dmd/impcnvtab.d
index ab46f5eebbd..832c331c314 100644
--- a/gcc/d/dmd/impcnvtab.d
+++ b/gcc/d/dmd/impcnvtab.d
@@ -64,6 +64,57 @@ enum ImpCnvTab impCnvTab = generateImpCnvTab();
ImpCnvTab generateImpCnvTab()
{
+ TY[TMAX] typeTYs =
+ [
+ Tarray,
+ Tsarray,
+ Taarray,
+ Tpointer,
+ Treference,
+ Tfunction,
+ Tident,
+ Tclass,
+ Tstruct,
+ Tenum,
+ Tdelegate,
+ Tnone,
+ Tvoid,
+ Tint8,
+ Tuns8,
+ Tint16,
+ Tuns16,
+ Tint32,
+ Tuns32,
+ Tint64,
+ Tuns64,
+ Tfloat32,
+ Tfloat64,
+ Tfloat80,
+ Timaginary32,
+ Timaginary64,
+ Timaginary80,
+ Tcomplex32,
+ Tcomplex64,
+ Tcomplex80,
+ Tbool,
+ Tchar,
+ Twchar,
+ Tdchar,
+ Terror,
+ Tinstance,
+ Ttypeof,
+ Ttuple,
+ Tslice,
+ Treturn,
+ Tnull,
+ Tvector,
+ Tint128,
+ Tuns128,
+ Ttraits,
+ Tmixin,
+ Tnoreturn,
+ Ttag,
+ ];
ImpCnvTab impCnvTab;
// Set conversion tables
@@ -375,5 +426,9 @@ ImpCnvTab generateImpCnvTab()
X(Tcomplex80,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80);
+ // "No type is implicitly convertible to noreturn, but noreturn is implicitly convertible to every other type"
+ foreach(convertToTy; typeTYs)
+ X(Tnoreturn, convertToTy, convertToTy, convertToTy, convertToTy);
+
return impCnvTab;
}
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index 32f57d46773..12608534879 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -6184,6 +6184,11 @@ extern (C++) final class TypeClass : Type
if (t && t.ty == Tclass)
{
ClassDeclaration cd = (cast(TypeClass)t).sym;
+ if (cd.semanticRun < PASS.semanticdone && !cd.isBaseInfoComplete())
+ cd.dsymbolSemantic(null);
+ if (sym.semanticRun < PASS.semanticdone && !sym.isBaseInfoComplete())
+ sym.dsymbolSemantic(null);
+
if (sym.isBaseOf(cd, poffset))
return true;
}
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index 2916bbc38dd..c1c2dc92e12 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -2829,10 +2829,20 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
rs.error("`return` statements cannot be in contracts");
errors = true;
}
- if (sc.os && sc.os.tok != TOK.onScopeFailure)
+ if (sc.os)
{
- rs.error("`return` statements cannot be in `%s` bodies", Token.toChars(sc.os.tok));
- errors = true;
+ // @@@DEPRECATED_2.112@@@
+ // Deprecated in 2.100, transform into an error in 2.112
+ if (sc.os.tok == TOK.onScopeFailure)
+ {
+ rs.deprecation("`return` statements cannot be in `scope(failure)` bodies.");
+ deprecationSupplemental(rs.loc, "Use try-catch blocks for this purpose");
+ }
+ else
+ {
+ rs.error("`return` statements cannot be in `%s` bodies", Token.toChars(sc.os.tok));
+ errors = true;
+ }
}
if (sc.tf)
{
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 73dab463926..6fba382f0ed 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -916,6 +916,17 @@ public:
gcc_unreachable ();
}
+ /* Look for exp = noreturn; */
+ if (e->e2->type->isTypeNoreturn ())
+ {
+ /* If the RHS is a `noreturn' expression, there is no point generating
+ any code for the assignment, just evaluate side effects. */
+ tree t1 = build_expr (e->e1);
+ tree t2 = build_expr (e->e2);
+ this->result_ = compound_expr (t1, t2);
+ return;
+ }
+
/* Look for array[] = n; */
if (e->e1->op == EXP::slice)
{
diff --git a/gcc/testsuite/gdc.test/compilable/backendfloatoptim.d b/gcc/testsuite/gdc.test/compilable/backendfloatoptim.d
new file mode 100644
index 00000000000..7ec9f614ef8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/backendfloatoptim.d
@@ -0,0 +1,10 @@
+// REQUIRED_ARGS: -O -inline
+
+//https://issues.dlang.org/show_bug.cgi?id=20143
+real fun(int x) { return 0.0; }
+
+double bug()
+{
+ // value passed to fun is irrelevant
+ return 0.0 / fun(420);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/noreturn1.d b/gcc/testsuite/gdc.test/compilable/noreturn1.d
index 5bba9baa72a..e648a56d896 100644
--- a/gcc/testsuite/gdc.test/compilable/noreturn1.d
+++ b/gcc/testsuite/gdc.test/compilable/noreturn1.d
@@ -122,3 +122,31 @@ noreturn testdg(noreturn delegate() dg)
{
dg();
}
+
+noreturn func()
+{
+ while(1)
+ {
+ }
+}
+alias AliasSeq(T...) = T;
+alias Types = AliasSeq!(bool, byte, ubyte, short, ushort, int, uint,
+ long, ulong, char, wchar, dchar, float, double,
+ real);
+void noreturnImplicit()
+{
+ /*
+ Testing both ways because, although the underlying table
+ is symmetrical the code that calls into it may be buggy.
+ */
+ {
+ int x = 2 + func();
+ int y = func() + 2;
+ }
+ foreach(T; Types)
+ {
+ T value;
+ auto x = value + throw new Exception("Hello");
+ auto y = (throw new Exception("wow")) + value;
+ }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23082.d b/gcc/testsuite/gdc.test/compilable/test23082.d
new file mode 100644
index 00000000000..9df4e4e7774
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23082.d
@@ -0,0 +1,17 @@
+// https://issues.dlang.org/show_bug.cgi?id=23082
+
+/*
+TEST_OUTPUT:
+---
+bar
+---
+*/
+
+void foo()() {}
+alias bar = foo;
+void bar() { }
+
+void main()
+{
+ pragma(msg, __traits(parent, main).bar.stringof);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23166.d b/gcc/testsuite/gdc.test/compilable/test23166.d
new file mode 100644
index 00000000000..66da4cd6963
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23166.d
@@ -0,0 +1,22 @@
+// REQUIRED_ARGS: -inline
+
+// https://issues.dlang.org/show_bug.cgi?id=23166
+
+// seg fault with -inline
+
+bool __equals(scope const char[] lhs, scope const char[] rhs)
+{
+ if (lhs.length != rhs.length)
+ return false;
+
+ {
+ import core.stdc.string : memcmp;
+ return lhs.length == 0;
+ }
+ return true;
+}
+
+int test(string type)
+{
+ return __equals(type, "as-is");
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23172.d b/gcc/testsuite/gdc.test/compilable/test23172.d
new file mode 100644
index 00000000000..18b6d4ce8c5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23172.d
@@ -0,0 +1,33 @@
+// https://issues.dlang.org/show_bug.cgi?id=23172
+
+enum E : ubyte { // `ubyte` is needed to trigger the bug
+ A,
+ B,
+}
+
+struct S {
+ E e;
+}
+
+void compiles(bool b, S s) {
+ E e = b ? E.A : s.e;
+}
+
+void errors(bool b, const ref S s) {
+ E e = b ? E.A : s.e;
+}
+
+// from https://issues.dlang.org/show_bug.cgi?id=23188
+
+enum Status : byte
+{
+ A, B, C
+}
+
+Status foo()
+{
+ Status t = Status.A;
+ const Status s = t;
+
+ return (s == Status.A) ? Status.B : s; // <-- here
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test23258.d b/gcc/testsuite/gdc.test/compilable/test23258.d
new file mode 100644
index 00000000000..1e8e91b7795
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test23258.d
@@ -0,0 +1,21 @@
+// https://issues.dlang.org/show_bug.cgi?id=23258
+
+struct SumType(Types...)
+{
+ this(Types[0])
+ {
+ }
+ this(Types[1])
+ {
+ }
+}
+
+alias A2 = SumType!(C1[], C2[]);
+
+class C1
+{
+}
+
+class C2
+{
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23181.d b/gcc/testsuite/gdc.test/fail_compilation/fail23181.d
new file mode 100644
index 00000000000..519244c1cdf
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23181.d
@@ -0,0 +1,16 @@
+/* https://issues.dlang.org/show_bug.cgi?id=23181
+TEST_OUTPUT:
+---
+$p:druntime/import/core/lifetime.d$($n$): Error: struct `fail23181.fail23181.NoPostblit` is not copyable because it has a disabled postblit
+$p:druntime/import/core/internal/array/construction.d$($n$): Error: template instance `core.lifetime.copyEmplace!(NoPostblit, NoPostblit)` error instantiating
+fail_compilation/fail23181.d(15): instantiated from here: `_d_arraysetctor!(NoPostblit[], NoPostblit)`
+---
+*/
+void fail23181()
+{
+ struct NoPostblit
+ {
+ @disable this(this);
+ }
+ NoPostblit[4] noblit23181 = NoPostblit();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail6889.d b/gcc/testsuite/gdc.test/fail_compilation/fail6889.d
index aa189770903..ee84a84ce79 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail6889.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail6889.d
@@ -55,7 +55,7 @@ L1:
scope(failure) { L2: goto L1; } // OK
goto L2; // NG
- scope(failure) { return; } // OK
+
foreach (i; 0..1)
{
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7848.d b/gcc/testsuite/gdc.test/fail_compilation/fail7848.d
index e8371c4f7fe..001c7d75443 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7848.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail7848.d
@@ -9,12 +9,12 @@ fail_compilation/fail7848.d(21): `fail7848.func` is declared here
fail_compilation/fail7848.d(27): Error: `@nogc` function `fail7848.C.__unittest_L25_C30` cannot call non-@nogc function `fail7848.func`
fail_compilation/fail7848.d(27): Error: function `fail7848.func` is not `nothrow`
fail_compilation/fail7848.d(25): Error: function `fail7848.C.__unittest_L25_C30` may throw but is marked as `nothrow`
-fail_compilation/fail7848.d(32): Error: `pure` function `fail7848.C.__invariant1` cannot call impure function `fail7848.func`
-fail_compilation/fail7848.d(32): Error: `@safe` function `fail7848.C.__invariant1` cannot call `@system` function `fail7848.func`
+fail_compilation/fail7848.d(32): Error: `pure` function `fail7848.C.__invariant0` cannot call impure function `fail7848.func`
+fail_compilation/fail7848.d(32): Error: `@safe` function `fail7848.C.__invariant0` cannot call `@system` function `fail7848.func`
fail_compilation/fail7848.d(21): `fail7848.func` is declared here
-fail_compilation/fail7848.d(32): Error: `@nogc` function `fail7848.C.__invariant1` cannot call non-@nogc function `fail7848.func`
+fail_compilation/fail7848.d(32): Error: `@nogc` function `fail7848.C.__invariant0` cannot call non-@nogc function `fail7848.func`
fail_compilation/fail7848.d(32): Error: function `fail7848.func` is not `nothrow`
-fail_compilation/fail7848.d(30): Error: function `fail7848.C.__invariant1` may throw but is marked as `nothrow`
+fail_compilation/fail7848.d(30): Error: function `fail7848.C.__invariant0` may throw but is marked as `nothrow`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21443.d b/gcc/testsuite/gdc.test/fail_compilation/test21443.d
new file mode 100644
index 00000000000..2d99524da35
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21443.d
@@ -0,0 +1,21 @@
+// https://issues.dlang.org/show_bug.cgi?id=21443
+// REQUIRED_ARGS: -de
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test21443.d(14): Deprecation: `return` statements cannot be in `scope(failure)` bodies.
+fail_compilation/test21443.d(14): Use try-catch blocks for this purpose
+---
+*/
+
+ulong get () @safe nothrow
+{
+ scope (failure) return 10;
+ throw new Error("");
+}
+
+void main () @safe
+{
+ assert(get() == 10); // passes
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23170.d b/gcc/testsuite/gdc.test/fail_compilation/test23170.d
new file mode 100644
index 00000000000..eb79cd81565
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23170.d
@@ -0,0 +1,12 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test23170.d(10): Error: array literal in `@nogc` delegate `test23170.__lambda5` may cause a GC allocation
+---
+*/
+// https://issues.dlang.org/show_bug.cgi?id=23170
+
+@nogc:
+enum lambda = () => badAlias([1, 2, 3]);
+alias badAlias = (int[] array) => id(array);
+int[] id(int[] array) { return array; }
diff --git a/gcc/testsuite/gdc.test/runnable/noreturn1.d b/gcc/testsuite/gdc.test/runnable/noreturn1.d
index 7d15b54a213..5ed46c16250 100644
--- a/gcc/testsuite/gdc.test/runnable/noreturn1.d
+++ b/gcc/testsuite/gdc.test/runnable/noreturn1.d
@@ -261,6 +261,37 @@ void testThrowDtor()
/*****************************************/
+noreturn func()
+{
+ throw new Exception("B");
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=23120
+void test23120()
+{
+ string a;
+ try
+ {
+ noreturn q = throw new Exception ("A");
+ }
+ catch(Exception e)
+ {
+ a ~= e.msg;
+ }
+
+ try
+ {
+ noreturn z = func();
+ }
+ catch(Exception e)
+ {
+ a ~= e.msg;
+ }
+
+ assert(a == "AB");
+}
+
+/*****************************************/
int main()
{
test1();
@@ -269,5 +300,6 @@ int main()
testThrowExpression();
testThrowSideEffect();
testThrowDtor();
+ test23120();
return 0;
}
diff --git a/gcc/testsuite/gdc.test/runnable/test20734.d b/gcc/testsuite/gdc.test/runnable/test20734.d
index 264602bccc5..b3c5916ada5 100644
--- a/gcc/testsuite/gdc.test/runnable/test20734.d
+++ b/gcc/testsuite/gdc.test/runnable/test20734.d
@@ -16,6 +16,7 @@ extern(C) int main() nothrow @nogc @safe
{
takeScopeSlice([ S(1), S(2) ]); // @nogc => no GC allocation
(() @trusted { assert(numDtor == 2); })(); // stack-allocated array literal properly destructed
+ assert23100([]);
return 0;
}
@@ -26,3 +27,9 @@ void test23098() @safe
{
f23098([10, 20]);
}
+
+// https://issues.dlang.org/show_bug.cgi?id=23100
+void assert23100(scope int[] d) @safe nothrow @nogc
+{
+ assert(!d);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test23181.d b/gcc/testsuite/gdc.test/runnable/test23181.d
new file mode 100644
index 00000000000..b961690a2bc
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test23181.d
@@ -0,0 +1,27 @@
+// https://issues.dlang.org/show_bug.cgi?id=23181
+void main()
+{
+ int count;
+ struct HasDtor
+ {
+ ~this() { ++count; }
+ }
+
+ // array[] = elem()
+ // -> creates temporary to construct array and calls destructor.
+ {
+ count = 0;
+ HasDtor[4] dtor1 = HasDtor();
+ assert(count == 1);
+ }
+ assert(count == 5);
+
+ // array[] = array[elem()]
+ // -> constructs array using direct emplacement.
+ {
+ count = 0;
+ HasDtor[2] dtor2 = [HasDtor(), HasDtor()];
+ assert(count == 0);
+ }
+ assert(count == 2);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test23234.d b/gcc/testsuite/gdc.test/runnable/test23234.d
new file mode 100644
index 00000000000..7872aa76dfe
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test23234.d
@@ -0,0 +1,22 @@
+// https://issues.dlang.org/show_bug.cgi?id=23234
+
+class Bar
+{
+}
+
+class Foo
+{
+ Bar get() { return new Bar; }
+ alias get this;
+}
+
+void main()
+{
+ auto foo = new Foo;
+ void test(Bar delegate() dg)
+ {
+ assert(dg() !is null);
+ }
+
+ test(() => foo);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/warning1.d b/gcc/testsuite/gdc.test/runnable/warning1.d
index 537088e97cc..01ac20c0baf 100644
--- a/gcc/testsuite/gdc.test/runnable/warning1.d
+++ b/gcc/testsuite/gdc.test/runnable/warning1.d
@@ -133,15 +133,6 @@ void test6518()
}
}
-/******************************************/
-// https://issues.dlang.org/show_bug.cgi?id=7232
-
-bool test7232()
-{
- scope(failure) return false;
- return true;
-}
-
/***************************************************/
struct S9332
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 9bab8ed6395..c96180a3751 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-9c0d4f914e0817c9ee4eafc5a45c41130aa6b981
+1462ebd188c0ab5181a0a75e3576754bb0b81a16
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/src/MERGE b/libphobos/src/MERGE
index ed9a02e1a0c..f2678185f39 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-604534d7cb29d49a6474f0aaaa5d166057a44f72
+5fef0d28fc873fb5a0dbfb9149759d76a7b9f1b7
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/algorithm/comparison.d b/libphobos/src/std/algorithm/comparison.d
index 2fcc2bacd5c..b810fbb9258 100644
--- a/libphobos/src/std/algorithm/comparison.d
+++ b/libphobos/src/std/algorithm/comparison.d
@@ -1027,7 +1027,7 @@ template equal(alias pred = "a == b")
}
}
- private bool equalLoop(Rs...)(Rs rs)
+ private bool equalLoop(Rs...)(ref Rs rs)
{
for (; !rs[0].empty; rs[0].popFront)
static foreach (r; rs[1 .. $])
diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d
index 1ee7faaee7b..fb15001233a 100644
--- a/libphobos/src/std/typecons.d
+++ b/libphobos/src/std/typecons.d
@@ -4905,8 +4905,14 @@ if (is(Interface == interface) && is(BaseClass == class))
// - try default first
// - only on a failure run & return fallback
enum fallback = q{
- scope (failure) return fallback.%1$s(args);
- return default_.%1$s(args);
+ try
+ {
+ return default_.%1$s(args);
+ }
+ catch (Exception)
+ {
+ return fallback.%1$s(args);
+ }
}.format(__traits(identifier, func));
}