diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 790f7f1bc..62f43fad3 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -278,6 +278,7 @@ struct BuildContext { bool copy_file_contents; RelocMode reloc_mode; + bool disable_red_zone; u32 cmd_doc_flags; @@ -1002,6 +1003,13 @@ void init_build_context(TargetMetrics *cross_target) { bc->threaded_checker = true; #endif + if (bc->disable_red_zone) { + if (!(bc->metrics.os == TargetOs_freestanding && !is_arch_wasm())) { + gb_printf_err("-disable-red-zone is not support for this target"); + gb_exit(1); + } + } + // NOTE(zangent): The linker flags to set the build architecture are different // across OSs. It doesn't make sense to allocate extra data on the heap diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 6f8caff98..45d741532 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -826,14 +826,6 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode; - if (ac.no_red_zone) { - if (!is_arch_wasm()) { - e->Procedure.no_red_zone = true; - } else { - error(e->token, "@(no_red_zone) is not supported on this target architecture"); - } - } - if (ac.objc_name.len || ac.objc_is_class_method || ac.objc_type) { if (ac.objc_name.len == 0 && ac.objc_is_class_method) { error(e->token, "@(objc_name) is required with @(objc_is_class_method)"); diff --git a/src/checker.cpp b/src/checker.cpp index 89e60c258..fe1d362fa 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3128,13 +3128,6 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) { } } return true; - } else if (name == "no_red_zone") { - if (value != nullptr) { - error(elem, "Expected no value for '%.*s'", LIT(name)); - } else { - ac->no_red_zone = true; - } - return true; } return false; } diff --git a/src/checker.hpp b/src/checker.hpp index 548439774..552e6aca7 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -117,7 +117,6 @@ struct AttributeContext { bool test : 1; bool init : 1; bool set_cold : 1; - bool no_red_zone : 1; u32 optimization_mode; // ProcedureOptimizationMode String objc_class; diff --git a/src/entity.cpp b/src/entity.cpp index 84ddd5c6b..f5720293f 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -226,7 +226,6 @@ struct Entity { bool is_foreign; bool is_export; bool generated_from_polymorphic; - bool no_red_zone; ProcedureOptimizationMode optimization_mode; } Procedure; struct { diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 209f2f67b..053ee2fb2 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -135,7 +135,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) lb_add_attribute_to_proc(m, p->value, "naked"); } - if (entity->Procedure.no_red_zone) { + if (!entity->Procedure.is_foreign && build_context.disable_red_zone) { lb_add_attribute_to_proc(m, p->value, "noredzone"); } diff --git a/src/main.cpp b/src/main.cpp index cfc7decb1..1e7b78da4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -626,6 +626,7 @@ enum BuildFlagKind { BuildFlag_Microarch, BuildFlag_RelocMode, + BuildFlag_DisableRedZone, BuildFlag_TestName, @@ -782,6 +783,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_Microarch, str_lit("microarch"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_RelocMode, str_lit("reloc-mode"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_DisableRedZone, str_lit("disable-red-zone"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_TestName, str_lit("test-name"), BuildFlagParam_String, Command_test); @@ -1365,6 +1367,9 @@ bool parse_build_flags(Array args) { break; } + case BuildFlag_DisableRedZone: + build_context.disable_red_zone = true; + break; case BuildFlag_TestName: { GB_ASSERT(value.kind == ExactValue_String); { @@ -2096,6 +2101,9 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(3, "pic"); print_usage_line(3, "dynamic-no-pic"); print_usage_line(0, ""); + + print_usage_line(1, "-disable-red-zone"); + print_usage_line(2, "Disable red zone on a supported freestanding target"); } if (check) {