d: Merge upstream dmd, druntime 5f7552bb28, phobos 67a47cf39.
D front-end changes: - Import dmd v2.103.0-rc.1. D runtime changes: - Import druntime v2.103.0-rc.1. Phobos changes: - Import phobos v2.103.0-rc.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 5f7552bb28. * dmd/VERSION: Bump version to v2.103.0-rc.1. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 5f7552bb28. * src/MERGE: Merge upstream phobos 67a47cf39.
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
||||
4ca4140e584c055a8a9bc727e56a97ebcecd61e0
|
||||
5f7552bb2829b75d5e36cc767a476e1ab35147b7
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/dmd repository.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
v2.103.0-beta.1
|
||||
v2.103.0-rc.1
|
||||
|
||||
+11
-1
@@ -2036,7 +2036,7 @@ public:
|
||||
}
|
||||
auto er = interpret(e.e1, istate, CTFEGoal.LValue);
|
||||
if (auto ve = er.isVarExp())
|
||||
if (ve.var == istate.fd.vthis)
|
||||
if (istate && ve.var == istate.fd.vthis)
|
||||
er = interpret(er, istate);
|
||||
|
||||
if (exceptionOrCant(er))
|
||||
@@ -2117,6 +2117,16 @@ public:
|
||||
return CTFEExp.cantexp;
|
||||
assert(e.type);
|
||||
|
||||
// There's a terrible hack in `dmd.dsymbolsem` that special case
|
||||
// a struct with all zeros to an `ExpInitializer(BlitExp(IntegerExp(0)))`
|
||||
// There's matching code for it in e2ir (toElem's visitAssignExp),
|
||||
// so we need the same hack here.
|
||||
// This does not trigger for global as they get a normal initializer.
|
||||
if (auto ts = e.type.isTypeStruct())
|
||||
if (auto ae = e.isBlitExp())
|
||||
if (ae.e2.op == EXP.int64)
|
||||
e = ts.defaultInitLiteral(loc);
|
||||
|
||||
if (e.op == EXP.construct || e.op == EXP.blit)
|
||||
{
|
||||
AssignExp ae = cast(AssignExp)e;
|
||||
|
||||
+17
-4
@@ -2162,10 +2162,23 @@ extern (C++) final class ArrayScopeSymbol : ScopeDsymbol
|
||||
* or a variable (in which case an expression is created in
|
||||
* toir.c).
|
||||
*/
|
||||
auto e = new VoidInitializer(Loc.initial);
|
||||
e.type = Type.tsize_t;
|
||||
v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, e);
|
||||
v.storage_class |= STC.temp | STC.ctfe; // it's never a true static variable
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=16213
|
||||
// For static arrays $ is known at compile time,
|
||||
// so declare it as a manifest constant.
|
||||
auto tsa = ce.type ? ce.type.isTypeSArray() : null;
|
||||
if (tsa)
|
||||
{
|
||||
auto e = new ExpInitializer(loc, tsa.dim);
|
||||
v = new VarDeclaration(loc, tsa.dim.type, Id.dollar, e, STC.manifest);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto e = new VoidInitializer(Loc.initial);
|
||||
e.type = Type.tsize_t;
|
||||
v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, e);
|
||||
v.storage_class |= STC.temp | STC.ctfe; // it's never a true static variable
|
||||
}
|
||||
}
|
||||
*pvar = v;
|
||||
}
|
||||
|
||||
@@ -1155,6 +1155,69 @@ L1:
|
||||
return e1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether `outerFunc` and `calledFunc` have the same `this`.
|
||||
* If `calledFunc` is the member of a base class of the class that contains
|
||||
* `outerFunc` we consider that they have the same this.
|
||||
*
|
||||
* This function is used to test whether `this` needs to be prepended to
|
||||
* a function call or function symbol. For example:
|
||||
*
|
||||
* struct X
|
||||
* {
|
||||
* void gun() {}
|
||||
* }
|
||||
* struct A
|
||||
* {
|
||||
* void fun() {}
|
||||
* void sun()
|
||||
* {
|
||||
* fun();
|
||||
* X.gun(); // error
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* When `fun` is called, `outerfunc` = `sun` and `calledFunc = `fun`.
|
||||
* `sun` is a member of `A` and `fun` is also a member of `A`, therefore
|
||||
* `this` can be prepended to `fun`. When `gun` is called (it will result
|
||||
* in an error, but that is not relevant here), which is a member of `X`,
|
||||
* no `this` is needed because the outer function does not have the same
|
||||
* `this` as `gun`.
|
||||
*
|
||||
* Returns:
|
||||
* `true` if outerFunc and calledFunc may use the same `this` pointer.
|
||||
* `false` otherwise.
|
||||
*/
|
||||
private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc)
|
||||
{
|
||||
auto thisAd = outerFunc.isMemberLocal();
|
||||
if (!thisAd)
|
||||
return false;
|
||||
|
||||
auto requiredAd = calledFunc.isMemberLocal();
|
||||
if (!requiredAd)
|
||||
return false;
|
||||
|
||||
if (thisAd == requiredAd)
|
||||
return true;
|
||||
|
||||
// outerfunc is the member of a base class that contains calledFunc,
|
||||
// then we consider that they have the same this.
|
||||
auto cd = requiredAd.isClassDeclaration();
|
||||
if (!cd)
|
||||
return false;
|
||||
|
||||
if (cd.isBaseOf2(thisAd.isClassDeclaration()))
|
||||
return true;
|
||||
|
||||
// if outerfunc is the member of a nested aggregate, then let
|
||||
// getRightThis take care of this.
|
||||
if (thisAd.isNested())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/***************************************
|
||||
* Pull out any properties.
|
||||
*/
|
||||
@@ -5209,7 +5272,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||
if (exp.f.checkNestedReference(sc, exp.loc))
|
||||
return setError();
|
||||
|
||||
if (hasThis(sc))
|
||||
auto memberFunc = hasThis(sc);
|
||||
if (memberFunc && haveSameThis(memberFunc, exp.f))
|
||||
{
|
||||
// Supply an implicit 'this', as in
|
||||
// this.ident
|
||||
@@ -6892,8 +6956,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||
AggregateDeclaration ad = f.isMemberLocal();
|
||||
if (f.needThis())
|
||||
e.e1 = getRightThis(e.loc, sc, ad, e.e1, f);
|
||||
if (e.e1.op == EXP.error)
|
||||
return setError();
|
||||
|
||||
if (f.type.ty == Tfunction)
|
||||
{
|
||||
@@ -7207,7 +7269,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||
}
|
||||
if (f.needThis())
|
||||
{
|
||||
if (hasThis(sc))
|
||||
auto memberFunc = hasThis(sc);
|
||||
if (memberFunc && haveSameThis(memberFunc, f))
|
||||
{
|
||||
/* Should probably supply 'this' after overload resolution,
|
||||
* not before.
|
||||
@@ -7309,6 +7372,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||
goto case Terror;
|
||||
}
|
||||
|
||||
if (sc.flags & SCOPE.Cfile && exp.type && exp.type.toBasetype().ty == Tvoid)
|
||||
{
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23752
|
||||
// `&*((void*)(0))` is allowed in C
|
||||
result = exp;
|
||||
return;
|
||||
}
|
||||
|
||||
if (exp.checkValue())
|
||||
return setError();
|
||||
|
||||
@@ -12311,6 +12382,29 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||
|
||||
Type t1 = exp.e1.type;
|
||||
Type t2 = exp.e2.type;
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23767
|
||||
// `cast(void*) 0` should be treated as `null` so the ternary expression
|
||||
// gets the pointer type of the other branch
|
||||
if (sc.flags & SCOPE.Cfile)
|
||||
{
|
||||
static void rewriteCNull(ref Expression e, ref Type t)
|
||||
{
|
||||
if (!t.isTypePointer())
|
||||
return;
|
||||
if (auto ie = e.optimize(WANTvalue).isIntegerExp())
|
||||
{
|
||||
if (ie.getInteger() == 0)
|
||||
{
|
||||
e = new NullExp(e.loc, Type.tnull);
|
||||
t = Type.tnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
rewriteCNull(exp.e1, t1);
|
||||
rewriteCNull(exp.e2, t2);
|
||||
}
|
||||
|
||||
if (t1.ty == Tnoreturn)
|
||||
{
|
||||
exp.type = t2;
|
||||
|
||||
@@ -4176,6 +4176,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, int flag)
|
||||
}
|
||||
if (v.type.ty == Terror)
|
||||
{
|
||||
e.error("type of variable `%s` has errors", v.toPrettyChars);
|
||||
return ErrorExp.get();
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -34,8 +34,9 @@ import core.stdc.stdio;
|
||||
* loc = the location for reporting line numbers in errors
|
||||
* torig = the type to generate the `TypeInfo` object for
|
||||
* sc = the scope
|
||||
* genObjCode = if true, object code will be generated for the obtained TypeInfo
|
||||
*/
|
||||
extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc)
|
||||
extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope* sc, bool genObjCode = true)
|
||||
{
|
||||
// printf("genTypeInfo() %s\n", torig.toChars());
|
||||
|
||||
@@ -80,7 +81,7 @@ extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope
|
||||
|
||||
// generate a COMDAT for other TypeInfos not available as builtins in
|
||||
// druntime
|
||||
if (!isUnqualifiedClassInfo && !builtinTypeInfo(t))
|
||||
if (!isUnqualifiedClassInfo && !builtinTypeInfo(t) && genObjCode)
|
||||
{
|
||||
if (sc) // if in semantic() pass
|
||||
{
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=16213
|
||||
|
||||
enum Id(size_t i) = i;
|
||||
void main()
|
||||
{
|
||||
int[5] y;
|
||||
y[ Id!($) - 1 ] = 3;
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// PERMUTE_ARGS: -preview=in
|
||||
bool fun(S)(ref S[3] a) { assert(a == [42, 84, 169]); return true; }
|
||||
bool fun2(S)(ref S a) { return true; }
|
||||
void main()
|
||||
@@ -14,4 +15,12 @@ void test2()
|
||||
{
|
||||
static immutable int[2] P = [ 0, 1 ];
|
||||
static assert(f2(P) == 1);
|
||||
immutable BigInt a, b;
|
||||
static assert(glob1.twice == b.twice);
|
||||
static assert(a.twice == b.twice);
|
||||
}
|
||||
|
||||
struct BigInt { int[64] big; }
|
||||
BigInt twice (in BigInt v) @safe pure nothrow @nogc { return v; }
|
||||
|
||||
immutable BigInt glob1 = BigInt.init;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
struct S1(T...) {
|
||||
auto fun() {
|
||||
static assert(__traits(compiles, &T[0]));
|
||||
}
|
||||
}
|
||||
|
||||
struct S2 {
|
||||
void gun() {}
|
||||
S1!gun overloaded;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=10886
|
||||
|
||||
struct A
|
||||
{
|
||||
@property int foo() { return 0; }
|
||||
int bar() { return 0; }
|
||||
}
|
||||
|
||||
struct B
|
||||
{
|
||||
void bar()
|
||||
{
|
||||
alias f = typeof(A.foo); // NG
|
||||
alias b = typeof(A.bar); // ok
|
||||
}
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=21288
|
||||
|
||||
struct XA
|
||||
{
|
||||
int p;
|
||||
}
|
||||
|
||||
struct XB
|
||||
{
|
||||
XA a() { return XA.init; }
|
||||
alias a this;
|
||||
}
|
||||
|
||||
struct XC
|
||||
{
|
||||
void foo()
|
||||
{
|
||||
static assert(XB.p.stringof == "p"); // Error: this for s needs to be type B not type C
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23760
|
||||
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail23760.d(16): Error: type of variable `fail23760.A.state` has errors
|
||||
fail_compilation/fail23760.d(16): Error: `(A).state` cannot be resolved
|
||||
fail_compilation/fail23760.d(21): Error: template instance `fail23760.JavaBridge!(A)` error instantiating
|
||||
fail_compilation/fail23760.d(24): instantiated from here: `JavaClass!(A)`
|
||||
---
|
||||
*/
|
||||
|
||||
class JavaBridge(Class)
|
||||
{
|
||||
static if(is(typeof(__traits(getMember, Class, "state")))) {}
|
||||
alias T = __traits(getOverloads, Class, "state");
|
||||
}
|
||||
|
||||
class JavaClass(CRTP)
|
||||
{
|
||||
JavaBridge!(CRTP) _javaDBridge;
|
||||
}
|
||||
|
||||
class A : JavaClass!A
|
||||
{
|
||||
State* state;
|
||||
}
|
||||
@@ -4,7 +4,7 @@ TEST_OUTPUT:
|
||||
fail_compilation/fail61.d(22): Error: no property `B` for type `fail61.A.B`
|
||||
fail_compilation/fail61.d(23): Error: no property `B` for type `fail61.A.B`
|
||||
fail_compilation/fail61.d(32): Error: no property `A2` for type `fail61.B2`
|
||||
fail_compilation/fail61.d(41): Error: `this` for `foo` needs to be type `B3` not type `fail61.C3`
|
||||
fail_compilation/fail61.d(41): Error: need `this` for `foo` of type `void()`
|
||||
---
|
||||
*/
|
||||
|
||||
|
||||
@@ -110,12 +110,15 @@ struct S6
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail_circular.d(123): Error: circular reference to variable `fail_circular.C.a1`
|
||||
fail_compilation/fail_circular.d(125): Error: circular reference to variable `fail_circular.C.b1`
|
||||
fail_compilation/fail_circular.d(127): Error: circular reference to variable `fail_circular.C.c1`
|
||||
fail_compilation/fail_circular.d(130): Error: circular reference to variable `fail_circular.C.a1a`
|
||||
fail_compilation/fail_circular.d(133): Error: circular reference to variable `fail_circular.C.b1a`
|
||||
fail_compilation/fail_circular.d(136): Error: circular reference to variable `fail_circular.C.c1a`
|
||||
fail_compilation/fail_circular.d(126): Error: circular reference to variable `fail_circular.C.a1`
|
||||
fail_compilation/fail_circular.d(128): Error: circular reference to variable `fail_circular.C.b1`
|
||||
fail_compilation/fail_circular.d(130): Error: circular reference to variable `fail_circular.C.c1`
|
||||
fail_compilation/fail_circular.d(133): Error: circular reference to variable `fail_circular.C.a1a`
|
||||
fail_compilation/fail_circular.d(132): Error: type of variable `fail_circular.C.a1b` has errors
|
||||
fail_compilation/fail_circular.d(136): Error: circular reference to variable `fail_circular.C.b1a`
|
||||
fail_compilation/fail_circular.d(135): Error: type of variable `fail_circular.C.b1b` has errors
|
||||
fail_compilation/fail_circular.d(139): Error: circular reference to variable `fail_circular.C.c1a`
|
||||
fail_compilation/fail_circular.d(138): Error: type of variable `fail_circular.C.c1b` has errors
|
||||
---
|
||||
*/
|
||||
class C
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/ice19295.d(11): Error: `this` for `gun` needs to be type `S2` not type `S1!(gun)`
|
||||
fail_compilation/ice19295.d(11): while evaluating `pragma(msg, &gun)`
|
||||
fail_compilation/ice19295.d(17): Error: template instance `ice19295.S1!(gun)` error instantiating
|
||||
---
|
||||
*/
|
||||
struct S1(T...) {
|
||||
auto fun() {
|
||||
pragma(msg, &T[0]);
|
||||
}
|
||||
}
|
||||
|
||||
struct S2 {
|
||||
void gun() {}
|
||||
S1!gun overloaded;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/ice23781.d(10): Error: variable `b` cannot be read at compile time
|
||||
---
|
||||
**/
|
||||
struct Bar { int i; }
|
||||
ref const(Bar) func1 (const return ref Bar b) { return b; }
|
||||
immutable E1 = Bar();
|
||||
enum E2 = &E1.func1();
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/ice9439.d(12): Error: `this` for `foo` needs to be type `Derived` not type `ice9439.Base`
|
||||
fail_compilation/ice9439.d(12): while evaluating: `static assert((__error).foo())`
|
||||
fail_compilation/ice9439.d(12): Error: need `this` for `foo` of type `int()`
|
||||
fail_compilation/ice9439.d(12): while evaluating: `static assert(foo())`
|
||||
fail_compilation/ice9439.d(19): Error: template instance `ice9439.Base.boo!(foo)` error instantiating
|
||||
---
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
4ca4140e584c055a8a9bc727e56a97ebcecd61e0
|
||||
5f7552bb2829b75d5e36cc767a476e1ab35147b7
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/dmd repository.
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
454dff14dcbd005f9550302c5836ef8e06ab663a
|
||||
67a47cf39d52b3cb3ae4117c0237415e03737f8a
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/phobos repository.
|
||||
|
||||
@@ -3033,13 +3033,13 @@ private
|
||||
4.5270000862445199635215E-5,
|
||||
];
|
||||
static immutable double[7] logp1Q = [
|
||||
1.0000000000000000000000E0,
|
||||
6.0118660497603843919306E1,
|
||||
2.1642788614495947685003E2,
|
||||
3.0909872225312059774938E2,
|
||||
2.2176239823732856465394E2,
|
||||
8.3047565967967209469434E1,
|
||||
1.5062909083469192043167E1,
|
||||
1.0000000000000000000000E0,
|
||||
];
|
||||
|
||||
static immutable double[7] log10P = [
|
||||
@@ -3101,13 +3101,13 @@ private
|
||||
4.5270000862E-5,
|
||||
];
|
||||
static immutable float[7] logp1Q = [
|
||||
1.00000000000E0,
|
||||
6.01186604976E1,
|
||||
2.16427886144E2,
|
||||
3.09098722253E2,
|
||||
2.21762398237E2,
|
||||
8.30475659679E1,
|
||||
1.50629090834E1,
|
||||
1.00000000000E0,
|
||||
];
|
||||
|
||||
// log2 and log10 uses the same coefficients as log.
|
||||
@@ -3323,7 +3323,7 @@ private T logImpl(T, bool LOG1P = false)(T x) @safe pure nothrow @nogc
|
||||
}
|
||||
static foreach (F; AliasSeq!(float, double, real))
|
||||
{{
|
||||
F[2][24] vals = [
|
||||
scope F[2][] vals = [
|
||||
[F(1), F(0x0p+0)], [F(2), F(0x1.62e42fefa39ef358p-1)],
|
||||
[F(4), F(0x1.62e42fefa39ef358p+0)], [F(8), F(0x1.0a2b23f3bab73682p+1)],
|
||||
[F(16), F(0x1.62e42fefa39ef358p+1)], [F(32), F(0x1.bb9d3beb8c86b02ep+1)],
|
||||
@@ -3335,6 +3335,9 @@ private T logImpl(T, bool LOG1P = false)(T x) @safe pure nothrow @nogc
|
||||
[F(17), F(0x1.6aa6bc1fa7f79cfp+1)], [F(31), F(0x1.b78ce48912b59f12p+1)],
|
||||
[F(33), F(0x1.bf8d8f4d5b8d1038p+1)], [F(63), F(0x1.09291e8e3181b20ep+2)],
|
||||
[F(65), F(0x1.0b292939429755ap+2)], [F(-0), -F.infinity], [F(0), -F.infinity],
|
||||
[F(0.1), F(-0x1.26bb1bbb5551582ep+1)], [F(0.25), F(-0x1.62e42fefa39ef358p+0)],
|
||||
[F(0.75), F(-0x1.269621134db92784p-2)], [F(0.875), F(-0x1.1178e8227e47bde4p-3)],
|
||||
[F(10), F(0x1.26bb1bbb5551582ep+1)], [F(100), F(0x1.26bb1bbb5551582ep+2)],
|
||||
[F(10000), F(0x1.26bb1bbb5551582ep+3)],
|
||||
];
|
||||
testLog(vals);
|
||||
@@ -3572,7 +3575,7 @@ Ldone:
|
||||
}
|
||||
static foreach (F; AliasSeq!(float, double, real))
|
||||
{{
|
||||
F[2][24] vals = [
|
||||
scope F[2][] vals = [
|
||||
[F(1), F(0x0p+0)], [F(2), F(0x1.34413509f79fef32p-2)],
|
||||
[F(4), F(0x1.34413509f79fef32p-1)], [F(8), F(0x1.ce61cf8ef36fe6cap-1)],
|
||||
[F(16), F(0x1.34413509f79fef32p+0)], [F(32), F(0x1.8151824c7587eafep+0)],
|
||||
@@ -3584,7 +3587,9 @@ Ldone:
|
||||
[F(17), F(0x1.3afeb354b7d9731ap+0)], [F(31), F(0x1.7dc9e145867e62eap+0)],
|
||||
[F(33), F(0x1.84bd545e4baeddp+0)], [F(63), F(0x1.cca1950e4511e192p+0)],
|
||||
[F(65), F(0x1.d01b16f9433cf7b8p+0)], [F(-0), -F.infinity], [F(0), -F.infinity],
|
||||
[F(10000), F(0x1p+2)],
|
||||
[F(0.1), F(-0x1p+0)], [F(0.25), F(-0x1.34413509f79fef32p-1)],
|
||||
[F(0.75), F(-0x1.ffbfc2bbc7803758p-4)], [F(0.875), F(-0x1.db11ed766abf432ep-5)],
|
||||
[F(10), F(0x1p+0)], [F(100), F(0x1p+1)], [F(10000), F(0x1p+2)],
|
||||
];
|
||||
testLog10(vals);
|
||||
}}
|
||||
@@ -3758,7 +3763,7 @@ private T log1pImpl(T)(T x) @safe pure nothrow @nogc
|
||||
}
|
||||
static foreach (F; AliasSeq!(float, double, real))
|
||||
{{
|
||||
F[2][24] vals = [
|
||||
scope F[2][] vals = [
|
||||
[F(1), F(0x1.62e42fefa39ef358p-1)], [F(2), F(0x1.193ea7aad030a976p+0)],
|
||||
[F(4), F(0x1.9c041f7ed8d336bp+0)], [F(8), F(0x1.193ea7aad030a976p+1)],
|
||||
[F(16), F(0x1.6aa6bc1fa7f79cfp+1)], [F(32), F(0x1.bf8d8f4d5b8d1038p+1)],
|
||||
@@ -3770,6 +3775,9 @@ private T log1pImpl(T)(T x) @safe pure nothrow @nogc
|
||||
[F(17), F(0x1.71f7b3a6b918664cp+1)], [F(31), F(0x1.bb9d3beb8c86b02ep+1)],
|
||||
[F(33), F(0x1.c35fc81b90df59c6p+1)], [F(63), F(0x1.0a2b23f3bab73682p+2)],
|
||||
[F(65), F(0x1.0c234da4a23a6686p+2)], [F(-0), F(-0x0p+0)], [F(0), F(0x0p+0)],
|
||||
[F(0.1), F(0x1.8663f793c46c69cp-4)], [F(0.25), F(0x1.c8ff7c79a9a21ac4p-3)],
|
||||
[F(0.75), F(0x1.1e85f5e7040d03ep-1)], [F(0.875), F(0x1.41d8fe84672ae646p-1)],
|
||||
[F(10), F(0x1.32ee3b77f374bb7cp+1)], [F(100), F(0x1.275e2271bba30be4p+2)],
|
||||
[F(10000), F(0x1.26bbed6fbd84182ep+3)],
|
||||
];
|
||||
testLog1p(vals);
|
||||
@@ -3981,7 +3989,7 @@ Ldone:
|
||||
}
|
||||
static foreach (F; AliasSeq!(float, double, real))
|
||||
{{
|
||||
F[2][24] vals = [
|
||||
scope F[2][] vals = [
|
||||
[F(1), F(0x0p+0)], [F(2), F(0x1p+0)],
|
||||
[F(4), F(0x1p+1)], [F(8), F(0x1.8p+1)],
|
||||
[F(16), F(0x1p+2)], [F(32), F(0x1.4p+2)],
|
||||
@@ -3993,6 +4001,9 @@ Ldone:
|
||||
[F(17), F(0x1.0598fdbeb244c5ap+2)], [F(31), F(0x1.3d118d66c4d4e554p+2)],
|
||||
[F(33), F(0x1.42d75a6eb1dfb0e6p+2)], [F(63), F(0x1.7e8bc1179e0caa9cp+2)],
|
||||
[F(65), F(0x1.816e79685c2d2298p+2)], [F(-0), -F.infinity], [F(0), -F.infinity],
|
||||
[F(0.1), F(-0x1.a934f0979a3715fcp+1)], [F(0.25), F(-0x1p+1)],
|
||||
[F(0.75), F(-0x1.a8ff971810a5e182p-2)], [F(0.875), F(-0x1.8a8980abfbd32668p-3)],
|
||||
[F(10), F(0x1.a934f0979a3715fcp+1)], [F(100), F(0x1.a934f0979a3715fcp+2)],
|
||||
[F(10000), F(0x1.a934f0979a3715fcp+3)],
|
||||
];
|
||||
testLog2(vals);
|
||||
@@ -4178,7 +4189,7 @@ private T logbImpl(T)(T x) @trusted pure nothrow @nogc
|
||||
}
|
||||
static foreach (F; AliasSeq!(float, double, real))
|
||||
{{
|
||||
F[2][24] vals = [
|
||||
scope F[2][] vals = [
|
||||
[F(1), F(0x0p+0)], [F(2), F(0x1p+0)],
|
||||
[F(4), F(0x1p+1)], [F(8), F(0x1.8p+1)],
|
||||
[F(16), F(0x1p+2)], [F(32), F(0x1.4p+2)],
|
||||
@@ -4190,6 +4201,9 @@ private T logbImpl(T)(T x) @trusted pure nothrow @nogc
|
||||
[F(17), F(0x1p+2)], [F(31), F(0x1p+2)],
|
||||
[F(33), F(0x1.4p+2)], [F(63), F(0x1.4p+2)],
|
||||
[F(65), F(0x1.8p+2)], [F(-0), -F.infinity], [F(0), -F.infinity],
|
||||
[F(0.1), F(-0x1p+2)], [F(0.25), F(-0x1p+1)],
|
||||
[F(0.75), F(-0x1p+0)], [F(0.875), F(-0x1p+0)],
|
||||
[F(10), F(0x1.8p+1)], [F(100), F(0x1.8p+2)],
|
||||
[F(10000), F(0x1.ap+3)],
|
||||
];
|
||||
testLogb(vals);
|
||||
|
||||
@@ -8812,6 +8812,30 @@ template getSymbolsByUDA(alias symbol, alias attribute)
|
||||
static assert(is(getSymbolsByUDA!(X, X) == AliasSeq!()));
|
||||
}
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=23776
|
||||
@safe pure nothrow @nogc unittest
|
||||
{
|
||||
struct T
|
||||
{
|
||||
struct Tag {}
|
||||
@Tag struct MyStructA {}
|
||||
@Tag struct MyStructB {}
|
||||
@Tag struct MyStructC {}
|
||||
}
|
||||
alias tcomponents = getSymbolsByUDA!(T, T.Tag);
|
||||
static assert(tcomponents.length > 0);
|
||||
|
||||
struct X
|
||||
{
|
||||
struct Tag {}
|
||||
@Tag enum MyEnumA;
|
||||
@Tag enum MyEnumB;
|
||||
@Tag enum MyEnumC;
|
||||
}
|
||||
alias xcomponents = getSymbolsByUDA!(X, X.Tag);
|
||||
static assert(xcomponents.length > 0);
|
||||
}
|
||||
|
||||
// getSymbolsByUDA produces wrong result if one of the symbols having the UDA is a function
|
||||
// https://issues.dlang.org/show_bug.cgi?id=18624
|
||||
@safe unittest
|
||||
@@ -8866,7 +8890,8 @@ private template getSymbolsByUDAImpl(alias symbol, alias attribute, names...)
|
||||
alias member = __traits(getMember, symbol, names[0]);
|
||||
|
||||
// Filtering not compiled members such as alias of basic types.
|
||||
static if (isAliasSeq!member || isType!member)
|
||||
static if (isAliasSeq!member ||
|
||||
(isType!member && !isAggregateType!member && !is(member == enum)))
|
||||
{
|
||||
alias getSymbolsByUDAImpl = tail;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user