d: Merge upstream dmd 423f19b41, druntime 100a608c, phobos a1f8c4c07.

D Runtime changes:

    - Fix stdc.stdio bindings to not depend on druntime (PR104729).
    - Implement stdc.math for Solaris (PR104735).

gcc/d/ChangeLog:

	* dmd/MERGE: Merge upstream dmd 423f19b41.

libphobos/ChangeLog:

	* libdruntime/MERGE: Merge upstream druntime 100a608c.
	* src/MERGE: Merge upstream phobos a1f8c4c07.
This commit is contained in:
Iain Buclaw 2022-03-02 18:16:08 +01:00
parent 12f8dc0b64
commit 8977f4bec6
21 changed files with 503 additions and 136 deletions

View File

@ -1,4 +1,4 @@
cf63dd8e5a77ecb68cf5e7c43bf7b6c4c1154bbe 423f19b41089f627808bf16ff21c60c0791712ba
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository. merge done from the dlang/dmd repository.

View File

@ -4295,8 +4295,13 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param
if (ti && ti.toAlias() == t.sym) if (ti && ti.toAlias() == t.sym)
{ {
auto tx = new TypeInstance(Loc.initial, ti); auto tx = new TypeInstance(Loc.initial, ti);
result = deduceType(tx, sc, tparam, parameters, dedtypes, wm); auto m = deduceType(tx, sc, tparam, parameters, dedtypes, wm);
return; // if we have a no match we still need to check alias this
if (m != MATCH.nomatch)
{
result = m;
return;
}
} }
/* Match things like: /* Match things like:

View File

@ -83,7 +83,7 @@ void emplaceExp(T : UnionExp)(T* p, Expression e)
memcpy(p, cast(void*)e, e.size); memcpy(p, cast(void*)e, e.size);
} }
// Return value for `checkModifiable` /// Return value for `checkModifiable`
enum Modifiable enum Modifiable
{ {
/// Not modifiable /// Not modifiable
@ -1766,6 +1766,7 @@ extern (C++) abstract class Expression : ASTNode
} }
/*********************************************************** /***********************************************************
* A compile-time known integer value
*/ */
extern (C++) final class IntegerExp : Expression extern (C++) final class IntegerExp : Expression
{ {
@ -1982,6 +1983,7 @@ extern (C++) final class IntegerExp : Expression
/*********************************************************** /***********************************************************
* Use this expression for error recovery. * Use this expression for error recovery.
*
* It should behave as a 'sink' to prevent further cascaded error messages. * It should behave as a 'sink' to prevent further cascaded error messages.
*/ */
extern (C++) final class ErrorExp : Expression extern (C++) final class ErrorExp : Expression
@ -2026,6 +2028,8 @@ extern (C++) final class ErrorExp : Expression
/*********************************************************** /***********************************************************
* An uninitialized value, * An uninitialized value,
* generated from void initializers. * generated from void initializers.
*
* https://dlang.org/spec/declaration.html#void_init
*/ */
extern (C++) final class VoidInitExp : Expression extern (C++) final class VoidInitExp : Expression
{ {
@ -2052,6 +2056,7 @@ extern (C++) final class VoidInitExp : Expression
/*********************************************************** /***********************************************************
* A compile-time known floating point number
*/ */
extern (C++) final class RealExp : Expression extern (C++) final class RealExp : Expression
{ {
@ -2127,6 +2132,7 @@ extern (C++) final class RealExp : Expression
} }
/*********************************************************** /***********************************************************
* A compile-time complex number (deprecated)
*/ */
extern (C++) final class ComplexExp : Expression extern (C++) final class ComplexExp : Expression
{ {
@ -2202,6 +2208,12 @@ extern (C++) final class ComplexExp : Expression
} }
/*********************************************************** /***********************************************************
* An identifier in the context of an expression (as opposed to a declaration)
*
* ---
* int x; // VarDeclaration with Identifier
* x++; // PostExp with IdentifierExp
* ---
*/ */
extern (C++) class IdentifierExp : Expression extern (C++) class IdentifierExp : Expression
{ {
@ -2235,6 +2247,9 @@ extern (C++) class IdentifierExp : Expression
} }
/*********************************************************** /***********************************************************
* The dollar operator used when indexing or slicing an array. E.g `a[$]`, `a[1 .. $]` etc.
*
* https://dlang.org/spec/arrays.html#array-length
*/ */
extern (C++) final class DollarExp : IdentifierExp extern (C++) final class DollarExp : IdentifierExp
{ {
@ -2353,6 +2368,8 @@ extern (C++) final class SuperExp : ThisExp
} }
/*********************************************************** /***********************************************************
* A compile-time known `null` value
*
* https://dlang.org/spec/expression.html#null * https://dlang.org/spec/expression.html#null
*/ */
extern (C++) final class NullExp : Expression extern (C++) final class NullExp : Expression
@ -2791,6 +2808,12 @@ extern (C++) final class StringExp : Expression
} }
/*********************************************************** /***********************************************************
* A sequence of expressions
*
* ---
* alias AliasSeq(T...) = T;
* alias Tup = AliasSeq!(3, int, "abc");
* ---
*/ */
extern (C++) final class TupleExp : Expression extern (C++) final class TupleExp : Expression
{ {
@ -4127,6 +4150,9 @@ extern (C++) final class TraitsExp : Expression
} }
/*********************************************************** /***********************************************************
* Generates a halt instruction
*
* `assert(0)` gets rewritten to this with `CHECKACTION.halt`
*/ */
extern (C++) final class HaltExp : Expression extern (C++) final class HaltExp : Expression
{ {
@ -4185,6 +4211,9 @@ extern (C++) final class IsExp : Expression
} }
/*********************************************************** /***********************************************************
* Base class for unary operators
*
* https://dlang.org/spec/expression.html#unary-expression
*/ */
extern (C++) abstract class UnaExp : Expression extern (C++) abstract class UnaExp : Expression
{ {
@ -4255,6 +4284,7 @@ alias fp_t = UnionExp function(const ref Loc loc, Type, Expression, Expression);
alias fp2_t = bool function(const ref Loc loc, EXP, Expression, Expression); alias fp2_t = bool function(const ref Loc loc, EXP, Expression, Expression);
/*********************************************************** /***********************************************************
* Base class for binary operators
*/ */
extern (C++) abstract class BinExp : Expression extern (C++) abstract class BinExp : Expression
{ {
@ -4550,6 +4580,7 @@ extern (C++) abstract class BinExp : Expression
} }
/*********************************************************** /***********************************************************
* Binary operator assignment, `+=` `-=` `*=` etc.
*/ */
extern (C++) class BinAssignExp : BinExp extern (C++) class BinAssignExp : BinExp
{ {
@ -4582,6 +4613,8 @@ extern (C++) class BinAssignExp : BinExp
} }
/*********************************************************** /***********************************************************
* A string mixin, `mixin("x")`
*
* https://dlang.org/spec/expression.html#mixin_expressions * https://dlang.org/spec/expression.html#mixin_expressions
*/ */
extern (C++) final class MixinExp : Expression extern (C++) final class MixinExp : Expression
@ -4628,6 +4661,11 @@ extern (C++) final class MixinExp : Expression
} }
/*********************************************************** /***********************************************************
* An import expression, `import("file.txt")`
*
* Not to be confused with module imports, `import std.stdio`, which is an `ImportStatement`
*
* https://dlang.org/spec/expression.html#import_expressions
*/ */
extern (C++) final class ImportExp : UnaExp extern (C++) final class ImportExp : UnaExp
{ {
@ -4643,6 +4681,8 @@ extern (C++) final class ImportExp : UnaExp
} }
/*********************************************************** /***********************************************************
* An assert expression, `assert(x == y)`
*
* https://dlang.org/spec/expression.html#assert_expressions * https://dlang.org/spec/expression.html#assert_expressions
*/ */
extern (C++) final class AssertExp : UnaExp extern (C++) final class AssertExp : UnaExp
@ -5153,6 +5193,7 @@ FuncDeclaration isFuncAddress(Expression e, bool* hasOverloads = null)
} }
/*********************************************************** /***********************************************************
* The 'address of' operator, `&p`
*/ */
extern (C++) final class AddrExp : UnaExp extern (C++) final class AddrExp : UnaExp
{ {
@ -5174,6 +5215,7 @@ extern (C++) final class AddrExp : UnaExp
} }
/*********************************************************** /***********************************************************
* The pointer dereference operator, `*p`
*/ */
extern (C++) final class PtrExp : UnaExp extern (C++) final class PtrExp : UnaExp
{ {
@ -5226,6 +5268,7 @@ extern (C++) final class PtrExp : UnaExp
} }
/*********************************************************** /***********************************************************
* The negation operator, `-x`
*/ */
extern (C++) final class NegExp : UnaExp extern (C++) final class NegExp : UnaExp
{ {
@ -5241,6 +5284,7 @@ extern (C++) final class NegExp : UnaExp
} }
/*********************************************************** /***********************************************************
* The unary add operator, `+x`
*/ */
extern (C++) final class UAddExp : UnaExp extern (C++) final class UAddExp : UnaExp
{ {
@ -5256,6 +5300,7 @@ extern (C++) final class UAddExp : UnaExp
} }
/*********************************************************** /***********************************************************
* The bitwise complement operator, `~x`
*/ */
extern (C++) final class ComExp : UnaExp extern (C++) final class ComExp : UnaExp
{ {
@ -5271,6 +5316,7 @@ extern (C++) final class ComExp : UnaExp
} }
/*********************************************************** /***********************************************************
* The logical not operator, `!x`
*/ */
extern (C++) final class NotExp : UnaExp extern (C++) final class NotExp : UnaExp
{ {
@ -5286,6 +5332,9 @@ extern (C++) final class NotExp : UnaExp
} }
/*********************************************************** /***********************************************************
* The delete operator, `delete x` (deprecated)
*
* https://dlang.org/spec/expression.html#delete_expressions
*/ */
extern (C++) final class DeleteExp : UnaExp extern (C++) final class DeleteExp : UnaExp
{ {
@ -5304,7 +5353,11 @@ extern (C++) final class DeleteExp : UnaExp
} }
/*********************************************************** /***********************************************************
* Possible to cast to one type while painting to another type * The type cast operator, `cast(T) x`
*
* It's possible to cast to one type while painting to another type
*
* https://dlang.org/spec/expression.html#cast_expressions
*/ */
extern (C++) final class CastExp : UnaExp extern (C++) final class CastExp : UnaExp
{ {
@ -5500,6 +5553,7 @@ extern (C++) final class SliceExp : UnaExp
} }
/*********************************************************** /***********************************************************
* The `.length` property of an array
*/ */
extern (C++) final class ArrayLengthExp : UnaExp extern (C++) final class ArrayLengthExp : UnaExp
{ {
@ -5684,6 +5738,11 @@ extern (C++) final class IntervalExp : Expression
} }
} }
/***********************************************************
* The `dg.ptr` property, pointing to the delegate's 'context'
*
* c.f.`DelegateFuncptrExp` for the delegate's function pointer `dg.funcptr`
*/
extern (C++) final class DelegatePtrExp : UnaExp extern (C++) final class DelegatePtrExp : UnaExp
{ {
extern (D) this(const ref Loc loc, Expression e1) extern (D) this(const ref Loc loc, Expression e1)
@ -5719,6 +5778,9 @@ extern (C++) final class DelegatePtrExp : UnaExp
} }
/*********************************************************** /***********************************************************
* The `dg.funcptr` property, pointing to the delegate's function
*
* c.f.`DelegatePtrExp` for the delegate's function pointer `dg.ptr`
*/ */
extern (C++) final class DelegateFuncptrExp : UnaExp extern (C++) final class DelegateFuncptrExp : UnaExp
{ {
@ -5835,7 +5897,7 @@ extern (C++) final class IndexExp : BinExp
} }
/*********************************************************** /***********************************************************
* For both i++ and i-- * The postfix increment/decrement operator, `i++` / `i--`
*/ */
extern (C++) final class PostExp : BinExp extern (C++) final class PostExp : BinExp
{ {
@ -5852,7 +5914,7 @@ extern (C++) final class PostExp : BinExp
} }
/*********************************************************** /***********************************************************
* For both ++i and --i * The prefix increment/decrement operator, `++i` / `--i`
*/ */
extern (C++) final class PreExp : UnaExp extern (C++) final class PreExp : UnaExp
{ {
@ -5876,6 +5938,9 @@ enum MemorySet
} }
/*********************************************************** /***********************************************************
* The assignment / initialization operator, `=`
*
* Note: operator assignment `op=` has a different base class, `BinAssignExp`
*/ */
extern (C++) class AssignExp : BinExp extern (C++) class AssignExp : BinExp
{ {
@ -5953,6 +6018,7 @@ extern (C++) final class ConstructExp : AssignExp
} }
/*********************************************************** /***********************************************************
* A bit-for-bit copy from `e2` to `e1`
*/ */
extern (C++) final class BlitExp : AssignExp extern (C++) final class BlitExp : AssignExp
{ {
@ -5981,6 +6047,7 @@ extern (C++) final class BlitExp : AssignExp
} }
/*********************************************************** /***********************************************************
* `x += y`
*/ */
extern (C++) final class AddAssignExp : BinAssignExp extern (C++) final class AddAssignExp : BinAssignExp
{ {
@ -5996,6 +6063,7 @@ extern (C++) final class AddAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* `x -= y`
*/ */
extern (C++) final class MinAssignExp : BinAssignExp extern (C++) final class MinAssignExp : BinAssignExp
{ {
@ -6011,6 +6079,7 @@ extern (C++) final class MinAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* `x *= y`
*/ */
extern (C++) final class MulAssignExp : BinAssignExp extern (C++) final class MulAssignExp : BinAssignExp
{ {
@ -6026,6 +6095,7 @@ extern (C++) final class MulAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* `x /= y`
*/ */
extern (C++) final class DivAssignExp : BinAssignExp extern (C++) final class DivAssignExp : BinAssignExp
{ {
@ -6041,6 +6111,7 @@ extern (C++) final class DivAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* `x %= y`
*/ */
extern (C++) final class ModAssignExp : BinAssignExp extern (C++) final class ModAssignExp : BinAssignExp
{ {
@ -6056,6 +6127,7 @@ extern (C++) final class ModAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* `x &= y`
*/ */
extern (C++) final class AndAssignExp : BinAssignExp extern (C++) final class AndAssignExp : BinAssignExp
{ {
@ -6071,6 +6143,7 @@ extern (C++) final class AndAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* `x |= y`
*/ */
extern (C++) final class OrAssignExp : BinAssignExp extern (C++) final class OrAssignExp : BinAssignExp
{ {
@ -6086,6 +6159,7 @@ extern (C++) final class OrAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* `x ^= y`
*/ */
extern (C++) final class XorAssignExp : BinAssignExp extern (C++) final class XorAssignExp : BinAssignExp
{ {
@ -6101,6 +6175,7 @@ extern (C++) final class XorAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* `x ^^= y`
*/ */
extern (C++) final class PowAssignExp : BinAssignExp extern (C++) final class PowAssignExp : BinAssignExp
{ {
@ -6116,6 +6191,7 @@ extern (C++) final class PowAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* `x <<= y`
*/ */
extern (C++) final class ShlAssignExp : BinAssignExp extern (C++) final class ShlAssignExp : BinAssignExp
{ {
@ -6131,6 +6207,7 @@ extern (C++) final class ShlAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* `x >>= y`
*/ */
extern (C++) final class ShrAssignExp : BinAssignExp extern (C++) final class ShrAssignExp : BinAssignExp
{ {
@ -6146,6 +6223,7 @@ extern (C++) final class ShrAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* `x >>>= y`
*/ */
extern (C++) final class UshrAssignExp : BinAssignExp extern (C++) final class UshrAssignExp : BinAssignExp
{ {
@ -6161,7 +6239,9 @@ extern (C++) final class UshrAssignExp : BinAssignExp
} }
/*********************************************************** /***********************************************************
* The ~= operator. It can have one of the following operators: * The `~=` operator.
*
* It can have one of the following operators:
* *
* EXP.concatenateAssign - appending T[] to T[] * EXP.concatenateAssign - appending T[] to T[]
* EXP.concatenateElemAssign - appending T to T[] * EXP.concatenateElemAssign - appending T to T[]
@ -6188,7 +6268,9 @@ extern (C++) class CatAssignExp : BinAssignExp
} }
} }
/// /***********************************************************
* The `~=` operator when appending a single element
*/
extern (C++) final class CatElemAssignExp : CatAssignExp extern (C++) final class CatElemAssignExp : CatAssignExp
{ {
extern (D) this(const ref Loc loc, Type type, Expression e1, Expression e2) extern (D) this(const ref Loc loc, Type type, Expression e1, Expression e2)
@ -6203,7 +6285,9 @@ extern (C++) final class CatElemAssignExp : CatAssignExp
} }
} }
/// /***********************************************************
* The `~=` operator when appending a single `dchar`
*/
extern (C++) final class CatDcharAssignExp : CatAssignExp extern (C++) final class CatDcharAssignExp : CatAssignExp
{ {
extern (D) this(const ref Loc loc, Type type, Expression e1, Expression e2) extern (D) this(const ref Loc loc, Type type, Expression e1, Expression e2)
@ -6219,6 +6303,8 @@ extern (C++) final class CatDcharAssignExp : CatAssignExp
} }
/*********************************************************** /***********************************************************
* The addition operator, `x + y`
*
* https://dlang.org/spec/expression.html#add_expressions * https://dlang.org/spec/expression.html#add_expressions
*/ */
extern (C++) final class AddExp : BinExp extern (C++) final class AddExp : BinExp
@ -6235,6 +6321,9 @@ extern (C++) final class AddExp : BinExp
} }
/*********************************************************** /***********************************************************
* The minus operator, `x - y`
*
* https://dlang.org/spec/expression.html#add_expressions
*/ */
extern (C++) final class MinExp : BinExp extern (C++) final class MinExp : BinExp
{ {
@ -6250,6 +6339,8 @@ extern (C++) final class MinExp : BinExp
} }
/*********************************************************** /***********************************************************
* The concatenation operator, `x ~ y`
*
* https://dlang.org/spec/expression.html#cat_expressions * https://dlang.org/spec/expression.html#cat_expressions
*/ */
extern (C++) final class CatExp : BinExp extern (C++) final class CatExp : BinExp
@ -6273,6 +6364,8 @@ extern (C++) final class CatExp : BinExp
} }
/*********************************************************** /***********************************************************
* The multiplication operator, `x * y`
*
* https://dlang.org/spec/expression.html#mul_expressions * https://dlang.org/spec/expression.html#mul_expressions
*/ */
extern (C++) final class MulExp : BinExp extern (C++) final class MulExp : BinExp
@ -6289,6 +6382,8 @@ extern (C++) final class MulExp : BinExp
} }
/*********************************************************** /***********************************************************
* The division operator, `x / y`
*
* https://dlang.org/spec/expression.html#mul_expressions * https://dlang.org/spec/expression.html#mul_expressions
*/ */
extern (C++) final class DivExp : BinExp extern (C++) final class DivExp : BinExp
@ -6305,6 +6400,8 @@ extern (C++) final class DivExp : BinExp
} }
/*********************************************************** /***********************************************************
* The modulo operator, `x % y`
*
* https://dlang.org/spec/expression.html#mul_expressions * https://dlang.org/spec/expression.html#mul_expressions
*/ */
extern (C++) final class ModExp : BinExp extern (C++) final class ModExp : BinExp
@ -6321,6 +6418,8 @@ extern (C++) final class ModExp : BinExp
} }
/*********************************************************** /***********************************************************
* The 'power' operator, `x ^^ y`
*
* https://dlang.org/spec/expression.html#pow_expressions * https://dlang.org/spec/expression.html#pow_expressions
*/ */
extern (C++) final class PowExp : BinExp extern (C++) final class PowExp : BinExp
@ -6337,6 +6436,9 @@ extern (C++) final class PowExp : BinExp
} }
/*********************************************************** /***********************************************************
* The 'shift left' operator, `x << y`
*
* https://dlang.org/spec/expression.html#shift_expressions
*/ */
extern (C++) final class ShlExp : BinExp extern (C++) final class ShlExp : BinExp
{ {
@ -6352,6 +6454,9 @@ extern (C++) final class ShlExp : BinExp
} }
/*********************************************************** /***********************************************************
* The 'shift right' operator, `x >> y`
*
* https://dlang.org/spec/expression.html#shift_expressions
*/ */
extern (C++) final class ShrExp : BinExp extern (C++) final class ShrExp : BinExp
{ {
@ -6367,6 +6472,9 @@ extern (C++) final class ShrExp : BinExp
} }
/*********************************************************** /***********************************************************
* The 'unsigned shift right' operator, `x >>> y`
*
* https://dlang.org/spec/expression.html#shift_expressions
*/ */
extern (C++) final class UshrExp : BinExp extern (C++) final class UshrExp : BinExp
{ {
@ -6382,6 +6490,9 @@ extern (C++) final class UshrExp : BinExp
} }
/*********************************************************** /***********************************************************
* The bitwise 'and' operator, `x & y`
*
* https://dlang.org/spec/expression.html#and_expressions
*/ */
extern (C++) final class AndExp : BinExp extern (C++) final class AndExp : BinExp
{ {
@ -6397,6 +6508,9 @@ extern (C++) final class AndExp : BinExp
} }
/*********************************************************** /***********************************************************
* The bitwise 'or' operator, `x | y`
*
* https://dlang.org/spec/expression.html#or_expressions
*/ */
extern (C++) final class OrExp : BinExp extern (C++) final class OrExp : BinExp
{ {
@ -6412,6 +6526,9 @@ extern (C++) final class OrExp : BinExp
} }
/*********************************************************** /***********************************************************
* The bitwise 'xor' operator, `x ^ y`
*
* https://dlang.org/spec/expression.html#xor_expressions
*/ */
extern (C++) final class XorExp : BinExp extern (C++) final class XorExp : BinExp
{ {
@ -6427,6 +6544,8 @@ extern (C++) final class XorExp : BinExp
} }
/*********************************************************** /***********************************************************
* The logical 'and' / 'or' operator, `X && Y` / `X || Y`
*
* https://dlang.org/spec/expression.html#andand_expressions * https://dlang.org/spec/expression.html#andand_expressions
* https://dlang.org/spec/expression.html#oror_expressions * https://dlang.org/spec/expression.html#oror_expressions
*/ */
@ -6445,6 +6564,8 @@ extern (C++) final class LogicalExp : BinExp
} }
/*********************************************************** /***********************************************************
* A comparison operator, `<` `<=` `>` `>=`
*
* `op` is one of: * `op` is one of:
* EXP.lessThan, EXP.lessOrEqual, EXP.greaterThan, EXP.greaterOrEqual * EXP.lessThan, EXP.lessOrEqual, EXP.greaterThan, EXP.greaterOrEqual
* *
@ -6465,6 +6586,11 @@ extern (C++) final class CmpExp : BinExp
} }
/*********************************************************** /***********************************************************
* The `in` operator, `"a" in ["a": 1]`
*
* Note: `x !in y` is rewritten to `!(x in y)` in the parser
*
* https://dlang.org/spec/expression.html#in_expressions
*/ */
extern (C++) final class InExp : BinExp extern (C++) final class InExp : BinExp
{ {
@ -6480,6 +6606,8 @@ extern (C++) final class InExp : BinExp
} }
/*********************************************************** /***********************************************************
* Associative array removal, `aa.remove(arg)`
*
* This deletes the key e1 from the associative array e2 * This deletes the key e1 from the associative array e2
*/ */
extern (C++) final class RemoveExp : BinExp extern (C++) final class RemoveExp : BinExp
@ -6539,7 +6667,7 @@ extern (C++) final class IdentityExp : BinExp
} }
/*********************************************************** /***********************************************************
* `econd ? e1 : e2` * The ternary operator, `econd ? e1 : e2`
* *
* https://dlang.org/spec/expression.html#conditional_expressions * https://dlang.org/spec/expression.html#conditional_expressions
*/ */
@ -6672,6 +6800,18 @@ bool isDefaultInitOp(EXP op) pure nothrow @safe @nogc
} }
/*********************************************************** /***********************************************************
* A special keyword when used as a function's default argument
*
* When possible, special keywords are resolved in the parser, but when
* appearing as a default argument, they result in an expression deriving
* from this base class that is resolved for each function call.
*
* ---
* const x = __LINE__; // resolved in the parser
* void foo(string file = __FILE__, int line = __LINE__); // DefaultInitExp
* ---
*
* https://dlang.org/spec/expression.html#specialkeywords
*/ */
extern (C++) class DefaultInitExp : Expression extern (C++) class DefaultInitExp : Expression
{ {
@ -6687,6 +6827,7 @@ extern (C++) class DefaultInitExp : Expression
} }
/*********************************************************** /***********************************************************
* The `__FILE__` token as a default argument
*/ */
extern (C++) final class FileInitExp : DefaultInitExp extern (C++) final class FileInitExp : DefaultInitExp
{ {
@ -6717,6 +6858,7 @@ extern (C++) final class FileInitExp : DefaultInitExp
} }
/*********************************************************** /***********************************************************
* The `__LINE__` token as a default argument
*/ */
extern (C++) final class LineInitExp : DefaultInitExp extern (C++) final class LineInitExp : DefaultInitExp
{ {
@ -6739,6 +6881,7 @@ extern (C++) final class LineInitExp : DefaultInitExp
} }
/*********************************************************** /***********************************************************
* The `__MODULE__` token as a default argument
*/ */
extern (C++) final class ModuleInitExp : DefaultInitExp extern (C++) final class ModuleInitExp : DefaultInitExp
{ {
@ -6763,6 +6906,7 @@ extern (C++) final class ModuleInitExp : DefaultInitExp
} }
/*********************************************************** /***********************************************************
* The `__FUNCTION__` token as a default argument
*/ */
extern (C++) final class FuncInitExp : DefaultInitExp extern (C++) final class FuncInitExp : DefaultInitExp
{ {
@ -6793,6 +6937,7 @@ extern (C++) final class FuncInitExp : DefaultInitExp
} }
/*********************************************************** /***********************************************************
* The `__PRETTY_FUNCTION__` token as a default argument
*/ */
extern (C++) final class PrettyFuncInitExp : DefaultInitExp extern (C++) final class PrettyFuncInitExp : DefaultInitExp
{ {

View File

@ -79,6 +79,12 @@ class Lexer
bool doDocComment; // collect doc comment information bool doDocComment; // collect doc comment information
bool anyToken; // seen at least one token bool anyToken; // seen at least one token
bool commentToken; // comments are TOK.comment's bool commentToken; // comments are TOK.comment's
version (DMDLIB)
{
bool whitespaceToken; // tokenize whitespaces
}
int inTokenStringConstant; // can be larger than 1 when in nested q{} strings int inTokenStringConstant; // can be larger than 1 when in nested q{} strings
int lastDocLine; // last line of previous doc comment int lastDocLine; // last line of previous doc comment
@ -145,6 +151,31 @@ class Lexer
} }
} }
version (DMDLIB)
{
this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset,
bool doDocComment, bool commentToken, bool whitespaceToken)
{
this(filename, base, begoffset, endoffset, doDocComment, commentToken);
this.whitespaceToken = whitespaceToken;
}
bool empty() const pure @property @nogc @safe
{
return front() == TOK.endOfFile;
}
TOK front() const pure @property @nogc @safe
{
return token.value;
}
void popFront()
{
nextToken();
}
}
/// Returns: a newly allocated `Token`. /// Returns: a newly allocated `Token`.
Token* allocateToken() pure nothrow @safe Token* allocateToken() pure nothrow @safe
{ {
@ -237,20 +268,52 @@ class Lexer
while (*p == ' ') while (*p == ' ')
p++; p++;
LendSkipFourSpaces: LendSkipFourSpaces:
version (DMDLIB)
{
if (whitespaceToken)
{
t.value = TOK.whitespace;
return;
}
}
continue; // skip white space continue; // skip white space
case '\t': case '\t':
case '\v': case '\v':
case '\f': case '\f':
p++; p++;
version (DMDLIB)
{
if (whitespaceToken)
{
t.value = TOK.whitespace;
return;
}
}
continue; // skip white space continue; // skip white space
case '\r': case '\r':
p++; p++;
if (*p != '\n') // if CR stands by itself if (*p != '\n') // if CR stands by itself
endOfLine(); endOfLine();
version (DMDLIB)
{
if (whitespaceToken)
{
t.value = TOK.whitespace;
return;
}
}
continue; // skip white space continue; // skip white space
case '\n': case '\n':
p++; p++;
endOfLine(); endOfLine();
version (DMDLIB)
{
if (whitespaceToken)
{
t.value = TOK.whitespace;
return;
}
}
continue; // skip white space continue; // skip white space
case '0': case '0':
if (!isZeroSecond(p[1])) // if numeric literal does not continue if (!isZeroSecond(p[1])) // if numeric literal does not continue
@ -594,8 +657,12 @@ class Lexer
} }
if (commentToken) if (commentToken)
{ {
p++; version (DMDLIB) {}
endOfLine(); else
{
p++;
endOfLine();
}
t.loc = startLoc; t.loc = startLoc;
t.value = TOK.comment; t.value = TOK.comment;
return; return;

View File

@ -469,10 +469,11 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
* Params: * Params:
* e = the DotVarExp or VarExp * e = the DotVarExp or VarExp
* var = set to the VarExp at the end, or null if doesn't end in VarExp * var = set to the VarExp at the end, or null if doesn't end in VarExp
* eint = set to the IntegerExp at the end, or null if doesn't end in IntegerExp
* offset = accumulation of all the .var offsets encountered * offset = accumulation of all the .var offsets encountered
* Returns: true on error * Returns: true on error
*/ */
static bool getVarAndOffset(Expression e, ref VarDeclaration var, ref uint offset) static bool getVarAndOffset(Expression e, out VarDeclaration var, out IntegerExp eint, ref uint offset)
{ {
if (e.type.size() == SIZE_INVALID) // trigger computation of v.offset if (e.type.size() == SIZE_INVALID) // trigger computation of v.offset
return true; return true;
@ -483,7 +484,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
if (!v || !v.isField() || v.isBitFieldDeclaration()) if (!v || !v.isField() || v.isBitFieldDeclaration())
return false; return false;
if (getVarAndOffset(dve.e1, var, offset)) if (getVarAndOffset(dve.e1, var, eint, offset))
return true; return true;
offset += v.offset; offset += v.offset;
} }
@ -497,12 +498,20 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
var = ve.var.isVarDeclaration(); var = ve.var.isVarDeclaration();
} }
} }
else if (auto ep = e.isPtrExp())
{
if (auto ei = ep.e1.isIntegerExp())
{
eint = ei;
}
}
return false; return false;
} }
uint offset; uint offset;
VarDeclaration var; VarDeclaration var;
if (getVarAndOffset(e.e1, var, offset)) IntegerExp eint;
if (getVarAndOffset(e.e1, var, eint, offset))
{ {
ret = ErrorExp.get(); ret = ErrorExp.get();
return; return;
@ -513,6 +522,11 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
ret.type = e.type; ret.type = e.type;
return; return;
} }
if (eint)
{
ret = new IntegerExp(e.loc, eint.toInteger() + offset, e.type);
return;
}
} }
if (auto ae = e.e1.isIndexExp()) if (auto ae = e.e1.isIndexExp())
{ {
@ -828,6 +842,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
void visitMin(MinExp e) void visitMin(MinExp e)
{ {
//printf("MinExp::optimize(%s)\n", e.toChars());
if (binOptimize(e, result)) if (binOptimize(e, result))
return; return;
if (e.e1.isConst() && e.e2.isConst()) if (e.e1.isConst() && e.e2.isConst())

View File

@ -47,6 +47,7 @@ import dmd.globals;
import dmd.gluelayer; import dmd.gluelayer;
import dmd.id; import dmd.id;
import dmd.identifier; import dmd.identifier;
import dmd.importc;
import dmd.init; import dmd.init;
import dmd.intrange; import dmd.intrange;
import dmd.mtype; import dmd.mtype;
@ -2862,6 +2863,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
rs.exp = inferType(rs.exp, fld.treq.nextOf().nextOf()); rs.exp = inferType(rs.exp, fld.treq.nextOf().nextOf());
rs.exp = rs.exp.expressionSemantic(sc); rs.exp = rs.exp.expressionSemantic(sc);
rs.exp = rs.exp.arrayFuncConv(sc);
// If we're returning by ref, allow the expression to be `shared` // If we're returning by ref, allow the expression to be `shared`
const returnSharedRef = (tf.isref && (fd.inferRetType || tret.isShared())); const returnSharedRef = (tf.isref && (fd.inferRetType || tret.isShared()));
rs.exp.checkSharedAccess(sc, returnSharedRef); rs.exp.checkSharedAccess(sc, returnSharedRef);

View File

@ -246,6 +246,7 @@ enum TOK : ubyte
arrow, // -> arrow, // ->
colonColon, // :: colonColon, // ::
wchar_tLiteral, wchar_tLiteral,
whitespace,
// C only keywords // C only keywords
inline, inline,
@ -851,6 +852,7 @@ extern (C++) struct Token
TOK.wcharLiteral: "wcharv", TOK.wcharLiteral: "wcharv",
TOK.dcharLiteral: "dcharv", TOK.dcharLiteral: "dcharv",
TOK.wchar_tLiteral: "wchar_tv", TOK.wchar_tLiteral: "wchar_tv",
TOK.whitespace: "whitespace",
TOK.hexadecimalString: "xstring", TOK.hexadecimalString: "xstring",

View File

@ -255,6 +255,7 @@ enum class TOK : unsigned char
arrow, // -> arrow, // ->
colonColon, // :: colonColon, // ::
wchar_tLiteral, wchar_tLiteral,
whitespace,
// C only keywords // C only keywords
inline_, inline_,

View File

@ -0,0 +1,15 @@
// https://issues.dlang.org/show_bug.cgi?id=21975
struct Outer(T)
{
Inner!T inner;
alias inner this;
}
struct Inner(T)
{
T t;
}
static assert(is(Outer!int : Inner!int)); // ok
static assert(is(Outer!int : Inner!T, T)); // needs to compile

View File

@ -4,6 +4,30 @@
#include <exception> #include <exception>
#include <cstdarg> #include <cstdarg>
#if _WIN32 // otherwise defined in C header files!
// https://issues.dlang.org/show_bug.cgi?id=18955
namespace std
{
template<typename Char>
struct char_traits
{
};
template<typename Char>
class allocator
{
};
template<typename Char, typename Traits, typename Alloc>
class basic_string
{
};
typedef basic_string<char, char_traits<char>, allocator<char> > string;
}
#else // if POSIX
#include <string>
#endif // _WIN32
#include "cppb.h" #include "cppb.h"
/**************************************/ /**************************************/
@ -317,10 +341,9 @@ size_t getoffset13161a()
/****************************************************/ /****************************************************/
#if __linux__ || __APPLE__ || __FreeBSD__ || __DragonFly__ #if __linux__
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <string>
#if __linux__ #if __linux__
template struct std::allocator<int>; template struct std::allocator<int>;
@ -903,26 +926,6 @@ void A18966::foo() { calledOverloads[i++] = 'A'; }
B18966::B18966() { foo(); } B18966::B18966() { foo(); }
void B18966::foo() { calledOverloads[i++] = 'B'; } void B18966::foo() { calledOverloads[i++] = 'B'; }
#if _WIN32 // otherwise defined in C header files!
// https://issues.dlang.org/show_bug.cgi?id=18955
namespace std
{
template<typename Char>
struct char_traits
{
};
template<typename Char>
class allocator
{
};
template<typename Char, typename Traits, typename Alloc>
class basic_string
{
};
typedef basic_string<char, char_traits<char>, allocator<char> > string;
}
#endif // _WIN32
void callback18955(const std::string& s); void callback18955(const std::string& s);
void test18955() void test18955()

View File

@ -1,4 +1,4 @@
caf14b0f4ebbae4157aac89368d6278332ee2aa1 0316b981e5f2fa1525e893c5d94c59c847a8c386
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the dlang/druntime repository. merge done from the dlang/druntime repository.

View File

@ -1229,7 +1229,10 @@ void __delete(T)(ref T x) @system
else static if (is(T == U*, U)) else static if (is(T == U*, U))
{ {
static if (is(U == struct)) static if (is(U == struct))
_destructRecurse(*x); {
if (x)
_destructRecurse(*x);
}
} }
else static if (is(T : E[], E)) else static if (is(T : E[], E))
{ {
@ -1334,6 +1337,10 @@ unittest
assert(a is null); assert(a is null);
assert(dtorCalled); assert(dtorCalled);
assert(GC.addrOf(cast(void*) a) == null); assert(GC.addrOf(cast(void*) a) == null);
// https://issues.dlang.org/show_bug.cgi?id=22779
A *aptr;
__delete(aptr);
} }
/// Deleting arrays /// Deleting arrays

View File

@ -90,6 +90,13 @@ else version (DragonFlyBSD)
/// ///
enum int FP_ILOGBNAN = int.max; enum int FP_ILOGBNAN = int.max;
} }
else version (Solaris)
{
///
enum int FP_ILOGB0 = -int.max;
///
enum int FP_ILOGBNAN = int.max;
}
else version (CRuntime_Bionic) else version (CRuntime_Bionic)
{ {
/// ///
@ -1380,18 +1387,128 @@ else version (DragonFlyBSD)
} }
else version (Solaris) else version (Solaris)
{ {
pure int __isnanf(float x); enum
pure int __isnan(double x); {
pure int __isnanl(real x); FP_INFINITE = 3,
FP_NAN = 4,
FP_NORMAL = 2,
FP_SUBNORMAL = 1,
FP_ZERO = 0,
}
enum
{
///
FP_FAST_FMA = 0,
///
FP_FAST_FMAF = 0,
///
FP_FAST_FMAL = 0,
}
extern (D)
{
//int fpclassify(real-floating x);
///
pure int fpclassify(float x)
{
return isnan(x) ? FP_NAN : isinf(x) ? FP_INFINITE :
isnormal(x) ? FP_NORMAL : x == 0.0f ? FP_ZERO :
FP_SUBNORMAL;
}
///
pure int fpclassify(double x)
{
return isnan(x) ? FP_NAN : isinf(x) ? FP_INFINITE :
isnormal(x) ? FP_NORMAL : x == 0.0 ? FP_ZERO :
FP_SUBNORMAL;
}
///
pure int fpclassify(real x)
{
return isnan(x) ? FP_NAN : isinf(x) ? FP_INFINITE :
isnormal(x) ? FP_NORMAL : x == 0.0L ? FP_ZERO :
FP_SUBNORMAL;
}
//int isfinite(real-floating x);
///
pure int isfinite(float x) { return !isnan(x) && !isinf(x); }
///
pure int isfinite(double x) { return !isnan(x) && !isinf(x); }
///
pure int isfinite(real x) { return !isnan(x) && !isinf(x); }
//int isinf(real-floating x);
///
pure int isinf(float x) { return x == float.infinity || x == -float.infinity; }
///
pure int isinf(double x) { return x == double.infinity || x == -double.infinity; }
///
pure int isinf(real x) { return x == real.infinity || x == -real.infinity; }
//int isnan(real-floating x); //int isnan(real-floating x);
///
pragma(mangle, "__isnanf") pure int isnan(float x);
/// ///
pragma(mangle, "__isnan") pure int isnan(double x); pure int isnan(float x) { return x != x; }
/// ///
pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl") pure int isnan(double x) { return x != x; }
pure int isnan(real x); ///
pure int isnan(real x) { return x != x; }
//int isnormal(real-floating x);
///
pure int isnormal(float x)
{
import core.math;
return isfinite(x) && fabs(x) >= float.min_normal;
}
///
pure int isnormal(double x)
{
import core.math;
return isfinite(x) && fabs(x) >= double.min_normal;
}
///
pure int isnormal(real x)
{
import core.math;
return isfinite(x) && fabs(x) >= real.min_normal;
}
//int signbit(real-floating x);
///
pure int signbit(float x)
{
version (SPARC_Any)
return cast(int)(*cast(uint*)&x >> 31);
else version (X86_Any)
return cast(int)(*cast(uint*)&x >> 31);
else
static assert(false, "Architecture not supported.");
}
///
pure int signbit(double x)
{
version (SPARC_Any)
return cast(int)(*cast(uint*)&x >> 31);
else version (X86_Any)
return cast(int)((cast(uint*)&x)[1] >> 31);
else
static assert(false, "Architecture not supported.");
}
///
pure int signbit(real x)
{
version (SPARC_Any)
return cast(int)(*cast(uint*)&x >> 31);
else version (X86_Any)
return cast(int)((cast(ushort *)&x)[4] >> 15);
else
static assert(false, "Architecture not supported.");
}
}
} }
else version (CRuntime_Bionic) else version (CRuntime_Bionic)
{ {

View File

@ -983,7 +983,7 @@ else version (NetBSD)
_IONBF = 2, _IONBF = 2,
} }
private extern __gshared FILE[3] __sF; private extern shared FILE[3] __sF;
@property auto __stdin()() { return &__sF[0]; } @property auto __stdin()() { return &__sF[0]; }
@property auto __stdout()() { return &__sF[1]; } @property auto __stdout()() { return &__sF[1]; }
@property auto __stderr()() { return &__sF[2]; } @property auto __stderr()() { return &__sF[2]; }
@ -1006,7 +1006,7 @@ else version (OpenBSD)
_IONBF = 2, _IONBF = 2,
} }
private extern __gshared FILE[3] __sF; private extern shared FILE[3] __sF;
@property auto __stdin()() { return &__sF[0]; } @property auto __stdin()() { return &__sF[0]; }
@property auto __stdout()() { return &__sF[1]; } @property auto __stdout()() { return &__sF[1]; }
@property auto __stderr()() { return &__sF[2]; } @property auto __stderr()() { return &__sF[2]; }
@ -1061,11 +1061,11 @@ else version (Solaris)
private extern shared FILE[_NFILE] __iob; private extern shared FILE[_NFILE] __iob;
/// ///
shared stdin = &__iob[0]; @property auto stdin()() { return &__iob[0]; }
/// ///
shared stdout = &__iob[1]; @property auto stdout()() { return &__iob[1]; }
/// ///
shared stderr = &__iob[2]; @property auto stderr()() { return &__iob[2]; }
} }
else version (CRuntime_Bionic) else version (CRuntime_Bionic)
{ {
@ -1082,11 +1082,11 @@ else version (CRuntime_Bionic)
private extern shared FILE[3] __sF; private extern shared FILE[3] __sF;
/// ///
shared stdin = &__sF[0]; @property auto stdin()() { return &__sF[0]; }
/// ///
shared stdout = &__sF[1]; @property auto stdout()() { return &__sF[1]; }
/// ///
shared stderr = &__sF[2]; @property auto stderr()() { return &__sF[2]; }
} }
else version (CRuntime_Musl) else version (CRuntime_Musl)
{ {

View File

@ -69,7 +69,7 @@ version (GenericBaseException)
{ {
@nogc: @nogc:
/// ///
this() nothrow {} extern(D) this() nothrow {}
/// ///
@weak ~this() nothrow {} // HACK: this should extern, but then we have link errors! @weak ~this() nothrow {} // HACK: this should extern, but then we have link errors!
@ -77,7 +77,7 @@ version (GenericBaseException)
@weak const(char)* what() const nothrow { return "unknown"; } // HACK: this should extern, but then we have link errors! @weak const(char)* what() const nothrow { return "unknown"; } // HACK: this should extern, but then we have link errors!
protected: protected:
this(const(char)*, int = 1) nothrow { this(); } // compat with MS derived classes extern(D) this(const(char)*, int = 1) nothrow { this(); } // compat with MS derived classes
} }
} }
else version (CppRuntime_DigitalMars) else version (CppRuntime_DigitalMars)
@ -87,7 +87,7 @@ else version (CppRuntime_DigitalMars)
{ {
@nogc: @nogc:
/// ///
this() nothrow {} extern(D) this() nothrow {}
//virtual ~this(); //virtual ~this();
void dtor() { } // reserve slot in vtbl[] void dtor() { } // reserve slot in vtbl[]
@ -105,7 +105,7 @@ else version (CppRuntime_Microsoft)
{ {
@nogc: @nogc:
/// ///
this(const(char)* message = "unknown", int = 1) nothrow { msg = message; } extern(D) this(const(char)* message = "unknown", int = 1) nothrow { msg = message; }
/// ///
@weak ~this() nothrow {} @weak ~this() nothrow {}
@ -131,7 +131,7 @@ class bad_exception : exception
{ {
@nogc: @nogc:
/// ///
this(const(char)* message = "bad exception") { super(message); } extern(D) this(const(char)* message = "bad exception") nothrow { super(message); }
version (GenericBaseException) version (GenericBaseException)
{ {

View File

@ -18,10 +18,10 @@ version (CppRuntime_DigitalMars)
import core.stdcpp.exception; import core.stdcpp.exception;
extern (C++, "std"): extern (C++, "std"):
@nogc:
class type_info class type_info
{ {
@nogc:
void* pdata; void* pdata;
public: public:
@ -41,8 +41,9 @@ version (CppRuntime_DigitalMars)
class bad_cast : exception class bad_cast : exception
{ {
this() nothrow { } @nogc:
this(const bad_cast) nothrow { } extern(D) this() nothrow { }
extern(D) this(const bad_cast) nothrow { }
//bad_cast operator=(const bad_cast) nothrow { return this; } //bad_cast operator=(const bad_cast) nothrow { return this; }
//virtual ~this() nothrow; //virtual ~this() nothrow;
override const(char)* what() const nothrow; override const(char)* what() const nothrow;
@ -50,8 +51,9 @@ version (CppRuntime_DigitalMars)
class bad_typeid : exception class bad_typeid : exception
{ {
this() nothrow { } @nogc:
this(const bad_typeid) nothrow { } extern(D) this() nothrow { }
extern(D) this(const bad_typeid) nothrow { }
//bad_typeid operator=(const bad_typeid) nothrow { return this; } //bad_typeid operator=(const bad_typeid) nothrow { return this; }
//virtual ~this() nothrow; //virtual ~this() nothrow;
override const (char)* what() const nothrow; override const (char)* what() const nothrow;
@ -62,7 +64,6 @@ else version (CppRuntime_Microsoft)
import core.stdcpp.exception; import core.stdcpp.exception;
extern (C++, "std"): extern (C++, "std"):
@nogc:
struct __type_info_node struct __type_info_node
{ {
@ -74,6 +75,7 @@ else version (CppRuntime_Microsoft)
class type_info class type_info
{ {
@nogc:
@weak ~this() nothrow {} @weak ~this() nothrow {}
//bool operator==(const type_info rhs) const; //bool operator==(const type_info rhs) const;
//bool operator!=(const type_info rhs) const; //bool operator!=(const type_info rhs) const;
@ -88,13 +90,15 @@ else version (CppRuntime_Microsoft)
class bad_cast : exception class bad_cast : exception
{ {
this(const(char)* msg = "bad cast") @nogc nothrow { super(msg); } @nogc:
extern(D) this(const(char)* msg = "bad cast") nothrow { super(msg); }
//virtual ~this(); //virtual ~this();
} }
class bad_typeid : exception class bad_typeid : exception
{ {
this(const(char)* msg = "bad typeid") @nogc nothrow { super(msg); } @nogc:
extern(D) this(const(char)* msg = "bad typeid") nothrow { super(msg); }
//virtual ~this(); //virtual ~this();
} }
} }
@ -108,10 +112,10 @@ else version (CppRuntime_Gcc)
} }
extern (C++, "std"): extern (C++, "std"):
@nogc:
abstract class type_info abstract class type_info
{ {
@nogc:
@weak ~this() {} @weak ~this() {}
@weak final const(char)* name() const nothrow @weak final const(char)* name() const nothrow
{ {
@ -133,19 +137,21 @@ else version (CppRuntime_Gcc)
protected: protected:
const(char)* _name; const(char)* _name;
this(const(char)* name) { _name = name; } extern(D) this(const(char)* name) { _name = name; }
} }
class bad_cast : exception class bad_cast : exception
{ {
this() nothrow {} @nogc:
extern(D) this() nothrow {}
//~this(); //~this();
@weak override const(char)* what() const nothrow { return "bad cast"; } @weak override const(char)* what() const nothrow { return "bad cast"; }
} }
class bad_typeid : exception class bad_typeid : exception
{ {
this() nothrow {} @nogc:
extern(D) this() nothrow {}
//~this(); //~this();
@weak override const(char)* what() const nothrow { return "bad typeid"; } @weak override const(char)* what() const nothrow { return "bad typeid"; }
} }
@ -155,10 +161,10 @@ else version (CppRuntime_Clang)
import core.stdcpp.exception; import core.stdcpp.exception;
extern (C++, "std"): extern (C++, "std"):
@nogc:
abstract class type_info abstract class type_info
{ {
@nogc:
@weak ~this() {} @weak ~this() {}
@weak final const(char)* name() const nothrow @weak final const(char)* name() const nothrow
{ {
@ -173,19 +179,21 @@ else version (CppRuntime_Clang)
protected: protected:
const(char)* __type_name; const(char)* __type_name;
this(const(char)* __n) { __type_name = __n; } extern(D) this(const(char)* __n) { __type_name = __n; }
} }
class bad_cast : exception class bad_cast : exception
{ {
this() nothrow {} @nogc:
extern(D) this() nothrow {}
//~this(); //~this();
@weak override const(char)* what() const nothrow { return "bad cast"; } @weak override const(char)* what() const nothrow { return "bad cast"; }
} }
class bad_typeid : exception class bad_typeid : exception
{ {
this() nothrow {} @nogc:
extern(D) this() nothrow {}
//~this(); //~this();
@weak override const(char)* what() const nothrow { return "bad typeid"; } @weak override const(char)* what() const nothrow { return "bad typeid"; }
} }

View File

@ -31,7 +31,7 @@ version (FreeBSD)
version = DarwinBSDLocale; version = DarwinBSDLocale;
version (NetBSD) version (NetBSD)
version = DarwinBSDLocale; version = DarwinBSDLocale;
version (DragonflyBSD) version (DragonFlyBSD)
version = DarwinBSDLocale; version = DarwinBSDLocale;
version (CRuntime_Glibc) version (CRuntime_Glibc)

View File

@ -4445,7 +4445,11 @@ void destroy(bool initialize = true, T)(T obj) if (is(T == class))
} }
} }
else else
rt_finalize(cast(void*)obj); {
// Bypass overloaded opCast
auto ptr = (() @trusted => *cast(void**) &obj)();
rt_finalize(ptr);
}
} }
/// ditto /// ditto
@ -4707,6 +4711,18 @@ nothrow unittest
assert(C.dtorCount == 1); assert(C.dtorCount == 1);
} }
// https://issues.dlang.org/show_bug.cgi?id=22832
nothrow unittest
{
static struct A {}
static class B
{
A opCast(T : A)() { return A(); }
}
destroy(B.init);
}
/// ditto /// ditto
void destroy(bool initialize = true, T)(ref T obj) void destroy(bool initialize = true, T)(ref T obj)
if (__traits(isStaticArray, T)) if (__traits(isStaticArray, T))

View File

@ -1,4 +1,4 @@
41aaf8c2636df0e2e3ad39933b321d2b4cd231fa a1f8c4c0700ce4e256f4130ad7883c6ea3890901
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository. merge done from the dlang/phobos repository.

View File

@ -8713,13 +8713,14 @@ public:
/++ /++
Creates a $(LREF SysTime) from a string with the format Creates a $(LREF SysTime) from a string with the format
YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds is the time YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ
zone). Whitespace is stripped from the given string. is the time zone). Whitespace is stripped from the given string.
The exact format is exactly as described in `toISOString` except that The exact format is exactly as described in $(LREF toISOString) except
trailing zeroes are permitted - including having fractional seconds with that trailing zeroes are permitted - including having fractional seconds
all zeroes. However, a decimal point with nothing following it is with all zeroes. The time zone and fractional seconds are optional,
invalid. Also, while $(LREF toISOString) will never generate a string however, a decimal point with nothing following it is invalid.
Also, while $(LREF toISOString) will never generate a string
with more than 7 digits in the fractional seconds (because that's the with more than 7 digits in the fractional seconds (because that's the
limit with hecto-nanosecond precision), it will allow more than 7 digits limit with hecto-nanosecond precision), it will allow more than 7 digits
in order to read strings from other sources that have higher precision in order to read strings from other sources that have higher precision
@ -9024,13 +9025,14 @@ public:
/++ /++
Creates a $(LREF SysTime) from a string with the format Creates a $(LREF SysTime) from a string with the format
YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ
time zone). Whitespace is stripped from the given string. is the time zone). Whitespace is stripped from the given string.
The exact format is exactly as described in `toISOExtString` The exact format is exactly as described in $(LREF toISOExtString)
except that trailing zeroes are permitted - including having fractional except that trailing zeroes are permitted - including having fractional
seconds with all zeroes. However, a decimal point with nothing following seconds with all zeroes. The time zone and fractional seconds are
it is invalid. Also, while $(LREF toISOExtString) will never generate a optional, however, a decimal point with nothing following it is invalid.
Also, while $(LREF toISOExtString) will never generate a
string with more than 7 digits in the fractional seconds (because that's string with more than 7 digits in the fractional seconds (because that's
the limit with hecto-nanosecond precision), it will allow more than 7 the limit with hecto-nanosecond precision), it will allow more than 7
digits in order to read strings from other sources that have higher digits in order to read strings from other sources that have higher
@ -9273,13 +9275,14 @@ public:
/++ /++
Creates a $(LREF SysTime) from a string with the format Creates a $(LREF SysTime) from a string with the format
YYYY-MM-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ
time zone). Whitespace is stripped from the given string. is the time zone). Whitespace is stripped from the given string.
The exact format is exactly as described in `toSimpleString` except The exact format is exactly as described in $(LREF toSimpleString) except
that trailing zeroes are permitted - including having fractional seconds that trailing zeroes are permitted - including having fractional seconds
with all zeroes. However, a decimal point with nothing following it is with all zeroes. The time zone and fractional seconds are optional,
invalid. Also, while $(LREF toSimpleString) will never generate a however, a decimal point with nothing following it is invalid.
Also, while $(LREF toSimpleString) will never generate a
string with more than 7 digits in the fractional seconds (because that's string with more than 7 digits in the fractional seconds (because that's
the limit with hecto-nanosecond precision), it will allow more than 7 the limit with hecto-nanosecond precision), it will allow more than 7
digits in order to read strings from other sources that have higher digits in order to read strings from other sources that have higher

View File

@ -1569,27 +1569,7 @@ private enum bool isSumTypeInstance(T) = is(T == SumType!Args, Args...);
} }
/// True if `T` is a [SumType] or implicitly converts to one, otherwise false. /// True if `T` is a [SumType] or implicitly converts to one, otherwise false.
template isSumType(T) enum bool isSumType(T) = is(T : SumType!Args, Args...);
{
static if (is(T : SumType!Args, Args...))
{
enum isSumType = true;
}
else static if (is(T == struct) && __traits(getAliasThis, T).length > 0)
{
// Workaround for https://issues.dlang.org/show_bug.cgi?id=21975
import std.traits : ReturnType;
alias AliasThisType = ReturnType!((T t) =>
__traits(getMember, t, __traits(getAliasThis, T)[0])
);
enum isSumType = .isSumType!AliasThisType;
}
else
{
enum isSumType = false;
}
}
/// ///
@safe unittest @safe unittest
@ -1610,25 +1590,6 @@ template isSumType(T)
assert(!isSumType!ContainsSumType); assert(!isSumType!ContainsSumType);
} }
@safe unittest
{
static struct AliasThisVar(T)
{
SumType!T payload;
alias payload this;
}
static struct AliasThisFunc(T)
{
SumType!T payload;
ref get() { return payload; }
alias get this;
}
static assert(isSumType!(AliasThisVar!int));
static assert(isSumType!(AliasThisFunc!int));
}
/** /**
* Calls a type-appropriate function with the value held in a [SumType]. * Calls a type-appropriate function with the value held in a [SumType].
* *