@@ -18,7 +18,9 @@ use crate::llvm;
1818use crate :: llvm:: AttributePlace :: Function ;
1919use crate :: type_:: Type ;
2020use crate :: value:: Value ;
21+ use itertools:: Itertools ;
2122use rustc_codegen_ssa:: traits:: TypeMembershipMethods ;
23+ use rustc_data_structures:: fx:: FxIndexSet ;
2224use rustc_middle:: ty:: { Instance , Ty } ;
2325use rustc_symbol_mangling:: typeid:: {
2426 kcfi_typeid_for_fnabi, kcfi_typeid_for_instance, typeid_for_fnabi, typeid_for_instance,
@@ -141,33 +143,48 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
141143
142144 if self . tcx . sess . is_sanitizer_cfi_enabled ( ) {
143145 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 are 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+ }
158178 } else {
159- let typeid = typeid_for_fnabi ( self . tcx , fn_abi, TypeIdOptions :: empty ( ) ) ;
160- self . set_type_metadata ( llfn, typeid) ;
161- let typeid = typeid_for_fnabi ( self . tcx , fn_abi, TypeIdOptions :: GENERALIZE_POINTERS ) ;
162- self . add_type_metadata ( llfn, typeid) ;
163- let typeid = typeid_for_fnabi ( self . tcx , fn_abi, TypeIdOptions :: NORMALIZE_INTEGERS ) ;
164- self . add_type_metadata ( llfn, typeid) ;
165- let typeid = typeid_for_fnabi (
166- self . tcx ,
167- fn_abi,
168- TypeIdOptions :: GENERALIZE_POINTERS | TypeIdOptions :: NORMALIZE_INTEGERS ,
169- ) ;
170- self . add_type_metadata ( llfn, typeid) ;
179+ for options in
180+ [ TypeIdOptions :: GENERALIZE_POINTERS , TypeIdOptions :: NORMALIZE_INTEGERS ]
181+ . into_iter ( )
182+ . powerset ( )
183+ . map ( TypeIdOptions :: from_iter)
184+ {
185+ let typeid = typeid_for_fnabi ( self . tcx , fn_abi, options) ;
186+ self . add_type_metadata ( llfn, typeid) ;
187+ }
171188 }
172189 }
173190
0 commit comments