diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-03-05 01:47:19 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-03-16 17:29:57 +0100 |
commit | 8da8c7d337123b28fdeb539a283d00732118712e (patch) | |
tree | 74096a23b9e2f64a7e25ec1e8d4d3b1d8934842e /libphobos/libdruntime | |
parent | c5e2c3dd6afcf9b152df72b30e205b0180c0afd5 (diff) |
d: Merge upstream dmd, druntime 4ca4140e58, phobos 454dff14d.
D front-end changes:
- Import dmd v2.103.0-beta.1.
- Using `alias this' for classes has been deprecated.
- The feature `-fpreview=dip25` is now enabled by default.
- The compile-time traits `isVirtualFunction' and
`getVirtualFunctions' have been deprecated.
D runtime changes:
- Import druntime v2.103.0-beta.1.
Phobos changes:
- Import phobos v2.103.0-beta.1.
- Updated unicode grapheme walking updated to conform to Unicode
version 15.
- Improved friendliness of error messages when instantiating
`std.algorithm.iteration.joiner' and
`std.algorithm.sorting.sort' with wrong inputs.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 4ca4140e58.
* dmd/VERSION: Bump version to v2.103.0-beta.1.
* Make-lang.in (D_FRONTEND_OBJS): Add d/errorsink.o.
* d-ctfloat.cc (CTFloat::sprint): Update signature for new front-end
interface.
* d-frontend.cc (getTypeInfoType): Likewise.
* d-lang.cc (d_handle_option): Remove handling of -fpreview=dip25 and
-frevert=dip25.
(d_post_options): Remove enabling of sealed references language
feature when scoped pointers is enabled.
* d-tree.h (create_typeinfo): Update signature.
* decl.cc (DeclVisitor::finish_vtable): Update for new front-end
interface.
(DeclVisitor::visit (VarDeclaration *)): Likewise.
(DeclVisitor::visit (FuncDeclaration *)): Check skipCodegen to see if
front-end explicitly requested not to generate code.
* expr.cc (ExprVisitor::visit (NewExp *)): Update for new front-end
interface.
* lang.opt (fpreview=dip25): Remove.
(frevert=dip25): Remove.
* modules.cc (layout_moduleinfo_fields): Update for new front-end
interface.
(layout_moduleinfo): Likewise.
* runtime.def (NEWCLASS): Remove.
* toir.cc (IRVisitor::visit (IfStatement *)): Don't generate IR for if
statement list when condition is `__ctfe'.
* typeinfo.cc (create_typeinfo): Add generate parameter.
* types.cc (layout_aggregate_members): Update for new front-end
interface.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 4ca4140e58.
* libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add core/factory.d.
* libdruntime/Makefile.in: Regenerate.
* src/MERGE: Merge upstream phobos 454dff14d.
* testsuite/libphobos.hash/test_hash.d: Update test.
* testsuite/libphobos.shared/finalize.d: Update test.
* libdruntime/core/factory.d: New file.
gcc/testsuite/ChangeLog:
* gdc.dg/torture/simd23084.d: New test.
* gdc.dg/torture/simd23085.d: New test.
* gdc.dg/torture/simd23218.d: New test.
Diffstat (limited to 'libphobos/libdruntime')
38 files changed, 559 insertions, 371 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index ac3dd129268..269eebfc483 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -09faa4eacd4fb147107e94eeebf56b3a73fdcc05 +4ca4140e584c055a8a9bc727e56a97ebcecd61e0 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am index 18154dedd9b..8225ba4a028 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -169,7 +169,7 @@ DRUNTIME_CSOURCES = core/stdc/errno_.c DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ core/builtins.d core/checkedint.d core/cpuid.d core/demangle.d \ - core/exception.d core/gc/config.d core/gc/gcinterface.d \ + core/exception.d core/factory.d core/gc/config.d core/gc/gcinterface.d \ core/gc/registry.d core/int128.d core/internal/abort.d \ core/internal/array/appending.d core/internal/array/arrayassign.d \ core/internal/array/capacity.d core/internal/array/casting.d \ diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index 3f04496bd7b..797d6435a7c 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -189,9 +189,10 @@ am__DEPENDENCIES_1 = am__dirstamp = $(am__leading_dot)dirstamp am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \ core/builtins.lo core/checkedint.lo core/cpuid.lo \ - core/demangle.lo core/exception.lo core/gc/config.lo \ - core/gc/gcinterface.lo core/gc/registry.lo core/int128.lo \ - core/internal/abort.lo core/internal/array/appending.lo \ + core/demangle.lo core/exception.lo core/factory.lo \ + core/gc/config.lo core/gc/gcinterface.lo core/gc/registry.lo \ + core/int128.lo core/internal/abort.lo \ + core/internal/array/appending.lo \ core/internal/array/arrayassign.lo \ core/internal/array/capacity.lo core/internal/array/casting.lo \ core/internal/array/comparison.lo \ @@ -838,7 +839,7 @@ libgdruntime_convenience_la_LINK = $(libgdruntime_la_LINK) DRUNTIME_CSOURCES = core/stdc/errno_.c DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \ core/builtins.d core/checkedint.d core/cpuid.d core/demangle.d \ - core/exception.d core/gc/config.d core/gc/gcinterface.d \ + core/exception.d core/factory.d core/gc/config.d core/gc/gcinterface.d \ core/gc/registry.d core/int128.d core/internal/abort.d \ core/internal/array/appending.d core/internal/array/arrayassign.d \ core/internal/array/capacity.d core/internal/array/casting.d \ @@ -1188,6 +1189,7 @@ core/checkedint.lo: core/$(am__dirstamp) core/cpuid.lo: core/$(am__dirstamp) core/demangle.lo: core/$(am__dirstamp) core/exception.lo: core/$(am__dirstamp) +core/factory.lo: core/$(am__dirstamp) core/gc/$(am__dirstamp): @$(MKDIR_P) core/gc @: > core/gc/$(am__dirstamp) diff --git a/libphobos/libdruntime/core/attribute.d b/libphobos/libdruntime/core/attribute.d index 8a1dc8add89..c2a7c334eb7 100644 --- a/libphobos/libdruntime/core/attribute.d +++ b/libphobos/libdruntime/core/attribute.d @@ -236,9 +236,9 @@ version (UdaGNUAbiTag) struct gnuAbiTag { string[] tags; - this(string[] tags...) + this(string[] tags...) @safe pure nothrow { - this.tags = tags; + this.tags = tags.dup; } } diff --git a/libphobos/libdruntime/core/cpuid.d b/libphobos/libdruntime/core/cpuid.d index 1c2ac067704..b79bd1df9c4 100644 --- a/libphobos/libdruntime/core/cpuid.d +++ b/libphobos/libdruntime/core/cpuid.d @@ -1080,7 +1080,7 @@ void cpuidSparc() } */ -shared static this() +pragma(crt_constructor) void cpuid_initialization() { auto cf = getCpuFeatures(); diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d index fe273319f21..3fcb26657c8 100644 --- a/libphobos/libdruntime/core/demangle.d +++ b/libphobos/libdruntime/core/demangle.d @@ -801,7 +801,7 @@ pure @safe: TypeTuple: B Number Arguments */ - char[] parseType( char[] name = null ) return scope + char[] parseType() return scope { static immutable string[23] primitives = [ "char", // a @@ -830,7 +830,7 @@ pure @safe: ]; static if (__traits(hasMember, Hooks, "parseType")) - if (auto n = hooks.parseType(this, name)) + if (auto n = hooks.parseType(this, null)) return n; debug(trace) printf( "parseType+\n" ); @@ -861,27 +861,24 @@ pure @safe: switch ( t ) { case 'Q': // Type back reference - return parseBackrefType( () => parseType( name ) ); + return parseBackrefType(() => parseType()); case 'O': // Shared (O Type) popFront(); put( "shared(" ); parseType(); put( ')' ); - pad( name ); return dst[beg .. len]; case 'x': // Const (x Type) popFront(); put( "const(" ); parseType(); put( ')' ); - pad( name ); return dst[beg .. len]; case 'y': // Immutable (y Type) popFront(); put( "immutable(" ); parseType(); put( ')' ); - pad( name ); return dst[beg .. len]; case 'N': popFront(); @@ -912,7 +909,6 @@ pure @safe: popFront(); parseType(); put( "[]" ); - pad( name ); return dst[beg .. len]; case 'G': // TypeStaticArray (G Number Type) popFront(); @@ -921,7 +917,6 @@ pure @safe: put( '[' ); put( num ); put( ']' ); - pad( name ); return dst[beg .. len]; case 'H': // TypeAssocArray (H Type Type) popFront(); @@ -931,31 +926,28 @@ pure @safe: put( '[' ); put( tx ); put( ']' ); - pad( name ); return dst[beg .. len]; case 'P': // TypePointer (P Type) popFront(); parseType(); put( '*' ); - pad( name ); return dst[beg .. len]; case 'F': case 'U': case 'W': case 'V': case 'R': // TypeFunction - return parseTypeFunction( name ); + return parseTypeFunction(); case 'C': // TypeClass (C LName) case 'S': // TypeStruct (S LName) case 'E': // TypeEnum (E LName) case 'T': // TypeTypedef (T LName) popFront(); parseQualifiedName(); - pad( name ); return dst[beg .. len]; case 'D': // TypeDelegate (D TypeFunction) popFront(); auto modifiers = parseModifier(); if ( front == 'Q' ) - parseBackrefType( () => parseTypeFunction( name, IsDelegate.yes ) ); + parseBackrefType(() => parseTypeFunction(IsDelegate.yes)); else - parseTypeFunction( name, IsDelegate.yes ); + parseTypeFunction(IsDelegate.yes); if (modifiers) { // write modifiers behind the function arguments @@ -989,7 +981,6 @@ pure @safe: { popFront(); put( primitives[cast(size_t)(t - 'a')] ); - pad( name ); return dst[beg .. len]; } else if (t == 'z') @@ -1000,12 +991,10 @@ pure @safe: case 'i': popFront(); put( "cent" ); - pad( name ); return dst[beg .. len]; case 'k': popFront(); put( "ucent" ); - pad( name ); return dst[beg .. len]; default: error(); @@ -1358,7 +1347,7 @@ pure @safe: TypeFunction: CallConvention FuncAttrs Arguments ArgClose Type */ - char[] parseTypeFunction( char[] name = null, IsDelegate isdg = IsDelegate.no ) return scope + char[] parseTypeFunction(IsDelegate isdg = IsDelegate.no) return scope { debug(trace) printf( "parseTypeFunction+\n" ); debug(trace) scope(success) printf( "parseTypeFunction-\n" ); @@ -1383,18 +1372,8 @@ pure @safe: auto retbeg = len; parseType(); put( ' ' ); - // append name/delegate/function - if ( name.length ) - { - if ( !contains( dst[0 .. len], name ) ) - put( name ); - else if ( shift( name ).ptr != name.ptr ) - { - argbeg -= name.length; - retbeg -= name.length; - } - } - else if ( IsDelegate.yes == isdg ) + // append delegate/function + if (IsDelegate.yes == isdg) put( "delegate" ); else put( "function" ); @@ -2933,7 +2912,7 @@ CXX_DEMANGLER getCXXDemangler() nothrow @trusted version (linux) import core.sys.linux.dlfcn : RTLD_DEFAULT; version (NetBSD) import core.sys.netbsd.dlfcn : RTLD_DEFAULT; version (OpenBSD) import core.sys.openbsd.dlfcn : RTLD_DEFAULT; - version (OSX) import core.sys.darwin.dlfcn : RTLD_DEFAULT; + version (Darwin) import core.sys.darwin.dlfcn : RTLD_DEFAULT; version (Solaris) import core.sys.solaris.dlfcn : RTLD_DEFAULT; if (auto found = cast(CXX_DEMANGLER) dlsym(RTLD_DEFAULT, "__cxa_demangle")) diff --git a/libphobos/libdruntime/core/factory.d b/libphobos/libdruntime/core/factory.d new file mode 100644 index 00000000000..f45a04ea91f --- /dev/null +++ b/libphobos/libdruntime/core/factory.d @@ -0,0 +1,68 @@ +/* Create classes from their modules and names. + * + * Copyright: Copyright (C) D Language Foundation 2023 + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Authors: Walter Bright, Steven Schveighoffer + * Source: $(DRUNTIMESRC core/_factory.d) + */ + +module core.factory; + +/** + * Create instance of class specified by the module symbol and a string + * representing the name of the class. + * The class must either have no constructors or have + * a default constructor. + * Params: + * mod = symbol representing the module that the class is in + * classname = string representing the name of the class + * Returns: + * null if failed + * Example: + * --- + * module foo.bar; + * + * class C + * { + * this() { x = 10; } + * int x; + * } + * + * void main() + * { + * auto c = cast(C)factory!(foo.bar)("C"); + * assert(c !is null && c.x == 10); + * } + * --- + */ +Object factory(alias mod)(string classname) +{ + foreach(cl; _getModuleClasses!mod) + { + if (cl.stringof == classname) + return cl.classinfo.create(); + } + return null; +} + +@system unittest +{ + Object valid_obj = factory!object("Object"); + Object invalid_obj = factory!object("__this_class_doesnt_exist__"); + + assert(valid_obj !is null); + assert(invalid_obj is null); +} + +/************************************** + * Retrieve as a tuple all the types of the top level classes in the module mod. + */ +private template _getModuleClasses(alias mod) { + alias result = _AliasSeq!(); + static foreach(m; __traits(allMembers, mod)) + static if(is(__traits(getMember, mod, m) == class)) + result = _AliasSeq!(result, __traits(getMember, mod, m)); + alias _getModuleClasses = result; +} + +private template _AliasSeq(TList...) { alias _AliasSeq = TList; } diff --git a/libphobos/libdruntime/core/int128.d b/libphobos/libdruntime/core/int128.d index 46eb9b27556..20fa7dea170 100644 --- a/libphobos/libdruntime/core/int128.d +++ b/libphobos/libdruntime/core/int128.d @@ -18,8 +18,23 @@ alias I = long; alias U = ulong; enum Ubits = uint(U.sizeof * 8); -version (X86_64) private enum Cent_alignment = 16; -else private enum Cent_alignment = (size_t.sizeof * 2); +version (DigitalMars) +{ + /* The alignment should follow target.stackAlign(), + * which is `isXmmSupported() ? 16 : (is64bit ? 8 : 4) + */ + version (D_SIMD) + private enum Cent_alignment = 16; + else version (X86_64) + private enum Cent_alignment = 8; + else + private enum Cent_alignment = 4; +} +else +{ + version (X86_64) private enum Cent_alignment = 16; + else private enum Cent_alignment = (size_t.sizeof * 2); +} align(Cent_alignment) struct Cent { diff --git a/libphobos/libdruntime/core/internal/array/appending.d b/libphobos/libdruntime/core/internal/array/appending.d index 616d27cfe83..b609167eefe 100644 --- a/libphobos/libdruntime/core/internal/array/appending.d +++ b/libphobos/libdruntime/core/internal/array/appending.d @@ -17,8 +17,6 @@ private enum isCopyingNothrow(T) = __traits(compiles, (ref T rhs) nothrow { T lh /// Implementation of `_d_arrayappendcTX` and `_d_arrayappendcTXTrace` template _d_arrayappendcTXImpl(Tarr : T[], T) { - import core.internal.array.utils : _d_HookTraceImpl; - private enum errorMessage = "Cannot append to array if compiling without support for runtime type information!"; /** @@ -51,17 +49,22 @@ template _d_arrayappendcTXImpl(Tarr : T[], T) return px; } else - assert(0, "Cannot append arrays if compiling without support for runtime type information!"); + assert(0, errorMessage); } - /** - * TraceGC wrapper around $(REF _d_arrayappendcTX, rt,array,appending,_d_arrayappendcTXImpl). - * Bugs: - * This function template was ported from a much older runtime hook that bypassed safety, - * purity, and throwabilty checks. To prevent breaking existing code, this function template - * is temporarily declared `@trusted pure` until the implementation can be brought up to modern D expectations. - */ - alias _d_arrayappendcTXTrace = _d_HookTraceImpl!(Tarr, _d_arrayappendcTX, errorMessage); + version (D_ProfileGC) + { + import core.internal.array.utils : _d_HookTraceImpl; + + /** + * TraceGC wrapper around $(REF _d_arrayappendcTX, rt,array,appending,_d_arrayappendcTXImpl). + * Bugs: + * This function template was ported from a much older runtime hook that bypassed safety, + * purity, and throwabilty checks. To prevent breaking existing code, this function template + * is temporarily declared `@trusted pure` until the implementation can be brought up to modern D expectations. + */ + alias _d_arrayappendcTXTrace = _d_HookTraceImpl!(Tarr, _d_arrayappendcTX, errorMessage); + } } /// Implementation of `_d_arrayappendT` @@ -71,7 +74,6 @@ ref Tarr _d_arrayappendT(Tarr : T[], T)(return ref scope Tarr x, scope Tarr y) @ import core.stdc.string : memcpy; import core.internal.traits : hasElaborateCopyConstructor, Unqual; - import core.lifetime : copyEmplace; enum hasPostblit = __traits(hasPostblit, T); auto length = x.length; @@ -81,6 +83,8 @@ ref Tarr _d_arrayappendT(Tarr : T[], T)(return ref scope Tarr x, scope Tarr y) @ // Only call `copyEmplace` if `T` has a copy ctor and no postblit. static if (hasElaborateCopyConstructor!T && !hasPostblit) { + import core.lifetime : copyEmplace; + foreach (i, ref elem; y) copyEmplace(elem, x[length + i]); } @@ -107,20 +111,23 @@ ref Tarr _d_arrayappendT(Tarr : T[], T)(return ref scope Tarr x, scope Tarr y) @ return x; } -/** - * TraceGC wrapper around $(REF _d_arrayappendT, core,internal,array,appending). - */ -ref Tarr _d_arrayappendTTrace(Tarr : T[], T)(string file, int line, string funcname, return ref scope Tarr x, scope Tarr y) @trusted +version (D_ProfileGC) { - version (D_TypeInfo) + /** + * TraceGC wrapper around $(REF _d_arrayappendT, core,internal,array,appending). + */ + ref Tarr _d_arrayappendTTrace(Tarr : T[], T)(string file, int line, string funcname, return ref scope Tarr x, scope Tarr y) @trusted { - import core.internal.array.utils: TraceHook, gcStatsPure, accumulatePure; - mixin(TraceHook!(Tarr.stringof, "_d_arrayappendT")); + version (D_TypeInfo) + { + import core.internal.array.utils: TraceHook, gcStatsPure, accumulatePure; + mixin(TraceHook!(Tarr.stringof, "_d_arrayappendT")); - return _d_arrayappendT(x, y); + return _d_arrayappendT(x, y); + } + else + assert(0, "Cannot append to array if compiling without support for runtime type information!"); } - else - assert(0, "Cannot append to array if compiling without support for runtime type information!"); } @safe unittest diff --git a/libphobos/libdruntime/core/internal/array/capacity.d b/libphobos/libdruntime/core/internal/array/capacity.d index 9440428ebd7..254e9501f63 100644 --- a/libphobos/libdruntime/core/internal/array/capacity.d +++ b/libphobos/libdruntime/core/internal/array/capacity.d @@ -22,8 +22,6 @@ private extern (C) void[] _d_arraysetlengthiT(const TypeInfo ti, size_t newlengt /// Implementation of `_d_arraysetlengthT` and `_d_arraysetlengthTTrace` template _d_arraysetlengthTImpl(Tarr : T[], T) { - import core.internal.array.utils : _d_HookTraceImpl; - private enum errorMessage = "Cannot resize arrays if compiling without support for runtime type information!"; /** @@ -54,14 +52,19 @@ template _d_arraysetlengthTImpl(Tarr : T[], T) assert(0, errorMessage); } - /** - * TraceGC wrapper around $(REF _d_arraysetlengthT, core,internal,array,core.internal.array.capacity). - * Bugs: - * This function template was ported from a much older runtime hook that bypassed safety, - * purity, and throwabilty checks. To prevent breaking existing code, this function template - * is temporarily declared `@trusted pure nothrow` until the implementation can be brought up to modern D expectations. - */ - alias _d_arraysetlengthTTrace = _d_HookTraceImpl!(Tarr, _d_arraysetlengthT, errorMessage); + version (D_ProfileGC) + { + import core.internal.array.utils : _d_HookTraceImpl; + + /** + * TraceGC wrapper around $(REF _d_arraysetlengthT, core,internal,array,core.internal.array.capacity). + * Bugs: + * This function template was ported from a much older runtime hook that bypassed safety, + * purity, and throwabilty checks. To prevent breaking existing code, this function template + * is temporarily declared `@trusted pure nothrow` until the implementation can be brought up to modern D expectations. + */ + alias _d_arraysetlengthTTrace = _d_HookTraceImpl!(Tarr, _d_arraysetlengthT, errorMessage); + } } @safe unittest diff --git a/libphobos/libdruntime/core/internal/array/concatenation.d b/libphobos/libdruntime/core/internal/array/concatenation.d index 955e3814769..99f33da7683 100644 --- a/libphobos/libdruntime/core/internal/array/concatenation.d +++ b/libphobos/libdruntime/core/internal/array/concatenation.d @@ -14,8 +14,6 @@ private extern (C) void[] _d_arraycatnTX(const TypeInfo ti, scope byte[][] arrs) /// Implementation of `_d_arraycatnTX` and `_d_arraycatnTXTrace` template _d_arraycatnTXImpl(Tarr : ResultArrT[], ResultArrT : T[], T) { - import core.internal.array.utils : _d_HookTraceImpl; - private enum errorMessage = "Cannot concatenate arrays if compiling without support for runtime type information!"; /** @@ -45,14 +43,19 @@ template _d_arraycatnTXImpl(Tarr : ResultArrT[], ResultArrT : T[], T) assert(0, errorMessage); } - /** - * TraceGC wrapper around $(REF _d_arraycatnTX, core,internal,array,concat). - * Bugs: - * This function template was ported from a much older runtime hook that bypassed safety, - * purity, and throwabilty checks. To prevent breaking existing code, this function template - * is temporarily declared `@trusted pure nothrow` until the implementation can be brought up to modern D expectations. - */ - alias _d_arraycatnTXTrace = _d_HookTraceImpl!(ResultArrT, _d_arraycatnTX, errorMessage); + version (D_ProfileGC) + { + import core.internal.array.utils : _d_HookTraceImpl; + + /** + * TraceGC wrapper around $(REF _d_arraycatnTX, core,internal,array,concat). + * Bugs: + * This function template was ported from a much older runtime hook that bypassed safety, + * purity, and throwabilty checks. To prevent breaking existing code, this function template + * is temporarily declared `@trusted pure nothrow` until the implementation can be brought up to modern D expectations. + */ + alias _d_arraycatnTXTrace = _d_HookTraceImpl!(ResultArrT, _d_arraycatnTX, errorMessage); + } } @safe unittest diff --git a/libphobos/libdruntime/core/internal/array/duplication.d b/libphobos/libdruntime/core/internal/array/duplication.d index 41dfab6f349..21894c29d38 100644 --- a/libphobos/libdruntime/core/internal/array/duplication.d +++ b/libphobos/libdruntime/core/internal/array/duplication.d @@ -15,10 +15,17 @@ U[] _dup(T, U)(scope T[] a) pure nothrow @trusted if (__traits(isPOD, T)) if (__ctfe) return _dupCtfe!(T, U)(a); - import core.stdc.string : memcpy; - auto arr = _d_newarrayU(typeid(T[]), a.length); - memcpy(arr.ptr, cast(const(void)*) a.ptr, T.sizeof * a.length); - return *cast(U[]*) &arr; + version (D_BetterC) + { + return _dupCtfe!(T, U)(a); + } + else + { + import core.stdc.string : memcpy; + auto arr = _d_newarrayU(typeid(T[]), a.length); + memcpy(arr.ptr, cast(const(void)*) a.ptr, T.sizeof * a.length); + return *cast(U[]*) &arr; + } } U[] _dupCtfe(T, U)(scope T[] a) @@ -41,25 +48,32 @@ U[] _dup(T, U)(T[] a) if (!__traits(isPOD, T)) if (__ctfe) return _dupCtfe!(T, U)(a); - import core.lifetime: copyEmplace; - U[] res = () @trusted { - auto arr = cast(U*) _d_newarrayU(typeid(T[]), a.length); - size_t i; - scope (failure) - { - import core.internal.lifetime: emplaceInitializer; - // Initialize all remaining elements to not destruct garbage - foreach (j; i .. a.length) - emplaceInitializer(cast() arr[j]); - } - for (; i < a.length; i++) - { - copyEmplace(a.ptr[i], arr[i]); - } - return cast(U[])(arr[0..a.length]); - } (); + version (D_BetterC) + { + return _dupCtfe!(T, U)(a); + } + else + { + import core.lifetime: copyEmplace; + U[] res = () @trusted { + auto arr = cast(U*) _d_newarrayU(typeid(T[]), a.length); + size_t i; + scope (failure) + { + import core.internal.lifetime: emplaceInitializer; + // Initialize all remaining elements to not destruct garbage + foreach (j; i .. a.length) + emplaceInitializer(cast() arr[j]); + } + for (; i < a.length; i++) + { + copyEmplace(a.ptr[i], arr[i]); + } + return cast(U[])(arr[0..a.length]); + } (); - return res; + return res; + } } // https://issues.dlang.org/show_bug.cgi?id=22107 diff --git a/libphobos/libdruntime/core/internal/array/utils.d b/libphobos/libdruntime/core/internal/array/utils.d index 41aa57faf0c..a16005e714d 100644 --- a/libphobos/libdruntime/core/internal/array/utils.d +++ b/libphobos/libdruntime/core/internal/array/utils.d @@ -34,76 +34,79 @@ ulong accumulatePure(string file, int line, string funcname, string name, ulong return func(file, line, funcname, name, size); } -/** - * TraceGC wrapper generator around the runtime hook `Hook`. - * Params: - * Type = The type of hook to report to accumulate - * Hook = The name hook to wrap - */ -template TraceHook(string Type, string Hook) +version (D_ProfileGC) { - const char[] TraceHook = q{ - import core.internal.array.utils : gcStatsPure, accumulatePure; - - pragma(inline, false); - string name = } ~ "`" ~ Type ~ "`;" ~ q{ - - // FIXME: use rt.tracegc.accumulator when it is accessable in the future. - version (tracegc) - } ~ "{\n" ~ q{ - import core.stdc.stdio; - - printf("%sTrace file = '%.*s' line = %d function = '%.*s' type = %.*s\n", - } ~ "\"" ~ Hook ~ "\".ptr," ~ q{ - file.length, file.ptr, - line, - funcname.length, funcname.ptr, - name.length, name.ptr - ); - } ~ "}\n" ~ q{ - ulong currentlyAllocated = gcStatsPure().allocatedInCurrentThread; - - scope(exit) - { - ulong size = gcStatsPure().allocatedInCurrentThread - currentlyAllocated; - if (size > 0) - if (!accumulatePure(file, line, funcname, name, size)) { - // This 'if' and 'assert' is needed to force the compiler to not remove the call to - // `accumulatePure`. It really want to do that while optimizing as the function is - // `pure` and it does not influence the result of this hook. - - // `accumulatePure` returns the value of `size`, which can never be zero due to the - // previous 'if'. So this assert will never be triggered. - assert(0); - } - } - }; -} + /** + * TraceGC wrapper generator around the runtime hook `Hook`. + * Params: + * Type = The type of hook to report to accumulate + * Hook = The name hook to wrap + */ + template TraceHook(string Type, string Hook) + { + const char[] TraceHook = q{ + import core.internal.array.utils : gcStatsPure, accumulatePure; + + pragma(inline, false); + string name = } ~ "`" ~ Type ~ "`;" ~ q{ + + // FIXME: use rt.tracegc.accumulator when it is accessable in the future. + version (tracegc) + } ~ "{\n" ~ q{ + import core.stdc.stdio; + + printf("%sTrace file = '%.*s' line = %d function = '%.*s' type = %.*s\n", + } ~ "\"" ~ Hook ~ "\".ptr," ~ q{ + file.length, file.ptr, + line, + funcname.length, funcname.ptr, + name.length, name.ptr + ); + } ~ "}\n" ~ q{ + ulong currentlyAllocated = gcStatsPure().allocatedInCurrentThread; + + scope(exit) + { + ulong size = gcStatsPure().allocatedInCurrentThread - currentlyAllocated; + if (size > 0) + if (!accumulatePure(file, line, funcname, name, size)) { + // This 'if' and 'assert' is needed to force the compiler to not remove the call to + // `accumulatePure`. It really want to do that while optimizing as the function is + // `pure` and it does not influence the result of this hook. + + // `accumulatePure` returns the value of `size`, which can never be zero due to the + // previous 'if'. So this assert will never be triggered. + assert(0); + } + } + }; + } -/** - * TraceGC wrapper around runtime hook `Hook`. - * Params: - * T = Type of hook to report to accumulate - * Hook = The hook to wrap - * errorMessage = The error message incase `version != D_TypeInfo` - * file = File that called `_d_HookTraceImpl` - * line = Line inside of `file` that called `_d_HookTraceImpl` - * funcname = Function that called `_d_HookTraceImpl` - * parameters = Parameters that will be used to call `Hook` - * Bugs: - * This function template needs be between the compiler and a much older runtime hook that bypassed safety, - * purity, and throwabilty checks. To prevent breaking existing code, this function template - * is temporarily declared `@trusted pure` until the implementation can be brought up to modern D expectations. -*/ -auto _d_HookTraceImpl(T, alias Hook, string errorMessage)(string file, int line, string funcname, Parameters!Hook parameters) @trusted pure -{ - version (D_TypeInfo) + /** + * TraceGC wrapper around runtime hook `Hook`. + * Params: + * T = Type of hook to report to accumulate + * Hook = The hook to wrap + * errorMessage = The error message incase `version != D_TypeInfo` + * file = File that called `_d_HookTraceImpl` + * line = Line inside of `file` that called `_d_HookTraceImpl` + * funcname = Function that called `_d_HookTraceImpl` + * parameters = Parameters that will be used to call `Hook` + * Bugs: + * This function template needs be between the compiler and a much older runtime hook that bypassed safety, + * purity, and throwabilty checks. To prevent breaking existing code, this function template + * is temporarily declared `@trusted pure` until the implementation can be brought up to modern D expectations. + */ + auto _d_HookTraceImpl(T, alias Hook, string errorMessage)(string file, int line, string funcname, Parameters!Hook parameters) @trusted pure { - mixin(TraceHook!(T.stringof, __traits(identifier, Hook))); - return Hook(parameters); + version (D_TypeInfo) + { + mixin(TraceHook!(T.stringof, __traits(identifier, Hook))); + return Hook(parameters); + } + else + assert(0, errorMessage); } - else - assert(0, errorMessage); } /** diff --git a/libphobos/libdruntime/core/internal/traits.d b/libphobos/libdruntime/core/internal/traits.d index 0b4890cbfa9..966839f176a 100644 --- a/libphobos/libdruntime/core/internal/traits.d +++ b/libphobos/libdruntime/core/internal/traits.d @@ -654,7 +654,7 @@ if (func.length == 1 /*&& isCallable!func*/) int test(int); int test() @property; } - alias ov = __traits(getVirtualFunctions, Overloads, "test"); + alias ov = __traits(getVirtualMethods, Overloads, "test"); alias F_ov0 = FunctionTypeOf!(ov[0]); alias F_ov1 = FunctionTypeOf!(ov[1]); alias F_ov2 = FunctionTypeOf!(ov[2]); diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d index 371308def79..5e339c041d1 100644 --- a/libphobos/libdruntime/core/lifetime.d +++ b/libphobos/libdruntime/core/lifetime.d @@ -2385,21 +2385,24 @@ template _d_delstructImpl(T) } } - import core.internal.array.utils : _d_HookTraceImpl; + version (D_ProfileGC) + { + import core.internal.array.utils : _d_HookTraceImpl; - private enum errorMessage = "Cannot delete struct if compiling without support for runtime type information!"; + private enum errorMessage = "Cannot delete struct if compiling without support for runtime type information!"; - /** - * TraceGC wrapper around $(REF _d_delstruct, core,lifetime,_d_delstructImpl). - * - * Bugs: - * This function template was ported from a much older runtime hook that - * bypassed safety, purity, and throwabilty checks. To prevent breaking - * existing code, this function template is temporarily declared - * `@trusted` until the implementation can be brought up to modern D - * expectations. - */ - alias _d_delstructTrace = _d_HookTraceImpl!(T, _d_delstruct, errorMessage); + /** + * TraceGC wrapper around $(REF _d_delstruct, core,lifetime,_d_delstructImpl). + * + * Bugs: + * This function template was ported from a much older runtime hook that + * bypassed safety, purity, and throwabilty checks. To prevent breaking + * existing code, this function template is temporarily declared + * `@trusted` until the implementation can be brought up to modern D + * expectations. + */ + alias _d_delstructTrace = _d_HookTraceImpl!(T, _d_delstruct, errorMessage); + } } @system pure nothrow unittest @@ -2709,3 +2712,108 @@ T _d_newThrowable(T)() @trusted assert(exc.refcount() == 1); assert(e.refcount() == 1); } + +/** + * Create a new class instance. + * Allocates memory and sets fields to their initial value, but does not call a + * constructor. + * --- + * new C() // _d_newclass!(C)() + * --- + * Returns: newly created object + */ +T _d_newclassT(T)() @trusted +if (is(T == class)) +{ + import core.internal.traits : hasIndirections; + import core.exception : onOutOfMemoryError; + import core.memory : GC, pureMalloc; + + alias BlkAttr = GC.BlkAttr; + + auto init = __traits(initSymbol, T); + void* p; + + static if (__traits(getLinkage, T) == "Windows") + { + p = pureMalloc(init.length); + if (!p) + onOutOfMemoryError(); + } + else + { + BlkAttr attr = BlkAttr.NONE; + + /* `extern(C++)`` classes don't have a classinfo pointer in their vtable, + * so the GC can't finalize them. + */ + static if (__traits(hasMember, T, "__dtor") && __traits(getLinkage, T) != "C++") + attr |= BlkAttr.FINALIZE; + static if (!hasIndirections!T) + attr |= BlkAttr.NO_SCAN; + + p = GC.malloc(init.length, attr, typeid(T)); + debug(PRINTF) printf(" p = %p\n", p); + } + + debug(PRINTF) + { + printf("p = %p\n", p); + printf("init.ptr = %p, len = %llu\n", init.ptr, cast(ulong)init.length); + printf("vptr = %p\n", *cast(void**) init); + printf("vtbl[0] = %p\n", (*cast(void***) init)[0]); + printf("vtbl[1] = %p\n", (*cast(void***) init)[1]); + printf("init[0] = %x\n", (cast(uint*) init)[0]); + printf("init[1] = %x\n", (cast(uint*) init)[1]); + printf("init[2] = %x\n", (cast(uint*) init)[2]); + printf("init[3] = %x\n", (cast(uint*) init)[3]); + printf("init[4] = %x\n", (cast(uint*) init)[4]); + } + + // initialize it + p[0 .. init.length] = init[]; + + debug(PRINTF) printf("initialization done\n"); + return cast(T) p; +} + +// Test allocation +@safe unittest +{ + class C { } + C c = _d_newclassT!C(); + + assert(c !is null); +} + +// Test initializers +@safe unittest +{ + { + class C { int x, y; } + C c = _d_newclassT!C(); + + assert(c.x == 0); + assert(c.y == 0); + } + { + class C { int x = 2, y = 3; } + C c = _d_newclassT!C(); + + assert(c.x == 2); + assert(c.y == 3); + } +} + +T _d_newclassTTrace(T)(string file, int line, string funcname) @trusted +{ + version (D_TypeInfo) + { + import core.internal.array.utils: TraceHook, gcStatsPure, accumulatePure; + mixin(TraceHook!(T.stringof, "_d_newclassT")); + + return _d_newclassT!T(); + } + else + assert(0, "Cannot create new class if compiling without support for runtime type information!"); +} diff --git a/libphobos/libdruntime/core/memory.d b/libphobos/libdruntime/core/memory.d index 7d1356af0be..96c2af478d3 100644 --- a/libphobos/libdruntime/core/memory.d +++ b/libphobos/libdruntime/core/memory.d @@ -202,8 +202,8 @@ unittest // make it more difficult to call the function again, manually. private void initialize(); pragma(crt_constructor) -pragma(mangle, `_D` ~ initialize.mangleof) -private extern (C) void initialize() @system +pragma(mangle, initialize.mangleof) +private extern (C) void _initialize() @system { version (Posix) { diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d index 16bc47501e3..c85682ec0a6 100644 --- a/libphobos/libdruntime/core/stdc/config.d +++ b/libphobos/libdruntime/core/stdc/config.d @@ -312,3 +312,28 @@ alias c_complex_float = __c_complex_float; alias c_complex_double = __c_complex_double; alias c_complex_real = __c_complex_real; } + + +// Returns the mangled name for the 64-bit time_t versions of +// functions affected by musl's transition to 64-bit time_t. +// https://musl.libc.org/time64.html +version (CRuntime_Musl) +{ + version (CRuntime_Musl_Pre_Time64) + enum muslRedirTime64 = false; + else + { + // time_t was defined as a C long in older Musl versions. + enum muslRedirTime64 = (c_long.sizeof == 4); + } +} +else + enum muslRedirTime64 = false; + +package(core) template muslRedirTime64Mangle(string name, string redirectedName) +{ + static if (muslRedirTime64) + enum muslRedirTime64Mangle = redirectedName; + else + enum muslRedirTime64Mangle = name; +} diff --git a/libphobos/libdruntime/core/stdc/time.d b/libphobos/libdruntime/core/stdc/time.d index b19c3c7a899..d7a57655fab 100644 --- a/libphobos/libdruntime/core/stdc/time.d +++ b/libphobos/libdruntime/core/stdc/time.d @@ -30,19 +30,25 @@ nothrow: @nogc: /// +pragma(mangle, muslRedirTime64Mangle!("difftime", "__difftime64")) pure double difftime(time_t time1, time_t time0); // MT-Safe /// +pragma(mangle, muslRedirTime64Mangle!("mktime", "__mktime64")) @system time_t mktime(scope tm* timeptr); // @system: MT-Safe env locale /// +pragma(mangle, muslRedirTime64Mangle!("time", "__time64")) time_t time(scope time_t* timer); /// @system char* asctime(const scope tm* timeptr); // @system: MT-Unsafe race:asctime locale /// +pragma(mangle, muslRedirTime64Mangle!("ctime", "__ctime64")) @system char* ctime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf race:asctime env locale /// +pragma(mangle, muslRedirTime64Mangle!("gmtime", "__gmtime64")) @system tm* gmtime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf env locale /// +pragma(mangle, muslRedirTime64Mangle!("localtime", "__localtime64")) @system tm* localtime(const scope time_t* timer); // @system: MT-Unsafe race:tmbuf env locale /// @system size_t strftime(scope char* s, size_t maxsize, const scope char* format, const scope tm* timeptr); // @system: MT-Safe env locale diff --git a/libphobos/libdruntime/core/sys/darwin/sys/event.d b/libphobos/libdruntime/core/sys/darwin/sys/event.d index 24f1cbe6528..53504db449e 100644 --- a/libphobos/libdruntime/core/sys/darwin/sys/event.d +++ b/libphobos/libdruntime/core/sys/darwin/sys/event.d @@ -46,12 +46,12 @@ enum : short EVFILT_EXCEPT = -15, } -extern(D) void EV_SET(kevent_t* kevp, typeof(kevent_t.tupleof) args) +extern(D) void EV_SET()(kevent_t* kevp, typeof(kevent_t.tupleof) args) { *kevp = kevent_t(args); } -extern(D) void EV_SET64(kevent64_s* kevp, typeof(kevent64_s.tupleof) args) +extern(D) void EV_SET64()(kevent64_s* kevp, typeof(kevent64_s.tupleof) args) { *kevp = kevent64_s(args); } diff --git a/libphobos/libdruntime/core/sys/posix/aio.d b/libphobos/libdruntime/core/sys/posix/aio.d index 3ea7f6a19ad..3a537a4a575 100644 --- a/libphobos/libdruntime/core/sys/posix/aio.d +++ b/libphobos/libdruntime/core/sys/posix/aio.d @@ -8,6 +8,7 @@ */ module core.sys.posix.aio; +import core.stdc.config; import core.sys.posix.signal; import core.sys.posix.sys.types; @@ -392,6 +393,7 @@ else int aio_fsync(int op, aiocb* aiocbp); int aio_error(const(aiocb)* aiocbp); ssize_t aio_return(aiocb* aiocbp); + pragma(mangle, muslRedirTime64Mangle!("aio_suspend", "__aio_suspend_time64")) int aio_suspend(const(aiocb*)* aiocb_list, int nitems, const(timespec)* timeout); int aio_cancel(int fd, aiocb* aiocbp); int lio_listio(int mode, const(aiocb*)* aiocb_list, int nitems, sigevent* sevp); diff --git a/libphobos/libdruntime/core/sys/posix/dlfcn.d b/libphobos/libdruntime/core/sys/posix/dlfcn.d index 5797b8fd35d..f4bd2d8ba92 100644 --- a/libphobos/libdruntime/core/sys/posix/dlfcn.d +++ b/libphobos/libdruntime/core/sys/posix/dlfcn.d @@ -177,6 +177,38 @@ version (CRuntime_Glibc) void* dli_saddr; } } +else +version (CRuntime_Musl) +{ + enum RTLD_LAZY = 1; + enum RTLD_NOW = 2; + enum RTLD_NOLOAD = 4; + enum RTLD_NODELETE = 4096; + enum RTLD_GLOBAL = 256; + enum RTLD_LOCAL = 0; + + enum RTLD_NEXT = cast(void *)-1; + enum RTLD_DEFAULT = cast(void *)0; + + enum RTLD_DI_LINKMAP = 2; + + int dlclose(void *); + char *dlerror(); + void *dlopen(const(char) *, int); + + pragma(mangle, muslRedirTime64Mangle!("dlsym", "__dlsym_time64")) + void *dlsym(void *__restrict, const(char) *__restrict); + + struct Dl_info + { + const(char)* dli_fname; + void* dli_fbase; + const(char)* dli_sname; + void* dli_saddr; + } + int dladdr(const(void) *, Dl_info *); + int dlinfo(void *, int, void *); +} else version (Darwin) { enum RTLD_LAZY = 0x00001; diff --git a/libphobos/libdruntime/core/sys/posix/mqueue.d b/libphobos/libdruntime/core/sys/posix/mqueue.d index ac697bf8b9b..eae50d27d83 100644 --- a/libphobos/libdruntime/core/sys/posix/mqueue.d +++ b/libphobos/libdruntime/core/sys/posix/mqueue.d @@ -178,6 +178,7 @@ ssize_t mq_receive (mqd_t mqdes, char* msg_ptr, size_t msg_len, uint* msg_prio); * On success, mq_receive() returns the number of bytes in the received * message; on error, -1 is returned, with errno set to indicate the error */ +pragma(mangle, muslRedirTime64Mangle!("mq_timedreceive", "__mq_timedreceive_time64")) ssize_t mq_timedreceive (mqd_t mqdes, char* msg_ptr, size_t msg_len, uint* msg_prio, const(timespec)* abs_timeout); @@ -216,5 +217,6 @@ int mq_send (mqd_t mqdes, const(char)* msg_ptr, size_t msg_len, uint msg_prio); * with errno set to indicate the error. * */ +pragma(mangle, muslRedirTime64Mangle!("mq_timedsend", "__mq_timedsend_time64")) int mq_timedsend (mqd_t mqdes, const(char)* msg_ptr, size_t msg_len, uint msg_prio, const(timespec)* abs_timeout); diff --git a/libphobos/libdruntime/core/sys/posix/netinet/in_.d b/libphobos/libdruntime/core/sys/posix/netinet/in_.d index a58fa850d5d..5818ee6e22b 100644 --- a/libphobos/libdruntime/core/sys/posix/netinet/in_.d +++ b/libphobos/libdruntime/core/sys/posix/netinet/in_.d @@ -547,7 +547,7 @@ version (CRuntime_Glibc) } // macros - extern (D) int IN6_IS_ADDR_UNSPECIFIED( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* addr ) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -555,7 +555,7 @@ version (CRuntime_Glibc) (cast(uint32_t*) addr)[3] == 0; } - extern (D) int IN6_IS_ADDR_LOOPBACK( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* addr ) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -563,29 +563,29 @@ version (CRuntime_Glibc) (cast(uint32_t*) addr)[3] == htonl( 1 ); } - extern (D) int IN6_IS_ADDR_MULTICAST( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* addr ) pure { return (cast(uint8_t*) addr)[0] == 0xff; } - extern (D) int IN6_IS_ADDR_LINKLOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* addr ) pure { return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfe800000 ); } - extern (D) int IN6_IS_ADDR_SITELOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* addr ) pure { return ((cast(uint32_t*) addr)[0] & htonl( 0xffc00000 )) == htonl( 0xfec00000 ); } - extern (D) int IN6_IS_ADDR_V4MAPPED( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* addr ) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && (cast(uint32_t*) addr)[2] == htonl( 0xffff ); } - extern (D) int IN6_IS_ADDR_V4COMPAT( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* addr ) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -593,31 +593,31 @@ version (CRuntime_Glibc) ntohl( (cast(uint32_t*) addr)[3] ) > 1; } - extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* addr ) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x1; } - extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* addr ) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x2; } - extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* addr ) pure { return IN6_IS_ADDR_MULTICAST(addr) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x5; } - extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* addr ) pure { return IN6_IS_ADDR_MULTICAST( addr) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x8; } - extern (D) int IN6_IS_ADDR_MC_GLOBAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* addr ) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0xe; @@ -670,7 +670,7 @@ else version (Darwin) } // macros - extern (D) int IN6_IS_ADDR_UNSPECIFIED( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_UNSPECIFIED( const scope in6_addr* addr ) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -678,7 +678,7 @@ else version (Darwin) (cast(uint32_t*) addr)[3] == 0; } - extern (D) int IN6_IS_ADDR_LOOPBACK( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_LOOPBACK( const scope in6_addr* addr ) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -686,29 +686,29 @@ else version (Darwin) (cast(uint32_t*) addr)[3] == ntohl( 1 ); } - extern (D) int IN6_IS_ADDR_MULTICAST( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MULTICAST( const scope in6_addr* addr ) pure { return addr.s6_addr[0] == 0xff; } - extern (D) int IN6_IS_ADDR_LINKLOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_LINKLOCAL( const scope in6_addr* addr ) pure { return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0x80; } - extern (D) int IN6_IS_ADDR_SITELOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_SITELOCAL( const scope in6_addr* addr ) pure { return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0xc0; } - extern (D) int IN6_IS_ADDR_V4MAPPED( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_V4MAPPED( const scope in6_addr* addr ) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && (cast(uint32_t*) addr)[2] == ntohl( 0x0000ffff ); } - extern (D) int IN6_IS_ADDR_V4COMPAT( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_V4COMPAT( const scope in6_addr* addr ) pure { return (cast(uint32_t*) addr)[0] == 0 && (cast(uint32_t*) addr)[1] == 0 && @@ -717,31 +717,31 @@ else version (Darwin) (cast(uint32_t*) addr)[3] != ntohl( 1 ); } - extern (D) int IN6_IS_ADDR_MC_NODELOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MC_NODELOCAL( const scope in6_addr* addr ) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x1; } - extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MC_LINKLOCAL( const scope in6_addr* addr ) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x2; } - extern (D) int IN6_IS_ADDR_MC_SITELOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MC_SITELOCAL( const scope in6_addr* addr ) pure { return IN6_IS_ADDR_MULTICAST(addr) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x5; } - extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MC_ORGLOCAL( const scope in6_addr* addr ) pure { return IN6_IS_ADDR_MULTICAST( addr) && ((cast(uint8_t*) addr)[1] & 0xf) == 0x8; } - extern (D) int IN6_IS_ADDR_MC_GLOBAL( in6_addr* addr ) pure + extern (D) int IN6_IS_ADDR_MC_GLOBAL( const scope in6_addr* addr ) pure { return IN6_IS_ADDR_MULTICAST( addr ) && ((cast(uint8_t*) addr)[1] & 0xf) == 0xe; diff --git a/libphobos/libdruntime/core/sys/posix/sched.d b/libphobos/libdruntime/core/sys/posix/sched.d index f6f0a58e359..ba7ab8984a9 100644 --- a/libphobos/libdruntime/core/sys/posix/sched.d +++ b/libphobos/libdruntime/core/sys/posix/sched.d @@ -65,7 +65,10 @@ version (linux) { int sched_priority; int __reserved1; - timespec[2] __reserved2; + static if (muslRedirTime64) + c_long[2] __reserved2; + else + timespec[2] __reserved2; int __reserved3; } } @@ -282,6 +285,7 @@ else version (CRuntime_Musl) { int sched_get_priority_max(int); int sched_get_priority_min(int); + pragma(mangle, muslRedirTime64Mangle!("sched_rr_get_interval", "__sched_rr_get_interval_time64")) int sched_rr_get_interval(pid_t, timespec*); } else version (CRuntime_UClibc) diff --git a/libphobos/libdruntime/core/sys/posix/semaphore.d b/libphobos/libdruntime/core/sys/posix/semaphore.d index d755f86c9cc..4f3b6e951c3 100644 --- a/libphobos/libdruntime/core/sys/posix/semaphore.d +++ b/libphobos/libdruntime/core/sys/posix/semaphore.d @@ -216,6 +216,7 @@ else version (CRuntime_Bionic) } else version (CRuntime_Musl) { + pragma(mangle, muslRedirTime64Mangle!("sem_timedwait", "__sem_timedwait_time64")) int sem_timedwait(sem_t*, const scope timespec*); } else version (CRuntime_UClibc) diff --git a/libphobos/libdruntime/core/sys/posix/signal.d b/libphobos/libdruntime/core/sys/posix/signal.d index 542e83a1679..f722bc4df62 100644 --- a/libphobos/libdruntime/core/sys/posix/signal.d +++ b/libphobos/libdruntime/core/sys/posix/signal.d @@ -2990,6 +2990,7 @@ else version (CRuntime_Bionic) else version (CRuntime_Musl) { int sigqueue(pid_t, int, const sigval); + pragma(mangle, muslRedirTime64Mangle!("sigtimedwait", "__sigtimedwait_time64")) int sigtimedwait(const scope sigset_t*, siginfo_t*, const scope timespec*); int sigwaitinfo(const scope sigset_t*, siginfo_t*); } diff --git a/libphobos/libdruntime/core/sys/posix/sys/resource.d b/libphobos/libdruntime/core/sys/posix/sys/resource.d index 1f46f03e14d..b997f112e4d 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/resource.d +++ b/libphobos/libdruntime/core/sys/posix/sys/resource.d @@ -547,6 +547,7 @@ else version (CRuntime_Musl) int setrlimit(int, const scope rlimit*); alias getrlimit getrlimit64; alias setrlimit setrlimit64; + pragma(mangle, muslRedirTime64Mangle!("getrusage", "__getrusage_time64")) int getrusage(int, rusage*); } else version (Solaris) diff --git a/libphobos/libdruntime/core/sys/posix/sys/select.d b/libphobos/libdruntime/core/sys/posix/sys/select.d index 06b094093ed..dd05d08dde6 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/select.d +++ b/libphobos/libdruntime/core/sys/posix/sys/select.d @@ -501,7 +501,9 @@ else version (CRuntime_Musl) { fdset.fds_bits[0 .. $] = 0; } + pragma(mangle, muslRedirTime64Mangle!("pselect", "__pselect_time64")) int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*); + pragma(mangle, muslRedirTime64Mangle!("select", "__select_time64")) int select(int, fd_set*, fd_set*, fd_set*, timeval*); } else version (CRuntime_UClibc) diff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d index ecc98ccf0ed..ee9e5da2feb 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/stat.d +++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d @@ -1656,7 +1656,6 @@ else version (CRuntime_Bionic) } else version (CRuntime_Musl) { - alias __mode_t = uint; enum { S_IRUSR = 0x100, // octal 0400 S_IWUSR = 0x080, // octal 0200 @@ -1890,8 +1889,11 @@ else version (CRuntime_Bionic) } else version (CRuntime_Musl) { + pragma(mangle, muslRedirTime64Mangle!("stat", "__stat_time64")) int stat(const scope char*, stat_t*); + pragma(mangle, muslRedirTime64Mangle!("fstat", "__fstat_time64")) int fstat(int, stat_t*); + pragma(mangle, muslRedirTime64Mangle!("lstat", "__lstat_time64")) int lstat(const scope char*, stat_t*); alias fstat fstat64; diff --git a/libphobos/libdruntime/core/sys/posix/sys/time.d b/libphobos/libdruntime/core/sys/posix/sys/time.d index b536eedc14f..dda4caf0bf3 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/time.d +++ b/libphobos/libdruntime/core/sys/posix/sys/time.d @@ -89,7 +89,9 @@ else version (CRuntime_Musl) time_t tv_sec; suseconds_t tv_usec; } + pragma(mangle, muslRedirTime64Mangle!("gettimeofday", "__gettimeofday_time64")) int gettimeofday(timeval*, void*); + pragma(mangle, muslRedirTime64Mangle!("utimes", "__utimes_time64")) int utimes(const scope char*, ref const(timeval)[2]); } else version (Darwin) diff --git a/libphobos/libdruntime/core/sys/posix/time.d b/libphobos/libdruntime/core/sys/posix/time.d index af52002b1aa..f49764d1964 100644 --- a/libphobos/libdruntime/core/sys/posix/time.d +++ b/libphobos/libdruntime/core/sys/posix/time.d @@ -83,6 +83,7 @@ else version (CRuntime_Bionic) } else version (CRuntime_Musl) { + pragma(mangle, muslRedirTime64Mangle!("timegm", "__timegm_time64")) time_t timegm(tm*); } else version (CRuntime_UClibc) @@ -483,15 +484,21 @@ else version (CRuntime_Musl) int nanosleep(const scope timespec*, timespec*); + pragma(mangle, muslRedirTime64Mangle!("clock_getres", "__clock_getres_time64")) int clock_getres(clockid_t, timespec*); + pragma(mangle, muslRedirTime64Mangle!("clock_gettime", "__clock_gettime64")) int clock_gettime(clockid_t, timespec*); + pragma(mangle, muslRedirTime64Mangle!("clock_settime", "__clock_settime64")) int clock_settime(clockid_t, const scope timespec*); + pragma(mangle, muslRedirTime64Mangle!("clock_nanosleep", "__clock_nanosleep_time64")) int clock_nanosleep(clockid_t, int, const scope timespec*, timespec*); int clock_getcpuclockid(pid_t, clockid_t *); int timer_create(clockid_t, sigevent*, timer_t*); int timer_delete(timer_t); + pragma(mangle, muslRedirTime64Mangle!("timer_gettime", "__timer_gettime64")) int timer_gettime(timer_t, itimerspec*); + pragma(mangle, muslRedirTime64Mangle!("timer_settime", "__timer_settime64")) int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*); int timer_getoverrun(timer_t); } @@ -596,8 +603,11 @@ else version (CRuntime_Bionic) else version (CRuntime_Musl) { char* asctime_r(const scope tm*, char*); + pragma(mangle, muslRedirTime64Mangle!("ctime_r", "__ctime64_r")) char* ctime_r(const scope time_t*, char*); + pragma(mangle, muslRedirTime64Mangle!("gmtime_r", "__gmtime64_r")) tm* gmtime_r(const scope time_t*, tm*); + pragma(mangle, muslRedirTime64Mangle!("localtime_r", "__localtime64_r")) tm* localtime_r(const scope time_t*, tm*); } else version (CRuntime_UClibc) diff --git a/libphobos/libdruntime/core/sys/posix/utime.d b/libphobos/libdruntime/core/sys/posix/utime.d index fcec7af3fde..e7059d71283 100644 --- a/libphobos/libdruntime/core/sys/posix/utime.d +++ b/libphobos/libdruntime/core/sys/posix/utime.d @@ -62,6 +62,7 @@ else version (CRuntime_Musl) time_t modtime; } + pragma(mangle, muslRedirTime64Mangle!("utime", "__utime64")) int utime(const scope char*, const scope utimbuf*); } else version (Darwin) diff --git a/libphobos/libdruntime/core/sys/windows/stacktrace.d b/libphobos/libdruntime/core/sys/windows/stacktrace.d index 8df29729af3..c10a9175b4d 100644 --- a/libphobos/libdruntime/core/sys/windows/stacktrace.d +++ b/libphobos/libdruntime/core/sys/windows/stacktrace.d @@ -30,6 +30,7 @@ extern(Windows) DWORD GetEnvironmentVariableA(LPCSTR lpName, LPSTR pBuffer, DWOR extern(Windows) alias USHORT function(ULONG FramesToSkip, ULONG FramesToCapture, PVOID *BackTrace, PULONG BackTraceHash) @nogc RtlCaptureStackBackTraceFunc; private __gshared RtlCaptureStackBackTraceFunc RtlCaptureStackBackTrace; +private __gshared CRITICAL_SECTION mutex; // cannot use core.sync.mutex.Mutex unfortunately (cyclic dependency...) private __gshared immutable bool initialized; @@ -63,11 +64,11 @@ public: skip += INTERNALFRAMES; } - if ( initialized ) + if (initialized) m_trace = trace(tracebuf[], skip, context); } - int opApply( scope int delegate(ref const(char[])) dg ) const + override int opApply( scope int delegate(ref const(char[])) dg ) const { return opApply( (ref size_t, ref const(char[]) buf) { @@ -76,7 +77,7 @@ public: } - int opApply( scope int delegate(ref size_t, ref const(char[])) dg ) const + override int opApply( scope int delegate(ref size_t, ref const(char[])) dg ) const { int result; foreach ( i, e; resolve(m_trace) ) @@ -118,10 +119,10 @@ public: /// ditto static ulong[] trace(ulong[] buffer, size_t skip = 0, CONTEXT* context = null) @nogc { - synchronized( typeid(StackTrace) ) - { - return traceNoSync(buffer, skip, context); - } + EnterCriticalSection(&mutex); + scope(exit) LeaveCriticalSection(&mutex); + + return traceNoSync(buffer, skip, context); } /** @@ -133,10 +134,15 @@ public: */ @trusted static char[][] resolve(const(ulong)[] addresses) { - synchronized( typeid(StackTrace) ) - { - return resolveNoSync(addresses); - } + // FIXME: make @nogc to avoid having to disable resolution within finalizers + import core.memory : GC; + if (GC.inFinalizer) + return null; + + EnterCriticalSection(&mutex); + scope(exit) LeaveCriticalSection(&mutex); + + return resolveNoSync(addresses); } private: @@ -421,5 +427,6 @@ shared static this() dbghelp.SymRegisterCallback64(hProcess, &FixupDebugHeader, 0); + InitializeCriticalSection(&mutex); initialized = true; } diff --git a/libphobos/libdruntime/core/sys/windows/winbase.d b/libphobos/libdruntime/core/sys/windows/winbase.d index 3b571ad57da..bbb6e9a7b41 100644 --- a/libphobos/libdruntime/core/sys/windows/winbase.d +++ b/libphobos/libdruntime/core/sys/windows/winbase.d @@ -38,6 +38,7 @@ import core.sys.windows.basetyps, core.sys.windows.w32api, core.sys.windows.winn // FIXME: //alias void va_list; import core.stdc.stdarg : va_list; +import core.stdc.string : memset, memcpy, memmove; // COMMPROP structure, used by GetCommProperties() @@ -1713,23 +1714,15 @@ extern (Windows) nothrow @nogc { BOOL CopyFileExA(LPCSTR, LPCSTR, LPPROGRESS_ROUTINE, LPVOID, LPBOOL, DWORD); BOOL CopyFileExW(LPCWSTR, LPCWSTR, LPPROGRESS_ROUTINE, LPVOID, LPBOOL, DWORD); - /+ FIXME - alias memmove RtlMoveMemory; - alias memcpy RtlCopyMemory; + alias RtlMoveMemory = memmove; + alias RtlCopyMemory = memcpy; + pragma(inline, true) void RtlFillMemory(PVOID Destination, SIZE_T Length, BYTE Fill) { memset(Destination, Fill, Length); } + pragma(inline, true) void RtlZeroMemory(PVOID Destination, SIZE_T Length) { memset(Destination, 0, Length); } + alias MoveMemory = RtlMoveMemory; + alias CopyMemory = RtlCopyMemory; + alias FillMemory = RtlFillMemory; + alias ZeroMemory = RtlZeroMemory; - void RtlFillMemory(PVOID dest, SIZE_T len, BYTE fill) { - memset(dest, fill, len); - } - - void RtlZeroMemory(PVOID dest, SIZE_T len) { - RtlFillMemory(dest, len, 0); - } - - alias RtlMoveMemory MoveMemory; - alias RtlCopyMemory CopyMemory; - alias RtlFillMemory FillMemory; - alias RtlZeroMemory ZeroMemory; - +/ BOOL CreateDirectoryA(LPCSTR, LPSECURITY_ATTRIBUTES); BOOL CreateDirectoryW(LPCWSTR, LPSECURITY_ATTRIBUTES); BOOL CreateDirectoryExA(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES); diff --git a/libphobos/libdruntime/core/thread/fiber.d b/libphobos/libdruntime/core/thread/fiber.d index efbad7d6b74..4590ff1c052 100644 --- a/libphobos/libdruntime/core/thread/fiber.d +++ b/libphobos/libdruntime/core/thread/fiber.d @@ -19,6 +19,8 @@ import core.thread.threadgroup; import core.thread.types; import core.thread.context; +import core.memory : pageSize; + /////////////////////////////////////////////////////////////////////////////// // Fiber Platform Detection /////////////////////////////////////////////////////////////////////////////// @@ -600,7 +602,7 @@ class Fiber version (X86_64) // libunwind on macOS 11 now requires more stack space than 16k, so // default to a larger stack size. This is only applied to X86 as - // the PAGESIZE is still 4k, however on AArch64 it is 16k. + // the pageSize is still 4k, however on AArch64 it is 16k. enum defaultStackPages = 8; else enum defaultStackPages = 4; @@ -623,8 +625,8 @@ class Fiber * In: * fn must not be null. */ - this( void function() fn, size_t sz = PAGESIZE * defaultStackPages, - size_t guardPageSize = PAGESIZE ) nothrow + this( void function() fn, size_t sz = pageSize * defaultStackPages, + size_t guardPageSize = pageSize ) nothrow in { assert( fn ); @@ -651,8 +653,8 @@ class Fiber * In: * dg must not be null. */ - this( void delegate() dg, size_t sz = PAGESIZE * defaultStackPages, - size_t guardPageSize = PAGESIZE ) nothrow + this( void delegate() dg, size_t sz = pageSize * defaultStackPages, + size_t guardPageSize = pageSize ) nothrow { allocStack( sz, guardPageSize ); reset( cast(void delegate() const) dg ); @@ -962,9 +964,9 @@ private: } do { - // adjust alloc size to a multiple of PAGESIZE - sz += PAGESIZE - 1; - sz -= sz % PAGESIZE; + // adjust alloc size to a multiple of pageSize + sz += pageSize - 1; + sz -= sz % pageSize; // NOTE: This instance of Thread.Context is dynamic so Fiber objects // can be collected by the GC so long as no user level references diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d index 7316373195a..066f39e39c7 100644 --- a/libphobos/libdruntime/core/thread/osthread.d +++ b/libphobos/libdruntime/core/thread/osthread.d @@ -19,7 +19,7 @@ import core.thread.threadbase; import core.thread.context; import core.thread.types; import core.atomic; -import core.memory : GC; +import core.memory : GC, pageSize; import core.time; import core.exception : onOutOfMemoryError; import core.internal.traits : externDFunc; @@ -1115,7 +1115,7 @@ unittest unittest { - // use >PAGESIZE to avoid stack overflow (e.g. in an syscall) + // use >pageSize to avoid stack overflow (e.g. in an syscall) auto thr = new Thread(function{}, 4096 + 1).start(); thr.join(); } @@ -2889,8 +2889,8 @@ private size_t adjustStackSize(size_t sz) nothrow @nogc } } - // stack size must be a multiple of PAGESIZE - sz = ((sz + PAGESIZE - 1) & ~(PAGESIZE - 1)); + // stack size must be a multiple of pageSize + sz = ((sz + pageSize - 1) & ~(pageSize - 1)); return sz; } diff --git a/libphobos/libdruntime/core/thread/types.d b/libphobos/libdruntime/core/thread/types.d index e50399a59d9..eb84ad74b48 100644 --- a/libphobos/libdruntime/core/thread/types.d +++ b/libphobos/libdruntime/core/thread/types.d @@ -47,31 +47,15 @@ else package { - static immutable size_t PAGESIZE; version (Posix) static immutable size_t PTHREAD_STACK_MIN; } shared static this() { - version (Windows) - { - import core.sys.windows.winbase; - - SYSTEM_INFO info; - GetSystemInfo(&info); - - PAGESIZE = info.dwPageSize; - assert(PAGESIZE < int.max); - } - else version (Posix) + version (Posix) { import core.sys.posix.unistd; - PAGESIZE = cast(size_t)sysconf(_SC_PAGESIZE); PTHREAD_STACK_MIN = cast(size_t)sysconf(_SC_THREAD_STACK_MIN); } - else - { - static assert(0, "unimplemented"); - } } diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index 0385b51d60e..a77788bec20 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -246,7 +246,7 @@ class Object * } * --- */ - deprecated static Object factory(string classname) + static Object factory(string classname) { auto ci = TypeInfo_Class.find(classname); if (ci) @@ -256,7 +256,7 @@ class Object return null; } - deprecated @system unittest + @system unittest { Object valid_obj = Object.factory("object.Object"); Object invalid_obj = Object.factory("object.__this_class_doesnt_exist__"); @@ -1417,7 +1417,7 @@ class TypeInfo_Function : TypeInfo int func(int a, int b); } - alias functionTypes = typeof(__traits(getVirtualFunctions, C, "func")); + alias functionTypes = typeof(__traits(getVirtualMethods, C, "func")); assert(typeid(functionTypes[0]).toString() == "void function()"); assert(typeid(functionTypes[1]).toString() == "void function(int)"); assert(typeid(functionTypes[2]).toString() == "int function(int, int)"); @@ -1431,7 +1431,7 @@ class TypeInfo_Function : TypeInfo void func(int a); } - alias functionTypes = typeof(__traits(getVirtualFunctions, C, "func")); + alias functionTypes = typeof(__traits(getVirtualMethods, C, "func")); Object obj = typeid(functionTypes[0]); assert(obj.opEquals(typeid(functionTypes[0]))); @@ -2927,25 +2927,6 @@ void clear(Value, Key)(Value[Key]* aa) assert("k1" !in aa); } -// Issue 20559 -@system unittest -{ - static class Foo - { - int[string] aa; - alias aa this; - } - - auto v = new Foo(); - v["Hello World"] = 42; - v.clear; - assert("Hello World" !in v); - - // Test for T* - static assert(!__traits(compiles, (&v).clear)); - static assert( __traits(compiles, (*(&v)).clear)); -} - /*********************************** * Reorganizes the associative array in place so that lookups are more * efficient. @@ -4280,44 +4261,6 @@ void destroy(bool initialize = true, T)(T obj) if (is(T == interface)) @system unittest { - // class with an `alias this` - class A - { - static int dtorCount; - ~this() - { - dtorCount++; - } - } - - class B - { - A a; - alias a this; - this() - { - a = new A; - } - static int dtorCount; - ~this() - { - dtorCount++; - } - } - auto b = new B; - assert(A.dtorCount == 0); - assert(B.dtorCount == 0); - destroy(b); - assert(A.dtorCount == 0); - assert(B.dtorCount == 1); - - auto a = new A; - destroy(a); - assert(A.dtorCount == 1); -} - -@system unittest -{ interface I { } { class A: I { string s = "A"; this() {} } @@ -4529,43 +4472,6 @@ if (__traits(isStaticArray, T)) } } -// https://issues.dlang.org/show_bug.cgi?id=19218 -@system unittest -{ - static struct S - { - static dtorCount = 0; - ~this() { ++dtorCount; } - } - - static interface I - { - ref S[3] getArray(); - alias getArray this; - } - - static class C : I - { - static dtorCount = 0; - ~this() { ++dtorCount; } - - S[3] a; - alias a this; - - ref S[3] getArray() { return a; } - } - - C c = new C(); - destroy(c); - assert(S.dtorCount == 3); - assert(C.dtorCount == 1); - - I i = new C(); - destroy(i); - assert(S.dtorCount == 6); - assert(C.dtorCount == 2); -} - /// ditto void destroy(bool initialize = true, T)(ref T obj) if (!is(T == struct) && !is(T == interface) && !is(T == class) && !__traits(isStaticArray, T)) @@ -4622,7 +4528,8 @@ they are only intended to be instantiated by the compiler, not the user. public import core.internal.entrypoint : _d_cmain; public import core.internal.array.appending : _d_arrayappendT; -public import core.internal.array.appending : _d_arrayappendTTrace; +version (D_ProfileGC) + public import core.internal.array.appending : _d_arrayappendTTrace; public import core.internal.array.appending : _d_arrayappendcTXImpl; public import core.internal.array.comparison : __cmp; public import core.internal.array.equality : __equals; @@ -4648,6 +4555,8 @@ public import core.internal.switch_: __switch_error; public import core.lifetime : _d_delstructImpl; public import core.lifetime : _d_newThrowable; +public import core.lifetime : _d_newclassT; +public import core.lifetime : _d_newclassTTrace; public @trusted @nogc nothrow pure extern (C) void _d_delThrowable(scope Throwable); |