mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-31 11:50:07 +00:00
Add -vet-explicit-allocators
This vet flag will make it so that allocators must be explicitly used in places where context.allocator and context.temp_allocator are a procedure parameter. The goal of this flag is to prevent using the context.allocator in cases where a different allocator was meant to be used. Some code bases default context.allocator to nil/panic allocator to catch this at runtime. This effectively makes it a compile time error instead.
This commit is contained in:
@@ -305,6 +305,7 @@ enum VetFlags : u64 {
|
||||
VetFlag_Cast = 1u<<8,
|
||||
VetFlag_Tabs = 1u<<9,
|
||||
VetFlag_UnusedProcedures = 1u<<10,
|
||||
VetFlag_ExplicitAllocators = 1u<<11,
|
||||
|
||||
VetFlag_Unused = VetFlag_UnusedVariables|VetFlag_UnusedImports,
|
||||
|
||||
@@ -338,6 +339,8 @@ u64 get_vet_flag_from_name(String const &name) {
|
||||
return VetFlag_Tabs;
|
||||
} else if (name == "unused-procedures") {
|
||||
return VetFlag_UnusedProcedures;
|
||||
} else if (name == "explicit-allocators") {
|
||||
return VetFlag_ExplicitAllocators;
|
||||
}
|
||||
return VetFlag_NONE;
|
||||
}
|
||||
|
||||
+30
-7
@@ -6253,20 +6253,43 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
|
||||
for (isize i = 0; i < pt->param_count; i++) {
|
||||
if (!visited[i]) {
|
||||
Entity *e = pt->params->Tuple.variables[i];
|
||||
bool context_allocator_error = false;
|
||||
if (e->kind == Entity_Variable) {
|
||||
if (e->Variable.param_value.kind != ParameterValue_Invalid) {
|
||||
ordered_operands[i].mode = Addressing_Value;
|
||||
ordered_operands[i].type = e->type;
|
||||
ordered_operands[i].expr = e->Variable.param_value.original_ast_expr;
|
||||
if (ast_file_vet_explicit_allocators(c->file)) {
|
||||
// NOTE(lucas): check if we are trying to default to context.allocator or context.temp_allocator
|
||||
if (e->Variable.param_value.original_ast_expr->kind == Ast_SelectorExpr) {
|
||||
auto& expr = e->Variable.param_value.original_ast_expr->SelectorExpr.expr;
|
||||
auto& selector = e->Variable.param_value.original_ast_expr->SelectorExpr.selector;
|
||||
if (expr->kind == Ast_Implicit &&
|
||||
expr->Implicit.string == STR_LIT("context") &&
|
||||
selector->kind == Ast_Ident &&
|
||||
(selector->Ident.token.string == STR_LIT("allocator") ||
|
||||
selector->Ident.token.string == STR_LIT("temp_allocator"))) {
|
||||
context_allocator_error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dummy_argument_count += 1;
|
||||
score += assign_score_function(1);
|
||||
continue;
|
||||
if (!context_allocator_error) {
|
||||
ordered_operands[i].mode = Addressing_Value;
|
||||
ordered_operands[i].type = e->type;
|
||||
ordered_operands[i].expr = e->Variable.param_value.original_ast_expr;
|
||||
|
||||
dummy_argument_count += 1;
|
||||
score += assign_score_function(1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (show_error) {
|
||||
if (e->kind == Entity_TypeName) {
|
||||
if (context_allocator_error) {
|
||||
gbString str = type_to_string(e->type);
|
||||
error(call, "Parameter '%.*s' of type '%s' must be explicitly provided in procedure call",
|
||||
LIT(e->token.string), str);
|
||||
gb_string_free(str);
|
||||
} else if (e->kind == Entity_TypeName) {
|
||||
error(call, "Type parameter '%.*s' is missing in procedure call",
|
||||
LIT(e->token.string));
|
||||
} else if (e->kind == Entity_Constant && e->Constant.value.kind != ExactValue_Invalid) {
|
||||
|
||||
+16
-10
@@ -346,6 +346,7 @@ enum BuildFlagKind {
|
||||
BuildFlag_VetCast,
|
||||
BuildFlag_VetTabs,
|
||||
BuildFlag_VetPackages,
|
||||
BuildFlag_VetExplicitAllocators,
|
||||
|
||||
BuildFlag_CustomAttribute,
|
||||
BuildFlag_IgnoreUnknownAttributes,
|
||||
@@ -565,6 +566,7 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
add_flag(&build_flags, BuildFlag_VetCast, str_lit("vet-cast"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_VetTabs, str_lit("vet-tabs"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_VetPackages, str_lit("vet-packages"), BuildFlagParam_String, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_VetExplicitAllocators, str_lit("vet-explicit-allocators"), BuildFlagParam_None, Command__does_check);
|
||||
|
||||
add_flag(&build_flags, BuildFlag_CustomAttribute, str_lit("custom-attribute"), BuildFlagParam_String, Command__does_check, true);
|
||||
add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None, Command__does_check);
|
||||
@@ -1276,16 +1278,17 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
build_context.vet_flags |= VetFlag_All;
|
||||
break;
|
||||
|
||||
case BuildFlag_VetUnusedVariables: build_context.vet_flags |= VetFlag_UnusedVariables; break;
|
||||
case BuildFlag_VetUnusedImports: build_context.vet_flags |= VetFlag_UnusedImports; break;
|
||||
case BuildFlag_VetUnused: build_context.vet_flags |= VetFlag_Unused; break;
|
||||
case BuildFlag_VetShadowing: build_context.vet_flags |= VetFlag_Shadowing; break;
|
||||
case BuildFlag_VetUsingStmt: build_context.vet_flags |= VetFlag_UsingStmt; break;
|
||||
case BuildFlag_VetUsingParam: build_context.vet_flags |= VetFlag_UsingParam; break;
|
||||
case BuildFlag_VetStyle: build_context.vet_flags |= VetFlag_Style; break;
|
||||
case BuildFlag_VetSemicolon: build_context.vet_flags |= VetFlag_Semicolon; break;
|
||||
case BuildFlag_VetCast: build_context.vet_flags |= VetFlag_Cast; break;
|
||||
case BuildFlag_VetTabs: build_context.vet_flags |= VetFlag_Tabs; break;
|
||||
case BuildFlag_VetUnusedVariables: build_context.vet_flags |= VetFlag_UnusedVariables; break;
|
||||
case BuildFlag_VetUnusedImports: build_context.vet_flags |= VetFlag_UnusedImports; break;
|
||||
case BuildFlag_VetUnused: build_context.vet_flags |= VetFlag_Unused; break;
|
||||
case BuildFlag_VetShadowing: build_context.vet_flags |= VetFlag_Shadowing; break;
|
||||
case BuildFlag_VetUsingStmt: build_context.vet_flags |= VetFlag_UsingStmt; break;
|
||||
case BuildFlag_VetUsingParam: build_context.vet_flags |= VetFlag_UsingParam; break;
|
||||
case BuildFlag_VetStyle: build_context.vet_flags |= VetFlag_Style; break;
|
||||
case BuildFlag_VetSemicolon: build_context.vet_flags |= VetFlag_Semicolon; break;
|
||||
case BuildFlag_VetCast: build_context.vet_flags |= VetFlag_Cast; break;
|
||||
case BuildFlag_VetTabs: build_context.vet_flags |= VetFlag_Tabs; break;
|
||||
case BuildFlag_VetExplicitAllocators: build_context.vet_flags |= VetFlag_ExplicitAllocators; break;
|
||||
case BuildFlag_VetUnusedProcedures:
|
||||
build_context.vet_flags |= VetFlag_UnusedProcedures;
|
||||
if (!set_flags[BuildFlag_VetPackages]) {
|
||||
@@ -2841,6 +2844,9 @@ gb_internal void print_show_help(String const arg0, String command, String optio
|
||||
print_usage_line(2, "Checks for the use of 'using' as a statement.");
|
||||
print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring.");
|
||||
}
|
||||
if (print_flag("-vet-explicit-allocators")) {
|
||||
print_usage_line(2, "Checks for the use of allocators being explicitely passed to a procedure.");
|
||||
}
|
||||
}
|
||||
|
||||
if (check) {
|
||||
|
||||
@@ -33,6 +33,10 @@ gb_internal bool ast_file_vet_deprecated(AstFile *f) {
|
||||
return (ast_file_vet_flags(f) & VetFlag_Deprecated) != 0;
|
||||
}
|
||||
|
||||
gb_internal bool ast_file_vet_explicit_allocators(AstFile *f) {
|
||||
return (ast_file_vet_flags(f) & VetFlag_ExplicitAllocators) != 0;
|
||||
}
|
||||
|
||||
gb_internal bool file_allow_newline(AstFile *f) {
|
||||
bool is_strict = build_context.strict_style || ast_file_vet_style(f);
|
||||
return !is_strict;
|
||||
@@ -6325,6 +6329,7 @@ gb_internal u64 parse_vet_tag(Token token_for_pos, String s) {
|
||||
error_line("\textra\n");
|
||||
error_line("\tcast\n");
|
||||
error_line("\ttabs\n");
|
||||
error_line("\texplicit-allocators\n");
|
||||
return build_context.vet_flags;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user