diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 6343703fd..f3ad5a7a1 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -2531,7 +2531,17 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de } check_close_scope(ctx); - check_proc_escapes(type, body); + // the entry point of an executable only returns as the program ends + bool is_entry_point = false; + if (build_context.build_mode == BuildMode_Executable && + !build_context.no_entry_point && + build_context.command_kind != Command_test) { + Entity *proc_entity = decl->entity.load(); + is_entry_point = proc_entity != nullptr && proc_entity == ctx->info->entry_point; + } + if (!is_entry_point) { + check_proc_escapes(type, body); + } check_scope_usage(ctx->checker, ctx->scope, check_vet_flags(body)); diff --git a/src/check_escape.cpp b/src/check_escape.cpp index b85b67feb..47ceebecb 100644 --- a/src/check_escape.cpp +++ b/src/check_escape.cpp @@ -1142,7 +1142,19 @@ gb_internal void escape_report(EscapeAnalysis *ea, Ast *node, String expr_str, E GB_PANIC("Unhandled EscapeReportKind"); break; } - error_line("\tSuggestion: If this is intended, make it explicit with a conversion to 'rawptr' or 'uintptr', or a 'transmute'\n"); + + if (kind == EscapeReport_Store) { + char const *zero = "{}"; + Type *t = node->tav.type; + if (t != nullptr && type_has_nil(t)) { + zero = "nil"; + } else if (t != nullptr && is_type_string(t)) { + zero = "\"\""; + } + error_line("\tSuggestion: Clear it before the procedure returns, e.g. 'defer %.*s = %s'\n", LIT(expr_str), zero); + } else { + error_line("\tSuggestion: If this is intended, make it explicit with a conversion to 'rawptr' or 'uintptr', or a 'transmute'\n"); + } } gb_internal void escape_report_value(EscapeAnalysis *ea, Ast *node, Ast *expr, String name, EscapeValue const &v) {