From 2252d992d79a39c0c9d1ad0eeb312b6e75195f8f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 29 Dec 2019 21:10:27 +0000 Subject: [PATCH] Add `-disable-assert` to disable the code generation of the built-in run-time 'assert' procedure --- core/runtime/core.odin | 7 +++++-- src/build_settings.cpp | 1 + src/check_decl.cpp | 10 ++++++++++ src/checker.cpp | 11 +++++++++++ src/checker.hpp | 2 ++ src/entity.cpp | 3 +++ src/ir.cpp | 6 ++++++ src/main.cpp | 10 ++++++++++ 8 files changed, 48 insertions(+), 2 deletions(-) diff --git a/core/runtime/core.odin b/core/runtime/core.odin index d09dfd72b..932a1fbd0 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -922,7 +922,8 @@ card :: proc(s: $S/bit_set[$E; $U]) -> int { @builtin -assert :: proc(condition: bool, message := "", loc := #caller_location) -> bool { +@(disabled=ODIN_DISABLE_ASSERT) +assert :: proc(condition: bool, message := "", loc := #caller_location) { if !condition { proc(message: string, loc: Source_Code_Location) { p := context.assertion_failure_proc; @@ -932,10 +933,10 @@ assert :: proc(condition: bool, message := "", loc := #caller_location) -> bool p("runtime assertion", message, loc); }(message, loc); } - return condition; } @builtin +@(disabled=ODIN_DISABLE_ASSERT) panic :: proc(message: string, loc := #caller_location) -> ! { p := context.assertion_failure_proc; if p == nil { @@ -945,6 +946,7 @@ panic :: proc(message: string, loc := #caller_location) -> ! { } @builtin +@(disabled=ODIN_DISABLE_ASSERT) unimplemented :: proc(message := "", loc := #caller_location) -> ! { p := context.assertion_failure_proc; if p == nil { @@ -954,6 +956,7 @@ unimplemented :: proc(message := "", loc := #caller_location) -> ! { } @builtin +@(disabled=ODIN_DISABLE_ASSERT) unreachable :: proc(message := "", loc := #caller_location) -> ! { p := context.assertion_failure_proc; if p == nil { diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 4b76106bd..046c3edab 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -91,6 +91,7 @@ struct BuildContext { String ODIN_VERSION; // compiler version String ODIN_ROOT; // Odin ROOT bool ODIN_DEBUG; // Odin in debug mode + bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not TargetEndianKind endian_kind; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index f59d072b7..0e669e473 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -675,6 +675,16 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { e->Procedure.is_export = ac.is_export; e->deprecated_message = ac.deprecated_message; ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix); + if (ac.has_disabled_proc) { + if (ac.disabled_proc) { + e->flags |= EntityFlag_Disabled; + } + Type *t = base_type(e->type); + GB_ASSERT(t->kind == Type_Proc); + if (t->Proc.result_count != 0) { + error(e->token, "Procedure with the 'disabled' attribute may not have any return values"); + } + } bool is_foreign = e->Procedure.is_foreign; bool is_export = e->Procedure.is_export; diff --git a/src/checker.cpp b/src/checker.cpp index 088f84e24..515df72f6 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -710,6 +710,7 @@ void init_universal(void) { add_global_string_constant(str_lit("ODIN_VERSION"), bc->ODIN_VERSION); add_global_string_constant(str_lit("ODIN_ROOT"), bc->ODIN_ROOT); add_global_constant(str_lit("ODIN_DEBUG"), t_untyped_bool, exact_value_bool(bc->ODIN_DEBUG)); + add_global_constant(str_lit("ODIN_DISABLE_ASSERT"), t_untyped_bool, exact_value_bool(bc->ODIN_DISABLE_ASSERT)); // Builtin Procedures @@ -2273,6 +2274,16 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) { } ac->require_results = true; return true; + } else if (name == "disabled") { + ExactValue ev = check_decl_attribute_value(c, value); + + if (ev.kind == ExactValue_Bool) { + ac->has_disabled_proc = true; + ac->disabled_proc = ev.value_bool; + } else { + error(elem, "Expected a boolean value for '%.*s'", LIT(name)); + } + return true; } return false; } diff --git a/src/checker.hpp b/src/checker.hpp index 9f6c54399..8ad0c0481 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -99,6 +99,8 @@ struct AttributeContext { bool is_static; bool require_results; bool force_foreign_import; + bool has_disabled_proc; + bool disabled_proc; String link_name; String link_prefix; isize init_expr_list_count; diff --git a/src/entity.cpp b/src/entity.cpp index 0c7bc8530..8273af3f1 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -55,6 +55,9 @@ enum EntityFlag { EntityFlag_CVarArg = 1<<21, EntityFlag_AutoCast = 1<<22, + + EntityFlag_Disabled = 1<<24, + }; enum EntityState { diff --git a/src/ir.cpp b/src/ir.cpp index 3be207e3e..dd9ba73cc 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3109,6 +3109,12 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, Array const &ar GB_ASSERT(pt->kind == Type_Proc); Type *results = pt->Proc.results; + if (p->entity != nullptr) { + if (p->entity->flags & EntityFlag_Disabled) { + return nullptr; + } + } + irValue *context_ptr = nullptr; if (pt->Proc.calling_convention == ProcCC_Odin) { context_ptr = ir_find_or_generate_context_ptr(p); diff --git a/src/main.cpp b/src/main.cpp index 19d13ff46..61ffd9eb7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -229,6 +229,7 @@ enum BuildFlagKind { BuildFlag_BuildMode, BuildFlag_Target, BuildFlag_Debug, + BuildFlag_DisableAssert, BuildFlag_NoBoundsCheck, BuildFlag_NoCRT, BuildFlag_UseLLD, @@ -318,6 +319,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String); add_flag(&build_flags, BuildFlag_Target, str_lit("target"), BuildFlagParam_String); add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None); + add_flag(&build_flags, BuildFlag_DisableAssert, str_lit("disable-assert"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None); @@ -669,6 +671,10 @@ bool parse_build_flags(Array args) { build_context.ODIN_DEBUG = true; break; + case BuildFlag_DisableAssert: + build_context.ODIN_DISABLE_ASSERT = true; + break; + case BuildFlag_NoBoundsCheck: build_context.no_bounds_check = true; break; @@ -1031,6 +1037,10 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(2, "Enabled debug information, and defines the global constant ODIN_DEBUG to be 'true'"); print_usage_line(0, ""); + print_usage_line(1, "-disable-assert"); + print_usage_line(2, "Disable the code generation of the built-in run-time 'assert' procedure, and defines the global constant ODIN_DISABLE_ASSERT to be 'true'"); + print_usage_line(0, ""); + print_usage_line(1, "-no-bounds-check"); print_usage_line(2, "Disables bounds checking program wide"); print_usage_line(0, "");