mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
commit
20bd0cacbd
36 changed files with 414 additions and 27 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
v2.100.0
|
||||
v2.100.1
|
||||
|
|
23
changelog/deprecate_scope_failure_return.dd
Normal file
23
changelog/deprecate_scope_failure_return.dd
Normal file
|
@ -0,0 +1,23 @@
|
|||
`scope(failure)` blocks that contain `return` statements are now deprecated
|
||||
|
||||
Starting with this release, having a `return` statement in the body of a `scope(failure)`
|
||||
statement is deprecated. Having the ability to `return` from such blocks is error prone since currently, Errors are also handled by `scope(failure)`. This leads to the following situation:
|
||||
|
||||
---
|
||||
ulong get () @safe nothrow
|
||||
{
|
||||
scope (failure) return 10;
|
||||
throw new Error("");
|
||||
}
|
||||
|
||||
void main () @safe
|
||||
{
|
||||
assert(get() == 10); // passes
|
||||
}
|
||||
---
|
||||
|
||||
where an error is circumvented by a return. If a return is indeed desired
|
||||
in such situations, then the solution is to simply use a try-catch block
|
||||
for the function body.
|
||||
|
||||
Note: `scope(exit)` and `scope(success)` already present this restriction.
|
|
@ -716,7 +716,7 @@ struct ASTBase
|
|||
{
|
||||
extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc, Identifier id, Statement fbody)
|
||||
{
|
||||
super(loc, endloc, id ? id : Identifier.generateId("__invariant"), stc, null);
|
||||
super(loc, endloc, id ? id : Identifier.generateIdWithLoc("__invariant", loc), stc, null);
|
||||
this.fbody = fbody;
|
||||
}
|
||||
|
||||
|
|
|
@ -1348,6 +1348,7 @@ void cddiv(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
|
|||
|
||||
code cs = void;
|
||||
cs.Iflags = 0;
|
||||
cs.IFL2 = 0;
|
||||
cs.Irex = 0;
|
||||
|
||||
switch (e2.Eoper)
|
||||
|
|
|
@ -984,6 +984,10 @@ static if (0)
|
|||
case TYdouble_alias:
|
||||
e.EV.Vdouble = e1.EV.Vdouble / e2.EV.Vdouble;
|
||||
break;
|
||||
case TYldouble:
|
||||
// cast is required because Vldouble is a soft type on windows
|
||||
e.EV.Vdouble = cast(double)(e1.EV.Vdouble / e2.EV.Vldouble);
|
||||
break;
|
||||
case TYidouble:
|
||||
e.EV.Vdouble = -e1.EV.Vdouble / e2.EV.Vdouble;
|
||||
break;
|
||||
|
|
|
@ -1105,10 +1105,15 @@ MATCH implicitConvTo(Expression e, Type t)
|
|||
}
|
||||
|
||||
MATCH visitCond(CondExp e)
|
||||
{
|
||||
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);
|
||||
|
@ -2942,6 +2947,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]);
|
||||
|
|
|
@ -4442,7 +4442,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);
|
||||
|
||||
|
|
|
@ -2077,6 +2077,15 @@ elem* toElem(Expression e, IRState *irs)
|
|||
return e;
|
||||
}
|
||||
|
||||
/*
|
||||
https://issues.dlang.org/show_bug.cgi?id=23120
|
||||
|
||||
If rhs is a noreturn expression, then there is no point
|
||||
to generate any code for the noreturen variable.
|
||||
*/
|
||||
if (ae.e2.type.isTypeNoreturn())
|
||||
return setResult(toElem(ae.e2, irs));
|
||||
|
||||
Type t1b = ae.e1.type.toBasetype();
|
||||
|
||||
// Look for array.length = n
|
||||
|
@ -6077,7 +6086,10 @@ Lagain:
|
|||
/* Need to do postblit/destructor.
|
||||
* void *_d_arraysetassign(void *p, void *value, int dim, TypeInfo ti);
|
||||
*/
|
||||
assert(op != EXP.construct, "Trying reference _d_arraysetctor, this should not happen!");
|
||||
if (op == EXP.construct)
|
||||
{
|
||||
assert(0, "Trying reference _d_arraysetctor, this should not happen!");
|
||||
}
|
||||
r = RTLSYM.ARRAYSETASSIGN;
|
||||
evalue = el_una(OPaddr, TYnptr, evalue);
|
||||
// This is a hack so we can call postblits on const/immutable objects.
|
||||
|
|
|
@ -9896,9 +9896,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);
|
||||
|
@ -12638,7 +12640,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())
|
||||
{
|
||||
|
|
|
@ -4222,6 +4222,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;
|
||||
}
|
||||
|
@ -4258,6 +4259,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[]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -237,7 +237,7 @@ public:
|
|||
auto e1 = doInlineAs!Expression(ifs.ifbody, ids);
|
||||
assert(ids.foundReturn);
|
||||
auto e2 = doInlineAs!Expression(s3, ids);
|
||||
|
||||
assert(e2);
|
||||
Expression e = new CondExp(econd.loc, econd, e1, e2);
|
||||
e.type = e1.type;
|
||||
if (e.type.ty == Ttuple)
|
||||
|
@ -250,6 +250,7 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
ids.foundReturn = false;
|
||||
auto e = doInlineAs!Expression(sx, ids);
|
||||
result = Expression.combine(result, e);
|
||||
}
|
||||
|
@ -375,6 +376,7 @@ public:
|
|||
|
||||
override void visit(ImportStatement s)
|
||||
{
|
||||
//printf("ImportStatement.doInlineAs!%s()\n", Result.stringof.ptr);
|
||||
}
|
||||
|
||||
override void visit(ForStatement s)
|
||||
|
|
|
@ -156,6 +156,7 @@ nothrow @nogc pure:
|
|||
static if (op == "+") return longdouble_soft(rhs).ld_add(this);
|
||||
else static if (op == "-") return longdouble_soft(rhs).ld_sub(this);
|
||||
else static if (op == "*") return longdouble_soft(rhs).ld_mul(this);
|
||||
else static if (op == "/") return longdouble_soft(rhs).ld_div(this);
|
||||
else static if (op == "%") return longdouble_soft(rhs).ld_mod(this);
|
||||
else static assert(false, "Operator `"~op~"` is not implemented");
|
||||
}
|
||||
|
|
|
@ -2845,11 +2845,21 @@ 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)
|
||||
{
|
||||
// @@@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)
|
||||
{
|
||||
rs.error("`return` statements cannot be in `finally` bodies");
|
||||
|
|
10
test/compilable/backendfloatoptim.d
Normal file
10
test/compilable/backendfloatoptim.d
Normal file
|
@ -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);
|
||||
}
|
|
@ -85,7 +85,7 @@ class C : Object
|
|||
}
|
||||
invariant
|
||||
{
|
||||
this.__invariant1() , this.__invariant2();
|
||||
this.__invariant0() , this.__invariant1();
|
||||
}
|
||||
}
|
||||
enum __c_wchar_t : dchar;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
17
test/compilable/test23082.d
Normal file
17
test/compilable/test23082.d
Normal file
|
@ -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);
|
||||
}
|
22
test/compilable/test23166.d
Normal file
22
test/compilable/test23166.d
Normal file
|
@ -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");
|
||||
}
|
33
test/compilable/test23172.d
Normal file
33
test/compilable/test23172.d
Normal file
|
@ -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
|
||||
}
|
16
test/fail_compilation/fail23181.d
Normal file
16
test/fail_compilation/fail23181.d
Normal file
|
@ -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();
|
||||
}
|
|
@ -55,7 +55,7 @@ L1:
|
|||
scope(failure) { L2: goto L1; } // OK
|
||||
goto L2; // NG
|
||||
|
||||
scope(failure) { return; } // OK
|
||||
|
||||
|
||||
foreach (i; 0..1)
|
||||
{
|
||||
|
|
|
@ -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`
|
||||
---
|
||||
*/
|
||||
|
||||
|
|
21
test/fail_compilation/test21443.d
Normal file
21
test/fail_compilation/test21443.d
Normal file
|
@ -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
|
||||
}
|
12
test/fail_compilation/test23170.d
Normal file
12
test/fail_compilation/test23170.d
Normal file
|
@ -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; }
|
3
test/runnable/extra-files/lib21723a.d
Normal file
3
test/runnable/extra-files/lib21723a.d
Normal file
|
@ -0,0 +1,3 @@
|
|||
import lib21723b;
|
||||
|
||||
alias Struct = lib21723b.Struct;
|
4
test/runnable/extra-files/lib21723b.d
Normal file
4
test/runnable/extra-files/lib21723b.d
Normal file
|
@ -0,0 +1,4 @@
|
|||
struct Struct {
|
||||
invariant { void call() { } }
|
||||
void templfun()() { }
|
||||
}
|
10
test/runnable/extra-files/lib23148.d
Normal file
10
test/runnable/extra-files/lib23148.d
Normal file
|
@ -0,0 +1,10 @@
|
|||
struct Struct {
|
||||
SumType!() v1;
|
||||
}
|
||||
void foo()() { SumType!() v2; }
|
||||
struct SumType() {
|
||||
~this() { }
|
||||
invariant { alias a = {}; match!a(); }
|
||||
|
||||
}
|
||||
void match(alias handler)() { }
|
5
test/runnable/extra-files/test21723.d
Normal file
5
test/runnable/extra-files/test21723.d
Normal file
|
@ -0,0 +1,5 @@
|
|||
import lib21723a;
|
||||
|
||||
void trigger(Struct val) { val.templfun; }
|
||||
|
||||
void main() { alias lambda = a => a; }
|
6
test/runnable/extra-files/test23148.d
Normal file
6
test/runnable/extra-files/test23148.d
Normal file
|
@ -0,0 +1,6 @@
|
|||
import lib23148;
|
||||
|
||||
alias l = _ => 0;
|
||||
void main() {
|
||||
foo!()();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
6
test/runnable/test21723.sh
Normal file
6
test/runnable/test21723.sh
Normal file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
$DMD -m${MODEL} -I${EXTRA_FILES} -of${OUTPUT_BASE}${LIBEXT} -lib ${EXTRA_FILES}/lib21723a.d ${EXTRA_FILES}/lib21723b.d
|
||||
$DMD -m${MODEL} -I${EXTRA_FILES} -of${OUTPUT_BASE}${EXE} -inline ${EXTRA_FILES}/test21723.d ${OUTPUT_BASE}${LIBEXT}
|
||||
|
||||
rm_retry ${OUTPUT_BASE}{${LIBEXT},${EXE}}
|
6
test/runnable/test23148.sh
Normal file
6
test/runnable/test23148.sh
Normal file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
$DMD -m${MODEL} -I${EXTRA_FILES} -of${OUTPUT_BASE}${LIBEXT} -lib ${EXTRA_FILES}/lib23148.d
|
||||
$DMD -m${MODEL} -I${EXTRA_FILES} -of${OUTPUT_BASE}${EXE} ${EXTRA_FILES}/test23148.d ${OUTPUT_BASE}${LIBEXT}
|
||||
|
||||
rm_retry ${OUTPUT_BASE}{${LIBEXT},${EXE}}
|
27
test/runnable/test23181.d
Normal file
27
test/runnable/test23181.d
Normal file
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue