@@ -308,7 +308,53 @@ pub fn check_tied_features(
308308/// Used to generate cfg variables and apply features
309309/// Must express features in the way Rust understands them
310310pub fn target_features ( sess : & Session , allow_unstable : bool ) -> Vec < Symbol > {
311- let target_machine = create_informational_target_machine ( sess) ;
311+ let rust_features = sess
312+ . target
313+ . supported_target_features ( )
314+ . iter ( )
315+ . map ( |( feature, _, _) | {
316+ ( to_llvm_features ( sess, feature) . llvm_feature_name , Symbol :: intern ( feature) )
317+ } )
318+ . collect :: < FxHashMap < _ , _ > > ( ) ;
319+
320+ let mut features = FxHashSet :: default ( ) ;
321+
322+ // Add base features for the target
323+ let target_machine = create_informational_target_machine ( sess, false ) ;
324+ features. extend (
325+ sess. target
326+ . supported_target_features ( )
327+ . iter ( )
328+ . filter ( |( feature, _, _) | {
329+ // skip checking special features, as LLVM may not understands them
330+ if RUSTC_SPECIAL_FEATURES . contains ( feature) {
331+ return true ;
332+ }
333+ // check that all features in a given smallvec are enabled
334+ for llvm_feature in to_llvm_features ( sess, feature) {
335+ let cstr = SmallCStr :: new ( llvm_feature) ;
336+ if !unsafe { llvm:: LLVMRustHasFeature ( & target_machine, cstr. as_ptr ( ) ) } {
337+ return false ;
338+ }
339+ }
340+ true
341+ } )
342+ . map ( |( feature, _, _) | Symbol :: intern ( feature) ) ,
343+ ) ;
344+
345+ // Add enabled features
346+ for llvm_feature in global_llvm_features ( sess, false ) {
347+ let ( add, llvm_feature) = llvm_feature. split_at ( 1 ) ;
348+ let feature =
349+ rust_features. get ( llvm_feature) . cloned ( ) . unwrap_or ( Symbol :: intern ( llvm_feature) ) ;
350+ if add == "+" {
351+ features. extend ( sess. target . implied_target_features ( std:: iter:: once ( feature) ) ) ;
352+ } else if add == "-" {
353+ features. remove ( & feature) ;
354+ }
355+ }
356+
357+ // Filter enabled features based on feature gates
312358 sess. target
313359 . supported_target_features ( )
314360 . iter ( )
@@ -320,18 +366,7 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
320366 }
321367 } )
322368 . filter ( |feature| {
323- // skip checking special features, as LLVM may not understands them
324- if RUSTC_SPECIAL_FEATURES . contains ( feature) {
325- return true ;
326- }
327- // check that all features in a given smallvec are enabled
328- for llvm_feature in to_llvm_features ( sess, feature) {
329- let cstr = SmallCStr :: new ( llvm_feature) ;
330- if !unsafe { llvm:: LLVMRustHasFeature ( & target_machine, cstr. as_ptr ( ) ) } {
331- return false ;
332- }
333- }
334- true
369+ RUSTC_SPECIAL_FEATURES . contains ( feature) || features. contains ( & Symbol :: intern ( feature) )
335370 } )
336371 . map ( |feature| Symbol :: intern ( feature) )
337372 . collect ( )
@@ -440,7 +475,7 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
440475
441476pub ( crate ) fn print ( req : & PrintRequest , mut out : & mut String , sess : & Session ) {
442477 require_inited ( ) ;
443- let tm = create_informational_target_machine ( sess) ;
478+ let tm = create_informational_target_machine ( sess, true ) ;
444479 match req. kind {
445480 PrintKind :: TargetCPUs => {
446481 // SAFETY generate a C compatible string from a byte slice to pass
0 commit comments