@@ -23,7 +23,10 @@ use rustc_hir::definitions::Definitions;
23
23
use rustc_index:: IndexVec ;
24
24
use rustc_middle:: bug;
25
25
use rustc_middle:: ty:: { TyCtxt , TyCtxtFeed } ;
26
- use rustc_session:: config:: { self , CrateType , ExternLocation } ;
26
+ use rustc_session:: config:: {
27
+ self , CrateType , ExtendedTargetModifierInfo , ExternLocation , OptionsTargetModifiers ,
28
+ TargetModifier ,
29
+ } ;
27
30
use rustc_session:: cstore:: { CrateDepKind , CrateSource , ExternCrate , ExternCrateSource } ;
28
31
use rustc_session:: lint:: { self , BuiltinLintDiag } ;
29
32
use rustc_session:: output:: validate_crate_name;
@@ -35,7 +38,9 @@ use tracing::{debug, info, trace};
35
38
36
39
use crate :: errors;
37
40
use crate :: locator:: { CrateError , CrateLocator , CratePaths } ;
38
- use crate :: rmeta:: { CrateDep , CrateMetadata , CrateNumMap , CrateRoot , MetadataBlob } ;
41
+ use crate :: rmeta:: {
42
+ CrateDep , CrateMetadata , CrateNumMap , CrateRoot , MetadataBlob , TargetModifiers ,
43
+ } ;
39
44
40
45
/// The backend's way to give the crate store access to the metadata in a library.
41
46
/// Note that it returns the raw metadata bytes stored in the library file, whether
@@ -296,6 +301,96 @@ impl CStore {
296
301
}
297
302
}
298
303
304
+ fn report_target_modifiers_extended (
305
+ tcx : TyCtxt < ' _ > ,
306
+ krate : & Crate ,
307
+ mods : & Vec < TargetModifier > ,
308
+ data : & CrateMetadata ,
309
+ ) {
310
+ let span = krate. spans . inner_span . shrink_to_lo ( ) ;
311
+ let allowed_flag_mismatches = & tcx. sess . opts . cg . unsafe_allow_abi_mismatch ;
312
+ let name = tcx. crate_name ( LOCAL_CRATE ) ;
313
+ let tmod_extender = |tmod : & TargetModifier | ( tmod. extend ( ) , tmod. clone ( ) ) ;
314
+ let report_diff = |prefix : & String ,
315
+ opt_name : & String ,
316
+ flag_local_value : & String ,
317
+ flag_extern_value : & String | {
318
+ if allowed_flag_mismatches. contains ( & opt_name) {
319
+ return ;
320
+ }
321
+ tcx. dcx ( ) . emit_err ( errors:: IncompatibleTargetModifiers {
322
+ span,
323
+ extern_crate : data. name ( ) ,
324
+ local_crate : name,
325
+ flag_name : opt_name. clone ( ) ,
326
+ flag_name_prefixed : format ! ( "-{}{}" , prefix, opt_name) ,
327
+ flag_local_value : flag_local_value. to_string ( ) ,
328
+ flag_extern_value : flag_extern_value. to_string ( ) ,
329
+ } ) ;
330
+ } ;
331
+ let mut it1 = mods. iter ( ) . map ( tmod_extender) ;
332
+ let mut it2 = data. target_modifiers ( ) . iter ( ) . map ( tmod_extender) ;
333
+ let mut left_name_val: Option < ( ExtendedTargetModifierInfo , TargetModifier ) > = None ;
334
+ let mut right_name_val: Option < ( ExtendedTargetModifierInfo , TargetModifier ) > = None ;
335
+ let no_val = "*" . to_string ( ) ;
336
+ loop {
337
+ left_name_val = left_name_val. or_else ( || it1. next ( ) ) ;
338
+ right_name_val = right_name_val. or_else ( || it2. next ( ) ) ;
339
+ match ( & left_name_val, & right_name_val) {
340
+ ( Some ( l) , Some ( r) ) => match l. 1 . opt . cmp ( & r. 1 . opt ) {
341
+ cmp:: Ordering :: Equal => {
342
+ if l. 0 . tech_value != r. 0 . tech_value {
343
+ report_diff ( & l. 0 . prefix , & l. 0 . name , & l. 1 . value_name , & r. 1 . value_name ) ;
344
+ }
345
+ left_name_val = None ;
346
+ right_name_val = None ;
347
+ }
348
+ cmp:: Ordering :: Greater => {
349
+ report_diff ( & r. 0 . prefix , & r. 0 . name , & no_val, & r. 1 . value_name ) ;
350
+ right_name_val = None ;
351
+ }
352
+ cmp:: Ordering :: Less => {
353
+ report_diff ( & l. 0 . prefix , & l. 0 . name , & l. 1 . value_name , & no_val) ;
354
+ left_name_val = None ;
355
+ }
356
+ } ,
357
+ ( Some ( l) , None ) => {
358
+ report_diff ( & l. 0 . prefix , & l. 0 . name , & l. 1 . value_name , & no_val) ;
359
+ left_name_val = None ;
360
+ }
361
+ ( None , Some ( r) ) => {
362
+ report_diff ( & r. 0 . prefix , & r. 0 . name , & no_val, & r. 1 . value_name ) ;
363
+ right_name_val = None ;
364
+ }
365
+ ( None , None ) => break ,
366
+ }
367
+ }
368
+ }
369
+
370
+ pub fn report_incompatible_target_modifiers ( & self , tcx : TyCtxt < ' _ > , krate : & Crate ) {
371
+ for flag_name in & tcx. sess . opts . cg . unsafe_allow_abi_mismatch {
372
+ if !OptionsTargetModifiers :: is_target_modifier ( flag_name) {
373
+ tcx. dcx ( ) . emit_err ( errors:: UnknownTargetModifierUnsafeAllowed {
374
+ span : krate. spans . inner_span . shrink_to_lo ( ) ,
375
+ flag_name : flag_name. clone ( ) ,
376
+ } ) ;
377
+ }
378
+ }
379
+
380
+ if tcx. crate_types ( ) . contains ( & CrateType :: ProcMacro ) {
381
+ return ;
382
+ }
383
+ let mods = tcx. sess . opts . gather_target_modifiers ( ) ;
384
+ for ( _cnum, data) in self . iter_crate_data ( ) {
385
+ if data. is_proc_macro_crate ( ) {
386
+ continue ;
387
+ }
388
+ if mods != * data. target_modifiers ( ) {
389
+ Self :: report_target_modifiers_extended ( tcx, krate, & mods, data) ;
390
+ }
391
+ }
392
+ }
393
+
299
394
pub fn new ( metadata_loader : Box < MetadataLoaderDyn > ) -> CStore {
300
395
CStore {
301
396
metadata_loader,
@@ -470,6 +565,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
470
565
} ;
471
566
472
567
let cnum_map = self . resolve_crate_deps ( dep_root, & crate_root, & metadata, cnum, dep_kind) ?;
568
+ let target_modifiers = self . resolve_target_modifiers ( & crate_root, & metadata, cnum) ?;
473
569
474
570
let raw_proc_macros = if crate_root. is_proc_macro_crate ( ) {
475
571
let temp_root;
@@ -494,6 +590,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
494
590
raw_proc_macros,
495
591
cnum,
496
592
cnum_map,
593
+ target_modifiers,
497
594
dep_kind,
498
595
source,
499
596
private_dep,
@@ -737,6 +834,25 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
737
834
Ok ( crate_num_map)
738
835
}
739
836
837
+ fn resolve_target_modifiers (
838
+ & mut self ,
839
+ crate_root : & CrateRoot ,
840
+ metadata : & MetadataBlob ,
841
+ krate : CrateNum ,
842
+ ) -> Result < TargetModifiers , CrateError > {
843
+ debug ! ( "resolving target modifiers of external crate" ) ;
844
+ if crate_root. is_proc_macro_crate ( ) {
845
+ return Ok ( TargetModifiers :: new ( ) ) ;
846
+ }
847
+ let mods = crate_root. decode_target_modifiers ( metadata) ;
848
+ let mut target_modifiers = TargetModifiers :: with_capacity ( mods. len ( ) ) ;
849
+ for modifier in mods {
850
+ target_modifiers. push ( modifier) ;
851
+ }
852
+ debug ! ( "resolve_target_modifiers: target mods for {:?} is {:?}" , krate, target_modifiers) ;
853
+ Ok ( target_modifiers)
854
+ }
855
+
740
856
fn dlsym_proc_macros (
741
857
& self ,
742
858
path : & Path ,
0 commit comments