mirror of
https://github.com/openRuyi-Project/gcc.git
synced 2026-09-07 22:42:06 +00:00
D front-end changes: - `delete' is no longer a keyword. - Initializing a field with itself has been deprecated. D runtime changes: - Add Windows BCrypt bindings under `core.sys.windows.bcrypt'. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream b7e3b3b617. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream b7e3b3b617. * libdruntime/Makefile.am (DRUNTIME_DSOURCES_WINDOWS): Add core/sys/windows/bcrypt.d. * libdruntime/Makefile.in: Regenerate. * libdruntime/gcc/sections/elf.d (sizeofTLS): Give function the same mangling as gcc.sections.sizeofTLS. * libdruntime/gcc/sections/package.d: Import core.internal.traits. (pinLoadedLibraries): Mangle as function from rt.sections_elf_shared. (unpinLoadedLibraries): Likewise. (inheritLoadedLibraries): Likewise. (cleanupLoadedLibraries): Likewise. (sizeOfTLS): Add forward declaration.
145 lines
4.0 KiB
D
145 lines
4.0 KiB
D
/**
|
|
This module contains compiler support for casting dynamic arrays
|
|
|
|
Copyright: Copyright Digital Mars 2000 - 2019.
|
|
License: Distributed under the
|
|
$(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
|
|
(See accompanying file LICENSE)
|
|
Source: $(DRUNTIMESRC core/internal/_array/_casting.d)
|
|
*/
|
|
module core.internal.array.casting;
|
|
|
|
/**
|
|
Used by `__ArrayCast` to emit a descriptive error message.
|
|
|
|
It is a template so it can be used by `__ArrayCast` in -betterC
|
|
builds. It is separate from `__ArrayCast` to minimize code
|
|
bloat.
|
|
|
|
Params:
|
|
fromType = name of the type being cast from
|
|
fromSize = total size in bytes of the array being cast from
|
|
fromLength = length of array being cast from
|
|
toType = name of the type being cast to
|
|
toElemSize = element size of array being cast to
|
|
*/
|
|
private void onArrayCastError()(string fromType, size_t fromSize, size_t fromLength, string toType, size_t toElemSize) @trusted
|
|
{
|
|
import core.internal.string : unsignedToTempString;
|
|
import core.memory : pureMalloc;
|
|
|
|
// convert discontiguous `msgComponents` to contiguous string on the C heap
|
|
enum msgLength = 2048;
|
|
// note: never freed!
|
|
char* msg = cast(char *)pureMalloc(msgLength);
|
|
|
|
size_t index = 0;
|
|
void add(const(char)[] m)
|
|
{
|
|
import core.stdc.string : memcpy;
|
|
|
|
auto N = msgLength - 1 - index;
|
|
if (N > m.length)
|
|
N = m.length;
|
|
// prevent superfluous and betterC-unfriendly checks via direct memcpy
|
|
memcpy(msg + index, m.ptr, N);
|
|
index += N;
|
|
}
|
|
|
|
add("`");
|
|
add(fromType);
|
|
add("[]` of length ");
|
|
auto s = unsignedToTempString(fromLength);
|
|
add(s[]);
|
|
add(" cannot be cast to `");
|
|
add(toType);
|
|
add("[]` as its length in bytes (");
|
|
s = unsignedToTempString(fromSize);
|
|
add(s[]);
|
|
add(") is not a multiple of `");
|
|
add(toType);
|
|
add(".sizeof` (");
|
|
s = unsignedToTempString(toElemSize);
|
|
add(s[]);
|
|
add(").");
|
|
msg[index] = '\0'; // null-termination
|
|
|
|
// first argument must evaluate to `false` at compile-time to maintain memory safety in release builds
|
|
assert(false, msg[0 .. index]);
|
|
}
|
|
|
|
/**
|
|
The compiler lowers expressions of `cast(TTo[])TFrom[]` to
|
|
this implementation. Note that this does not detect alignment problems.
|
|
|
|
Params:
|
|
from = the array to reinterpret-cast
|
|
|
|
Returns:
|
|
`from` reinterpreted as `TTo[]`
|
|
*/
|
|
TTo[] __ArrayCast(TFrom, TTo)(return scope TFrom[] from) @nogc pure @trusted
|
|
{
|
|
const fromSize = from.length * TFrom.sizeof;
|
|
const toLength = fromSize / TTo.sizeof;
|
|
|
|
if ((fromSize % TTo.sizeof) != 0)
|
|
{
|
|
onArrayCastError(TFrom.stringof, fromSize, from.length, TTo.stringof, TTo.sizeof);
|
|
}
|
|
|
|
struct Array
|
|
{
|
|
size_t length;
|
|
void* ptr;
|
|
}
|
|
auto a = cast(Array*)&from;
|
|
a.length = toLength; // jam new length
|
|
return *cast(TTo[]*)a;
|
|
}
|
|
|
|
@safe @nogc pure nothrow unittest
|
|
{
|
|
byte[int.sizeof * 3] b = cast(byte) 0xab;
|
|
int[] i;
|
|
short[] s;
|
|
|
|
i = __ArrayCast!(byte, int)(b);
|
|
assert(i.length == 3);
|
|
foreach (v; i)
|
|
assert(v == cast(int) 0xabab_abab);
|
|
|
|
s = __ArrayCast!(byte, short)(b);
|
|
assert(s.length == 6);
|
|
foreach (v; s)
|
|
assert(v == cast(short) 0xabab);
|
|
|
|
s = __ArrayCast!(int, short)(i);
|
|
assert(s.length == 6);
|
|
foreach (v; s)
|
|
assert(v == cast(short) 0xabab);
|
|
}
|
|
|
|
@system nothrow unittest
|
|
{
|
|
string msg;
|
|
try
|
|
{
|
|
auto str = "hello";
|
|
auto wstr = cast(wstring) str;
|
|
}
|
|
catch (Throwable t)
|
|
msg = t.msg;
|
|
|
|
static immutable expected = "`immutable(char)[]` of length 5 cannot be cast to `immutable(wchar)[]` as " ~
|
|
"its length in bytes (5) is not a multiple of `immutable(wchar).sizeof` (2).";
|
|
|
|
if (msg != expected)
|
|
{
|
|
import core.stdc.stdio : printf;
|
|
printf("Expected: |%.*s|\n", cast(int) expected.length, expected.ptr);
|
|
printf("Actual : |%.*s|\n", cast(int) msg.length, msg.ptr);
|
|
assert(false);
|
|
}
|
|
}
|