Fix transmute_undefined_repr with single field #[repr(C)] structs

This commit is contained in:
Jason Newcomb 2022-02-13 13:22:17 -05:00
parent c37d6eed06
commit 662df33e97
6 changed files with 14 additions and 7 deletions

View file

@ -277,6 +277,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
LintId::of(transmute::TRANSMUTE_NUM_TO_BYTES),
LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
LintId::of(transmute::WRONG_TRANSMUTE),
LintId::of(transmuting_null::TRANSMUTING_NULL),

View file

@ -58,6 +58,7 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
LintId::of(swap::ALMOST_SWAPPED),
LintId::of(to_string_in_display::TO_STRING_IN_DISPLAY),
LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
LintId::of(transmute::WRONG_TRANSMUTE),
LintId::of(transmuting_null::TRANSMUTING_NULL),

View file

@ -26,7 +26,6 @@ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
LintId::of(strings::STRING_LIT_AS_BYTES),
LintId::of(suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS),
LintId::of(trailing_empty_array::TRAILING_EMPTY_ARRAY),
LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
LintId::of(transmute::USELESS_TRANSMUTE),
LintId::of(use_self::USE_SELF),
])

View file

@ -358,7 +358,8 @@ declare_clippy_lint! {
declare_clippy_lint! {
/// ### What it does
/// Checks for transmutes either to or from a type which does not have a defined representation.
/// Checks for transmutes between types which do not have a representation defined relative to
/// each other.
///
/// ### Why is this bad?
/// The results of such a transmute are not defined.
@ -376,7 +377,7 @@ declare_clippy_lint! {
/// ```
#[clippy::version = "1.60.0"]
pub TRANSMUTE_UNDEFINED_REPR,
nursery,
correctness,
"transmute to or from a type with an undefined representation"
}

View file

@ -255,9 +255,6 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
ReducedTy::UnorderedFields(ty)
},
ty::Adt(def, substs) if def.is_struct() => {
if def.repr.inhibit_struct_field_reordering_opt() {
return ReducedTy::OrderedFields(ty);
}
let mut iter = def
.non_enum_variant()
.fields
@ -270,7 +267,11 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
ty = sized_ty;
continue;
}
ReducedTy::UnorderedFields(ty)
if def.repr.inhibit_struct_field_reordering_opt() {
ReducedTy::OrderedFields(ty)
} else {
ReducedTy::UnorderedFields(ty)
}
},
ty::Ref(..) | ty::RawPtr(_) => ReducedTy::Ref(ty),
_ => ReducedTy::Other(ty),

View file

@ -40,5 +40,9 @@ fn main() {
let _: Ty<[u8; 8]> = core::mem::transmute(value::<Ty2<u32, i32>>()); // Ok, transmute to byte array
let _: Ty2<u32, i32> = core::mem::transmute(value::<Ty<[u8; 8]>>()); // Ok, transmute from byte array
// issue #8417
let _: Ty2C<Ty2<u32, i32>, ()> = core::mem::transmute(value::<Ty2<u32, i32>>()); // Ok, Ty2 types are the same
let _: Ty2<u32, i32> = core::mem::transmute(value::<Ty2C<Ty2<u32, i32>, ()>>()); // Ok, Ty2 types are the same
}
}