diff --git a/src/ctfeexpr.c b/src/ctfeexpr.c index 48d92c1362b2..ec3d94c9af39 100644 --- a/src/ctfeexpr.c +++ b/src/ctfeexpr.c @@ -1793,11 +1793,23 @@ Expression *ctfeCast(Loc loc, Type *type, Type *to, Expression *e) { return paintTypeOntoLiteral(to, e); } + Expression *r; if (e->type->equals(type) && type->equals(to)) - r = e; // necessary not to change e's address for pointer comparisons + { + // necessary not to change e's address for pointer comparisons + r = e; + } + else if (to->toBasetype()->ty == Tarray && type->toBasetype()->ty == Tarray && + to->toBasetype()->nextOf()->size() == type->toBasetype()->nextOf()->size()) + { + // Bugzilla 12495: Array reinterpret casts: eg. string to immutable(ubyte)[] + return paintTypeOntoLiteral(to, e); + } else + { r = Cast(type, to, e).copy(); + } if (CTFEExp::isCantExp(r)) error(loc, "cannot cast %s to %s at compile time", e->toChars(), to->toChars()); if (e->op == TOKarrayliteral) diff --git a/test/compilable/interpret3.d b/test/compilable/interpret3.d index d7f2bbb43cb8..c4179731e009 100644 --- a/test/compilable/interpret3.d +++ b/test/compilable/interpret3.d @@ -7143,6 +7143,29 @@ static assert({ return true; }()); +/************************************************** + 12495 - cast from string to immutable(ubyte)[] +**************************************************/ + +string getStr12495() +{ + char[1] buf = void; // dummy starting point. + string s = cast(string)buf[0..0]; // empty slice, .ptr points mutable. + assert(buf.ptr == s.ptr); + s ~= 'a'; // this should allocate. + assert(buf.ptr != s.ptr); + return s.idup; // this should allocate again, and + // definitly point immutable memory. +} +auto indexOf12495(string s) +{ + auto p1 = s.ptr; + auto p2 = (cast(immutable(ubyte)[])s).ptr; + assert(cast(void*)p1 == cast(void*)p2); // OK <- fails + return cast(void*)p2 - cast(void*)p1; // OK <- "cannot subtract pointers ..." +} +static assert(indexOf12495(getStr12495()) == 0); + /************************************************** 13992 - Repainting pointer arithmetic result **************************************************/