Change Log: 2.077.0
Download D 2.077.0
released Nov 1, 2017
Compiler changes
Runtime changes
List of all bug fixes and enhancements in D 2.077.0.
Compiler changes
- Mangled Symbols now back reference types and identifiers.
Symbols with extern(D) linkage are now mangled using back references to types and identifiers if these occur more than once in the mangled name as emitted before. This reduces symbol length, especially with chained expressions of templated functions with Voldemort return types. For example, the average symbol length of the 127000+ symbols created by a phobos unittest build is reduced by a factor of about 3, while the longest symbol shrinks from 416133 to 1142 characters.
See details in the ABI specification.
- Removed prelude assert for constructors & destructors
The compiler used to insert an assert(this, "null this"); at the start of constructors & destructors. To trigger these asserts one needed to construct or destruct an aggregate at the null memory location. This would crash upon any data member access, which is required for a constructor or destructor to do anything useful.
- DMD builds are now reproducible
The dmd reference compiler now deterministically produces identical binaries for a given source code and configuration, thus allowing third parties to verify that distributed binaries indeed originate from specified source code.
This guarantee only applies when the same compiler version and configuration is used. Also values of the non-deterministic lexer tokens __DATE__, __TIME__, and __TIMESTAMP__ must not end up in the binary.
See reproducible-builds.org for further information.
Runtime changes
- core.atomic.atomicLoad's returns types have changed for aggregate types that have indirections.
core.atomic.atomicLoad used to strip the shared qualifier off too eagerly. When an aggregate type has a "head" and a "tail", connected by an indirection, then atomicLoad used to strip shared off the tail. That was a bug (Bugzilla 16230). atomicLoad only loads the head. The tail remains in shared memory, and must keep the shared qualifier.
When loading a struct that contains indirections, atomicLoad now returns a wrapper that provides getters which return properly typed values.
When loading a class reference, atomicLoad now leaves the shared qualifier on.
Example:
class C { int value; } shared C shc = new C; struct S { int head; int* tailPointer; } shared int tail = 1; auto shs = shared S(2, &tail); void main() { import core.atomic : atomicLoad, atomicOp; // Loading a class reference: shared C c = atomicLoad(shc); // c itself is not actually shared. It's safe to copy it non-atomically: shared C c2 = c; // ok // c's fields are still shared and need to be loaded atomically: int v = atomicLoad(c.value); // Loading a struct that has an indirection: auto s = atomicLoad(shs); // The struct's head has been copied and can be modified non-atomically: ++s.head; // The tail is still shared and needs to be handled atomically: shared(int)* t = s.tailPointer; atomicOp!"+="(*t, 1); }
- Vectorized array operations are now templated
Array operations have been converted from dedicated assembly routines for some array operations to a generic template implementation for all array operations. This provides huge performance increases (2-4x higher throughput) for array operations that were not previously vectorized. Furthermore the implementation makes better use of vectorization even for short arrays to heavily reduce latency for some operations (up to 4x).
For GDC/LDC the implementation relies on auto-vectorization, for DMD the implementation performs the vectorization itself. Support for vector operations with DMD is determined statically (-march=native, -march=avx2) to avoid binary bloat and the small test overhead. DMD enables SSE2 for 64-bit targets by default.
Also see druntime#1891
Note: The implementation no longer weakens floating point divisions (e.g. ary[] / scalar) to multiplication (ary[] * (1.0 / scalar)) as that may reduce precision. To preserve the higher performance of float multiplication when loss of precision is acceptable, use either -ffast-math with GDC/LDC or manually rewrite your code to multiply by (1.0 / scalar) for DMD.
List of all bug fixes and enhancements in D 2.077.0:
DMD Compiler regressions
- Bugzilla 15538: [REG 2.064] wrong code with switch
- Bugzilla 16013: [REG2.072a] ICE with mutually dependent structs and alias this
- Bugzilla 16273: [REG 2.072a] dmd segfault with inheritance, templates, override
- Bugzilla 17307: [REG2.072.0][ICE] TypeBasic::implicitConvTo: After error "anonymous struct can only be a part of an aggregate"
- Bugzilla 17684: [REG 2.062] static alias this bug or incomplete implementation?
DMD Compiler bugs
- Bugzilla 6625: Distribute newer Windows API import libraries
- Bugzilla 11259: __traits(isSame) fails on the result of __traits(parent) if parent is a package
- Bugzilla 17370: [scope] Escaping scope pointers possible via struct GC allocation
- Bugzilla 17568: [scope] addresses to fields can be escaped from scope method
- Bugzilla 17725: [scope] escape from nested function to enclosing local
- Bugzilla 17751: Internal error: ddmd/backend/el.c 2927
- Bugzilla 17782: The identifier delimiter of a delimited string can not begin with '_'
- Bugzilla 17790: [scope] Escaping pointer possible through array of aggregates
- Bugzilla 17795: [scope] Scope errors not detected in ~= operation
- Bugzilla 17857: T.alignof ignores explicit align(N) type alignment
- Bugzilla 17943: Wrong pointer arithmetic optimization
DMD Compiler enhancements
- Bugzilla 10523: Don't call array op functions for short vector ops
- Bugzilla 13262: Cannot send certain shared data to another thread
- Bugzilla 15831: IFTI voldemort type exploding bloat
- Bugzilla 16995: __traits(getUnittests) doesn't work with separate compilation
- Bugzilla 17787: Add a BetterC predefined version so libraries can adapt
- Bugzilla 17791: Add __traits(isDeprecated, ...)
- Bugzilla 17887: Add WebAssembly reserved version identifier
Phobos bugs
- Bugzilla 3191: std.zlib.UnCompress errors if buffer is reused
- Bugzilla 8779: std.zlib.UnCompress needs a way to detect end-of-stream
- Bugzilla 9505: std.zlib seem to be bugged
- Bugzilla 10444: writeln of a SIMD register
- Bugzilla 11389: template arity does not work with function type
- Bugzilla 12470: std.array.replace does not work with inout(char)[]
- Bugzilla 13829: std.uni.byCodePoint for strings has length
- Bugzilla 15096: std.array.array cannot be instantiated for pointers to ranges
- Bugzilla 15735: std.algorithm.iteration.splitter returns empty range
- Bugzilla 16264: BigInt multiplication crashes on 64-bit (biguintnoasm.d(276): Range violation)
- Bugzilla 17847: Properly sanitize seeds for Park–Miller engines
Phobos enhancements
- Bugzilla 4582: distinct field names constraint for std.typecons.Tuple
- Bugzilla 6004: std.range.unzip()
- Bugzilla 6409: std.array.empty for associative arrays too
- Bugzilla 9183: Add a Nullable.get(x) overload
- Bugzilla 9591: std.typetuple.staticApplyMap
- Bugzilla 16512: std.allocator: Nullify the argument passed to allocator.dispose
- Bugzilla 16984: Make more modules runnable on dlang.org
- Bugzilla 17803: std.typecons.Tuple: opAssign should return ref Tuple
- Bugzilla 17844: std.process.execute should allow not capturing stderr
Druntime bugs
- Bugzilla 16230: core.atomic.atomicLoad removes shared from aggregate types too eagerly
- Bugzilla 17829: core.stdc.errno does not work with -betterC
dlang.org bugs
- Bugzilla 9958: "Integer FloatSuffix" is not a valid FloatLiteral
- Bugzilla 17649: CONTRIBUTING.md instructions failed (no ../druntime dir)
- Bugzilla 17798: [2.076] "static foreach" not documented
- Bugzilla 17848: Example of floating point literals in the documentation is invalid
- Bugzilla 17856: __traits( identifier ) could use examples in on line documentation.
dlang.org enhancements
- Bugzilla 17581: Document behavior of -betterC