mirror of
https://github.com/odin-lang/Odin.git
synced 2026-10-09 06:12:05 -04:00
Skip the escape analysis for an executable's entry point, suggest clearing stores, and add type_zero_value_string
This commit is contained in:
1 parent
5522d18745
commit
edeca40dd6
3 files changed
+51
-25
No files matched your search
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user