Skip the escape analysis for an executable's entry point, suggest clearing stores, and add type_zero_value_string

This commit is contained in:
gingerBill committed 2026-10-07 13:41:32 +01:00
1 parent 5522d18745
commit edeca40dd6
3 files changed
+51 -25

No files matched your search

+1 -8
View File
@@ -1144,14 +1144,7 @@ gb_internal void escape_report(EscapeAnalysis *ea, Ast *node, String expr_str, E
}
if (kind == EscapeReport_Store) {
char const *zero = "{}";
Type *t = node->tav.type;
if (t != nullptr && type_has_nil(t)) {
zero = "nil";
} else if (t != nullptr && is_type_string(t)) {
zero = "\"\"";
}
error_line("\tSuggestion: Clear it before the procedure returns, e.g. 'defer %.*s = %s'\n", LIT(expr_str), zero);
error_line("\tSuggestion: Clear it before the procedure returns, e.g. 'defer %.*s = %s'\n", LIT(expr_str), type_zero_value_string(node->tav.type));
} else {
error_line("\tSuggestion: If this is intended, make it explicit with a conversion to 'rawptr' or 'uintptr', or a 'transmute'\n");
}
+1 -17
View File
@@ -2741,23 +2741,7 @@ gb_internal char const *zero_value_suggestion(Operand *o, Type *type) {
if (!is_exact_value_zero(o->value)) {
return nullptr;
}
char const *suggestion = nullptr;
if (is_type_string(type)) {
suggestion = "\"\"";
} else if (is_type_boolean(type)) {
suggestion = "false";
} else if (is_type_bit_set(type)) {
// A bit_set accepts both `nil` and `{}`. `{}` is a bit more idiomatic
// because `{.Something}` becomes `{}` when no bits are set.
suggestion = "{}";
} else if (type_has_nil(type)) {
suggestion = "nil";
} else {
suggestion = "{}";
}
return suggestion;
return type_zero_value_string(type);
}
gb_internal void check_assignment_error_suggestion(CheckerContext *c, Operand *o, Type *type, i64 max_bit_size) {
+49
View File
@@ -2753,6 +2753,55 @@ gb_internal bool type_has_nil(Type *t) {
return false;
}
gb_internal char const *type_zero_value_string(Type *t) {
t = base_type(t);
if (t == nullptr) {
return "{}";
}
switch (t->kind) {
case Type_Basic:
switch (t->Basic.kind) {
case Basic_string:
case Basic_string16:
case Basic_UntypedString:
return "\"\"";
case Basic_rawptr:
case Basic_cstring:
case Basic_cstring16:
case Basic_any:
case Basic_typeid:
case Basic_UntypedNil:
return "nil";
}
if (t->Basic.flags & BasicFlag_Boolean) {
return "false";
}
if (t->Basic.flags & (BasicFlag_Numeric|BasicFlag_Rune)) {
return "0";
}
return "{}";
case Type_Pointer:
case Type_MultiPointer:
case Type_SoaPointer:
case Type_Slice:
case Type_DynamicArray:
case Type_Map:
case Type_Proc:
return "nil";
case Type_Union:
case Type_Struct:
// a union without #no_nil, or a #soa slice or dynamic array
if (type_has_nil(t)) {
return "nil";
}
return "{}";
}
// an enum or bit_set may also be 'nil', but '{}' reads better
return "{}";
}
gb_internal bool is_type_union_constantable(Type *type);
gb_internal bool is_type_constant_type_for_unions(Type *t) {