Add -disable-assert to disable the code generation of the built-in run-time 'assert' procedure

This commit is contained in:
gingerBill
2019-12-29 21:10:27 +00:00
parent 2d70a784d1
commit 2252d992d7
8 changed files with 48 additions and 2 deletions

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -55,6 +55,9 @@ enum EntityFlag {
EntityFlag_CVarArg = 1<<21,
EntityFlag_AutoCast = 1<<22,
EntityFlag_Disabled = 1<<24,
};
enum EntityState {

View File

@@ -3109,6 +3109,12 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, Array<irValue *> 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);

View File

@@ -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<String> 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<String> 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, "");