-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Open
Labels
Description
Rust has a concept of data-carrying enums, where variants aren't just integer values, but composite types. They look like:
pub enum DataCarryingEnum {
First { a: u32, b: i32 },
Second(u32, i32),
Third(u32),
}
This type's debug info is the following DICompositeType
with DW_TAG_structure_type
tag:
!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "DataCarryingEnum", scope: !2, file: !5, size: 96, align: 32, flags: DIFlagPublic, elements: !6, templateParams: !16, identifier: "2bc4a1fe2282cdc6dd55af802fccb261")
With one element being also a DICompositeType
, but with DW_TAG_variant_part
tag:
!6 = !{!7}
!7 = !DICompositeType(tag: DW_TAG_variant_part, scope: !4, file: !5, size: 96, align: 32, elements: !8, templateParams: !16, identifier: "6c4a6a604e3dcbb53b9dbd2113a7a3e2", discriminator: !26)
Which then holds different variants as DIDerivedType
elements with DW_TAG_member
tag:
!8 = !{!9, !17, !22}
!9 = !DIDerivedType(tag: DW_TAG_member, name: "First", scope: !7, file: !5, baseType: !10, size: 96, align: 32, extraData: i32 0)
!10 = !DICompositeType(tag: DW_TAG_structure_type, name: "First", scope: !4, file: !5, size: 96, align: 32, flags: DIFlagPublic, elements: !11, templateParams: !16, identifier: "d02872fc81dfee23fe3b1b59ad9887b8")
!11 = !{!12, !14}
!12 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !10, file: !5, baseType: !13, size: 32, align: 32, offset: 32, flags: DIFlagPublic)
!13 = !DIBasicType(name: "u32", size: 32, encoding: DW_ATE_unsigned)
!14 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !10, file: !5, baseType: !15, size: 32, align: 32, offset: 64, flags: DIFlagPublic)
!15 = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed)
!16 = !{}
!17 = !DIDerivedType(tag: DW_TAG_member, name: "Second", scope: !7, file: !5, baseType: !18, size: 96, align: 32, extraData: i32 1)
!18 = !DICompositeType(tag: DW_TAG_structure_type, name: "Second", scope: !4, file: !5, size: 96, align: 32, flags: DIFlagPublic, elements: !19, templateParams: !16, identifier: "d12042e992b976eabc7aa6ed0657048d")
!19 = !{!20, !21}
!20 = !DIDerivedType(tag: DW_TAG_member, name: "__0", scope: !18, file: !5, baseType: !13, size: 32, align: 32, offset: 32, flags: DIFlagPublic)
!21 = !DIDerivedType(tag: DW_TAG_member, name: "__1", scope: !18, file: !5, baseType: !15, size: 32, align: 32, offset: 64, flags: DIFlagPublic)
!22 = !DIDerivedType(tag: DW_TAG_member, name: "Third", scope: !7, file: !5, baseType: !23, size: 96, align: 32, extraData: i32 2)
!23 = !DICompositeType(tag: DW_TAG_structure_type, name: "Third", scope: !4, file: !5, size: 96, align: 32, flags: DIFlagPublic, elements: !24, templateParams: !16, identifier: "77e269baca088eafc02a70358f3c026c")
!24 = !{!25}
!25 = !DIDerivedType(tag: DW_TAG_member, name: "__0", scope: !23, file: !5, baseType: !13, size: 32, align: 32, offset: 32, flags: DIFlagPublic)
!26 = !DIDerivedType(tag: DW_TAG_member, scope: !4, file: !5, baseType: !13, size: 32, align: 32, flags: DIFlagArtificial)
BPF backend is assuming that all the elements of the first DICompositeType
(!4
) are DIDerivedType
s and uses an unchecked cast:
llvm-project/llvm/lib/Target/BPF/BTFDebug.cpp
Line 699 in 40bf68f
const auto Elem = cast<DIDerivedType>(Element); |
Which causes crashes when building a Rust BPF module with data-carrying enums, when assertions are enabled:
Assertion failed: isa<To>(Val) && "cast<Ty>() argument of incompatible type!" (/home/vadorovsky/src/llvm-project/llvm/include/llvm/Support/Casting.h: cast: 578)
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.