mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-29 09:43:56 +00:00
Merge pull request #3832 from Feoramund/vet-identical-cast
Add `-vet-identical-cast`
This commit is contained in:
@@ -106,8 +106,8 @@ generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, times
|
||||
temporary: [2]u8
|
||||
bytes_generated := rand.read(temporary[:])
|
||||
assert(bytes_generated == 2, "RNG failed to generate 2 bytes for UUID v1.")
|
||||
result[8] |= cast(u8)temporary[0] & 0x3F
|
||||
result[9] = cast(u8)temporary[1]
|
||||
result[8] |= temporary[0] & 0x3F
|
||||
result[9] = temporary[1]
|
||||
}
|
||||
|
||||
if realized_node, ok := node.?; ok {
|
||||
|
||||
@@ -184,7 +184,7 @@ parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info:
|
||||
case 16: (cast(^u16) ptr)^ = cast(u16) value
|
||||
case 32: (cast(^u32) ptr)^ = cast(u32) value
|
||||
case 64: (cast(^u64) ptr)^ = cast(u64) value
|
||||
case 128: (cast(^u128) ptr)^ = cast(u128) value
|
||||
case 128: (cast(^u128) ptr)^ = value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -555,7 +555,7 @@ open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (Handle, Errno
|
||||
err := fchmod(handle, cast(u16)mode)
|
||||
if err != 0 {
|
||||
_unix_close(handle)
|
||||
return INVALID_HANDLE, cast(Errno)err
|
||||
return INVALID_HANDLE, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -742,10 +742,11 @@ enum VetFlags : u64 {
|
||||
VetFlag_UnusedVariables = 1u<<5,
|
||||
VetFlag_UnusedImports = 1u<<6,
|
||||
VetFlag_Deprecated = 1u<<7,
|
||||
VetFlag_IdenticalCast = 1u<<8,
|
||||
|
||||
VetFlag_Unused = VetFlag_UnusedVariables|VetFlag_UnusedImports,
|
||||
|
||||
VetFlag_All = VetFlag_Unused|VetFlag_Shadowing|VetFlag_UsingStmt|VetFlag_Deprecated,
|
||||
VetFlag_All = VetFlag_Unused|VetFlag_Shadowing|VetFlag_UsingStmt|VetFlag_Deprecated|VetFlag_IdenticalCast,
|
||||
|
||||
VetFlag_Using = VetFlag_UsingStmt|VetFlag_UsingParam,
|
||||
};
|
||||
@@ -769,6 +770,8 @@ u64 get_vet_flag_from_name(String const &name) {
|
||||
return VetFlag_Semicolon;
|
||||
} else if (name == "deprecated") {
|
||||
return VetFlag_Deprecated;
|
||||
} else if (name == "identical-cast") {
|
||||
return VetFlag_IdenticalCast;
|
||||
}
|
||||
return VetFlag_NONE;
|
||||
}
|
||||
|
||||
@@ -3310,7 +3310,7 @@ gb_internal bool check_cast_internal(CheckerContext *c, Operand *x, Type *type)
|
||||
|
||||
}
|
||||
|
||||
gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type) {
|
||||
gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type, bool forbid_identical = false) {
|
||||
if (!is_operand_value(*x)) {
|
||||
error(x->expr, "Only values can be casted");
|
||||
x->mode = Addressing_Invalid;
|
||||
@@ -3382,6 +3382,25 @@ gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type) {
|
||||
add_package_dependency(c, "runtime", "gnu_f2h_ieee", REQUIRE);
|
||||
}
|
||||
}
|
||||
if (forbid_identical && check_vet_flags(c) & VetFlag_IdenticalCast) {
|
||||
Type *src_exact = x->type;
|
||||
Type *dst_exact = type;
|
||||
|
||||
if (src_exact != nullptr &&
|
||||
dst_exact != nullptr &&
|
||||
// If we check polymorphic procedures, we risk erring on
|
||||
// identical casts that cannot be foreseen or otherwise
|
||||
// forbidden, so just skip them.
|
||||
(c->curr_proc_sig == nullptr || !is_type_polymorphic(c->curr_proc_sig)) &&
|
||||
src_exact == dst_exact)
|
||||
{
|
||||
gbString oper_str = expr_to_string(x->expr);
|
||||
gbString to_type = type_to_string(dst_exact);
|
||||
error(x->expr, "Unneeded cast of `%s` to identical type `%s`", oper_str, to_type);
|
||||
gb_string_free(oper_str);
|
||||
gb_string_free(to_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x->type = type;
|
||||
@@ -10718,7 +10737,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast
|
||||
check_transmute(c, node, o, type);
|
||||
break;
|
||||
case Token_cast:
|
||||
check_cast(c, o, type);
|
||||
check_cast(c, o, type, true);
|
||||
break;
|
||||
default:
|
||||
error(node, "Invalid AST: Invalid casting expression");
|
||||
|
||||
@@ -300,6 +300,7 @@ enum BuildFlagKind {
|
||||
BuildFlag_VetUsingParam,
|
||||
BuildFlag_VetStyle,
|
||||
BuildFlag_VetSemicolon,
|
||||
BuildFlag_VetIdenticalCast,
|
||||
|
||||
BuildFlag_CustomAttribute,
|
||||
BuildFlag_IgnoreUnknownAttributes,
|
||||
@@ -499,6 +500,7 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
add_flag(&build_flags, BuildFlag_VetUsingParam, str_lit("vet-using-param"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_VetStyle, str_lit("vet-style"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_VetSemicolon, str_lit("vet-semicolon"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_VetIdenticalCast, str_lit("vet-identical-cast"), 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);
|
||||
@@ -1152,6 +1154,7 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
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_VetIdenticalCast: build_context.vet_flags |= VetFlag_IdenticalCast; break;
|
||||
|
||||
case BuildFlag_CustomAttribute:
|
||||
{
|
||||
@@ -2243,6 +2246,10 @@ gb_internal void print_show_help(String const arg0, String const &command) {
|
||||
print_usage_line(1, "-vet-semicolon");
|
||||
print_usage_line(2, "Errs on unneeded semicolons.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-vet-identical-cast");
|
||||
print_usage_line(2, "Errs on casting a value to its own type.");
|
||||
print_usage_line(0, "");
|
||||
}
|
||||
|
||||
if (check) {
|
||||
|
||||
Reference in New Issue
Block a user