diff --git a/releasenotes.md b/releasenotes.md index 13b5d212c..4de0cfcb6 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -108,6 +108,7 @@ - Add deprecation for `@param foo "abc"`. - Add `--header-output` and `header-output` options for controlling header output folder. - Generic faults is disallowed. +- Detect when a slice on the stack is accidentally returned from a function. ### Fixes - Assert triggered when casting from `int[2]` to `uint[2]` #2115 diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 617da0b32..ed27d70ea 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -600,6 +600,13 @@ INLINE bool sema_check_not_stack_variable_escape(SemaContext *context, Expr *exp Expr *outer = expr; expr = sema_dive_into_expression(expr); bool allow_pointer = false; + if (expr_is_const_slice(expr) && expr->const_expr.slice_init) + { + RETURN_SEMA_ERROR(outer, "A slice literal is backed by a stack allocated array which will be invalid once the function returns. " + "However, you can place the literal in a global or 'static' variable and safely return that value as long " + "as the caller of the function won't modify the slice."); + + } // We only want && and & if (expr->expr_kind == EXPR_SUBSCRIPT_ADDR) { diff --git a/test/test_suite/arrays/slice_literal_fn_return.c3 b/test/test_suite/arrays/slice_literal_fn_return.c3 new file mode 100644 index 000000000..c98d2585f --- /dev/null +++ b/test/test_suite/arrays/slice_literal_fn_return.c3 @@ -0,0 +1,9 @@ +import std; +fn int[] hello() +{ + return { 1, 2 }; // #error: will be invalid +} +fn void main() +{ + hello(); +} \ No newline at end of file