From 04bd8b21ee11f7ab16d8dc97c28a5b37365db89f Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Mon, 3 Jun 2024 14:07:03 +0100 Subject: [PATCH] Fix Bugzilla 24582 - Detect unsafe `cast(bool[])` Allow literal cast Make deprecation Add specific supplemental message --- compiler/src/dmd/safe.d | 8 ++++++++ compiler/test/fail_compilation/bool_cast.d | 15 +++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 compiler/test/fail_compilation/bool_cast.d diff --git a/compiler/src/dmd/safe.d b/compiler/src/dmd/safe.d index e28baf45ff5f..9a00d260f2d6 100644 --- a/compiler/src/dmd/safe.d +++ b/compiler/src/dmd/safe.d @@ -219,6 +219,14 @@ bool isSafeCast(Expression e, Type tfrom, Type tto, string* msg = null) return false; } + // For bool, only 0 and 1 are safe values + // Runtime array cast reinterprets data + if (ttobn.ty == Tbool && tfromn.ty != Tbool && e.op != EXP.arrayLiteral) + { + if (msg) + *msg = "Array data may have bytes which are not 0 or 1"; + } + // If the struct is opaque we don't know about the struct members then the cast becomes unsafe if (ttobn.ty == Tstruct && !(cast(TypeStruct)ttobn).sym.members || tfromn.ty == Tstruct && !(cast(TypeStruct)tfromn).sym.members) diff --git a/compiler/test/fail_compilation/bool_cast.d b/compiler/test/fail_compilation/bool_cast.d new file mode 100644 index 000000000000..6a0f537a6f97 --- /dev/null +++ b/compiler/test/fail_compilation/bool_cast.d @@ -0,0 +1,15 @@ +/* +REQUIRED_ARGS: -de +TEST_OUTPUT: +--- +fail_compilation/bool_cast.d(13): Deprecation: cast from `ubyte[]` to `bool[]` not allowed in safe code +fail_compilation/bool_cast.d(13): Array data may have bytes which are not 0 or 1 +--- +*/ + +void main() @safe +{ + ubyte[] a = [2, 4]; + auto b = cast(bool[]) a; // reinterprets a's data + auto c = cast(bool[]) [2, 4]; // literal cast applies to each element +}