From ad3cd883505cba9a12ef93908195a02c7a948c91 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 20 Jan 2025 16:26:26 +0100 Subject: [PATCH] Fix dues to crash when converting a const vector to another vector #1864. --- releasenotes.md | 1 + src/compiler/sema_casts.c | 11 ++++++++++- test/test_suite/vector/vector_to_array_fail.c3 | 2 +- test/test_suite/vector/vector_to_vector_const_fail.c3 | 5 +++++ 4 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 test/test_suite/vector/vector_to_vector_const_fail.c3 diff --git a/releasenotes.md b/releasenotes.md index f3346c416..c010d1a52 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -14,6 +14,7 @@ - Const strings and bytes were not properly converted to compile time bools. - Concatenating a const empty slice with another array caused a null pointer access. - Fix `linux-crt` and `linux-crtbegin` not getting recognized as a project paramater +- Fix dues to crash when converting a const vector to another vector #1864. ### Stdlib changes - Added '%h' and '%H' for printing out binary data in hexadecimal using the formatter. diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 3cdeb1ab0..ece34f986 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -1286,11 +1286,20 @@ static bool rule_vec_to_vec(CastContext *cc, bool is_explicit, bool is_silent) { if (cc->from->array.len != cc->to->array.len) return sema_cast_error(cc, false, is_silent); Type *from_base = cc->from->array.base; + CastContext cc_copy = *cc; cast_context_set_to(cc, cc->to->array.base); // Allow bool vectors to expand to any int. if (from_base == type_bool && cc->to_group == CONV_INT) return true; + // Create a fake expression that can't be folded for some checking if the + // the elements could be cast. + Expr temp = { .expr_kind = EXPR_EXPR_BLOCK, .type = from_base, .span = cc->expr->span, .resolve_status = RESOLVE_DONE }; + cc->expr = &temp; cast_context_set_from(cc, from_base); - return cast_is_allowed(cc, is_explicit, is_silent); + bool success = cast_is_allowed(cc, is_explicit, true); + *cc = cc_copy; + if (is_silent) return success; + if (success) return true; + return sema_cast_error(cc, is_explicit ? false : rule_vec_to_vec(cc, true, true), false); } static bool rule_expand_to_vec(CastContext *cc, bool is_explicit, bool is_silent) diff --git a/test/test_suite/vector/vector_to_array_fail.c3 b/test/test_suite/vector/vector_to_array_fail.c3 index 2fc0c366d..1635a9403 100644 --- a/test/test_suite/vector/vector_to_array_fail.c3 +++ b/test/test_suite/vector/vector_to_array_fail.c3 @@ -9,5 +9,5 @@ fn void main() int[<*>] z = x; int[<*>] w = y; double[<2>] ww = x; - short[<2>] www = y; // #error: implicitly be converted + short[<2>] www = y; // #error: Implicitly casting 'int[2]' to 'short[<2>]' } \ No newline at end of file diff --git a/test/test_suite/vector/vector_to_vector_const_fail.c3 b/test/test_suite/vector/vector_to_vector_const_fail.c3 new file mode 100644 index 000000000..bd595d27d --- /dev/null +++ b/test/test_suite/vector/vector_to_vector_const_fail.c3 @@ -0,0 +1,5 @@ +fn int main(String[] args) +{ + const double[4] ONE = { 1.0, 1.0, 1.0, 1.0 }; + float[<4>] vec4 = ONE; // #error: Implicitly casting 'double[4]' to 'float[<4>]' +} \ No newline at end of file