@@ -18,7 +18,9 @@ use crate::llvm;
18
18
use crate :: llvm:: AttributePlace :: Function ;
19
19
use crate :: type_:: Type ;
20
20
use crate :: value:: Value ;
21
+ use itertools:: Itertools ;
21
22
use rustc_codegen_ssa:: traits:: TypeMembershipMethods ;
23
+ use rustc_data_structures:: fx:: FxIndexSet ;
22
24
use rustc_middle:: ty:: { Instance , Ty } ;
23
25
use rustc_symbol_mangling:: typeid:: {
24
26
kcfi_typeid_for_fnabi, kcfi_typeid_for_instance, typeid_for_fnabi, typeid_for_instance,
@@ -141,20 +143,38 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
141
143
142
144
if self . tcx . sess . is_sanitizer_cfi_enabled ( ) {
143
145
if let Some ( instance) = instance {
144
- let typeid = typeid_for_instance ( self . tcx , instance, TypeIdOptions :: empty ( ) ) ;
145
- self . set_type_metadata ( llfn, typeid) ;
146
- let typeid =
147
- typeid_for_instance ( self . tcx , instance, TypeIdOptions :: GENERALIZE_POINTERS ) ;
148
- self . add_type_metadata ( llfn, typeid) ;
149
- let typeid =
150
- typeid_for_instance ( self . tcx , instance, TypeIdOptions :: NORMALIZE_INTEGERS ) ;
151
- self . add_type_metadata ( llfn, typeid) ;
152
- let typeid = typeid_for_instance (
153
- self . tcx ,
154
- instance,
155
- TypeIdOptions :: GENERALIZE_POINTERS | TypeIdOptions :: NORMALIZE_INTEGERS ,
156
- ) ;
157
- self . add_type_metadata ( llfn, typeid) ;
146
+ let mut typeids = FxIndexSet :: default ( ) ;
147
+ for options in
148
+ [ TypeIdOptions :: GENERALIZE_POINTERS , TypeIdOptions :: NORMALIZE_INTEGERS ]
149
+ . into_iter ( )
150
+ . powerset ( )
151
+ . map ( TypeIdOptions :: from_iter)
152
+ {
153
+ let typeid = typeid_for_instance ( self . tcx , instance, options) ;
154
+ typeids. insert ( typeid. clone ( ) ) ;
155
+ self . add_type_metadata ( llfn, typeid) ;
156
+ }
157
+ // Attach a secondary type id to methods with their concrete self so they can be
158
+ // used as function pointers. The secondary type ids tend to repeat a lot (e.g.,
159
+ // they repeat for all non methods). Always attaching them makes it difficult to
160
+ // maintain tests and debug by looking at the .ll files and correlating typeid
161
+ // attachments with the actual type metadata so add secondary type ids only when
162
+ // they're unique. This also makes it easy to identify methods by when they have a
163
+ // secondary type id.
164
+ for options in [
165
+ TypeIdOptions :: NO_SELF_TYPE_ERASURE ,
166
+ TypeIdOptions :: GENERALIZE_POINTERS ,
167
+ TypeIdOptions :: NORMALIZE_INTEGERS ,
168
+ ]
169
+ . into_iter ( )
170
+ . powerset ( )
171
+ . map ( TypeIdOptions :: from_iter)
172
+ {
173
+ let typeid = typeid_for_instance ( self . tcx , instance, options) ;
174
+ if typeids. insert ( typeid. clone ( ) ) {
175
+ self . add_type_metadata ( llfn, typeid) ;
176
+ }
177
+ }
158
178
} else {
159
179
let typeid = typeid_for_fnabi ( self . tcx , fn_abi, TypeIdOptions :: empty ( ) ) ;
160
180
self . set_type_metadata ( llfn, typeid) ;
0 commit comments