소스 검색

Merge pull request #5081 from Lperlind/vet-explicit-allocators

Add -vet-explicit-allocators
gingerBill 5 일 전
부모
커밋
513e6daace
3개의 변경된 파일38개의 추가작업 그리고 7개의 파일을 삭제
  1. 3 0
      src/build_settings.cpp
  2. 30 7
      src/check_expr.cpp
  3. 5 0
      src/parser.cpp

+ 3 - 0
src/build_settings.cpp

@@ -309,6 +309,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,
 
@@ -342,6 +343,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
src/check_expr.cpp

@@ -6245,20 +6245,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) {

+ 5 - 0
src/parser.cpp

@@ -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;
@@ -6356,6 +6360,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;
 		}
 	}