From 6784db9f8631d84a54ed595ef3963e0f3d09fdd1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 7 Oct 2026 20:56:04 +0100 Subject: [PATCH] Add `-no-escape-analysis`, which cannot be used with `-vet-nil-deref` or `-vet-uninitialized` --- src/build_settings.cpp | 1 + src/check_expr.cpp | 2 +- src/checker.cpp | 10 +++++++--- src/main.cpp | 17 +++++++++++++++++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 2d9eddfcd..510bc402b 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -563,6 +563,7 @@ struct BuildContext { bool no_crt; bool no_rpath; bool no_entry_point; + bool no_escape_analysis; bool no_thread_local; bool cross_compiling; bool different_os; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index bf8497aac..bdf44f08c 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -9562,7 +9562,7 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c c->decl->defer_used += 1; } } - if (c->curr_proc_decl != nullptr) { + if (c->curr_proc_decl != nullptr && !build_context.no_escape_analysis) { per_thread_array_add(&c->info->checked_calls_queue, CheckedCall{c->curr_proc_decl, callee}); } } diff --git a/src/checker.cpp b/src/checker.cpp index a1ef18ab7..ae7a0ea86 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -6852,7 +6852,9 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u if (body_was_checked) { pi->decl->proc_info = pi; - per_thread_array_add(&c->info.checked_bodies_queue, pi); + if (!build_context.no_escape_analysis) { + per_thread_array_add(&c->info.checked_bodies_queue, pi); + } pi->decl->proc_checked_state.store(ProcCheckedState_Checked); if (pi->body) { Entity *e = pi->decl->entity; @@ -8072,8 +8074,10 @@ gb_internal void check_parsed_files(Checker *c) { debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); - TIME_SECTION("check escapes"); - check_escapes(c); + if (!build_context.no_escape_analysis) { + TIME_SECTION("check escapes"); + check_escapes(c); + } TIME_SECTION("check unique link names"); check_link_name_uses(c); diff --git a/src/main.cpp b/src/main.cpp index e6f951c9e..593914a15 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -430,6 +430,7 @@ enum BuildFlagKind { BuildFlag_NoCRT, BuildFlag_NoRPath, BuildFlag_NoEntryPoint, + BuildFlag_NoEscapeAnalysis, BuildFlag_Linker, BuildFlag_UseSeparateModules, BuildFlag_UseSingleModule, @@ -703,6 +704,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_NoRPath, str_lit("no-rpath"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test); + add_flag(&build_flags, BuildFlag_NoEscapeAnalysis, str_lit("no-escape-analysis"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_Linker, str_lit("linker"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_UseSeparateModules, str_lit("use-separate-modules"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_UseSingleModule, str_lit("use-single-module"), BuildFlagParam_None, Command__does_build); @@ -1426,6 +1428,9 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_NoEntryPoint: build_context.no_entry_point = true; break; + case BuildFlag_NoEscapeAnalysis: + build_context.no_escape_analysis = true; + break; case BuildFlag_NoThreadLocal: build_context.no_thread_local = true; break; @@ -2077,6 +2082,11 @@ gb_internal bool parse_build_flags(Array args) { bad_flags = true; } + if (set_flags[BuildFlag_NoEscapeAnalysis] && (set_flags[BuildFlag_VetNilDeref] || set_flags[BuildFlag_VetUninitialized])) { + gb_printf_err("-vet-nil-deref and -vet-uninitialized cannot be used with -no-escape-analysis, as they are part of it\n"); + bad_flags = true; + } + if ((!(build_context.export_timings_format == TimingsExportUnspecified)) && (build_context.export_timings_file.len == 0)) { gb_printf_err("`-export-timings:` requires `-export-timings-file:` to be specified as well\n"); bad_flags = true; @@ -3257,6 +3267,13 @@ gb_internal int print_show_help(String const arg0, String command, String option } } + if (check) { + if (print_flag("-no-escape-analysis")) { + print_usage_line(2, "Disables the escape analysis of stack memory, including the error for returning the address of a local."); + print_usage_line(2, "Cannot be used with -vet-nil-deref or -vet-uninitialized."); + } + } + if (run_or_build) { if (print_flag("-no-rpath")) { print_usage_line(2, "Disables automatic addition of an rpath linked to the executable directory.");