From e63c620433f51da97a45e5400ca0a71202d7b129 Mon Sep 17 00:00:00 2001 From: tsbockman Date: Fri, 21 Apr 2017 12:26:16 -0700 Subject: [PATCH] issue 15645 - Prevent unsafe usage of Tuple.slice --- std/typecons.d | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/std/typecons.d b/std/typecons.d index d43da0331b7..6671f5e9d46 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -970,7 +970,7 @@ template Tuple(Specs...) } /** - * Takes a slice of this `Tuple`. + * Takes a slice by-reference of this `Tuple`. * * Params: * from = A `size_t` designating the starting position of the slice. @@ -982,9 +982,14 @@ template Tuple(Specs...) * the original. */ @property - ref Tuple!(sliceSpecs!(from, to)) slice(size_t from, size_t to)() @trusted + ref inout(Tuple!(sliceSpecs!(from, to))) slice(size_t from, size_t to)() inout @trusted if (from <= to && to <= Types.length) { + static assert( + (typeof(this).alignof % typeof(return).alignof == 0) && + (expand[from].offsetof % typeof(return).alignof == 0), + "Slicing by reference is impossible because of an alignment mistmatch. (See Phobos issue #15645.)"); + return *cast(typeof(return)*) &(field[from]); } @@ -997,6 +1002,10 @@ template Tuple(Specs...) auto s = a.slice!(1, 3); static assert(is(typeof(s) == Tuple!(string, float))); assert(s[0] == "abc" && s[1] == 4.5); + + // Phobos issue #15645 + Tuple!(int, short, bool, double) b; + static assert(!__traits(compiles, b.slice!(2, 4))); } /**