@@ -16,9 +16,12 @@ use crate::{extract_cdb_version, extract_gdb_version};
16
16
#[ cfg( test) ]
17
17
mod tests;
18
18
19
- /// The result of parse_cfg_name_directive.
19
+ /// Whether a given property holds true of this test instance. Usually,
20
+ /// a property is something about the target (e.g. whether the target is Windows),
21
+ /// but it could also be something more general (e.g. whether this test is being
22
+ /// cross-compiled.)
20
23
#[ derive( Clone , Copy , PartialEq , Debug ) ]
21
- enum ParsedNameDirective {
24
+ enum EvaluatedProp {
22
25
/// No match.
23
26
NoMatch ,
24
27
/// Match.
@@ -228,6 +231,10 @@ impl TestProps {
228
231
if !testfile. is_dir ( ) {
229
232
let file = File :: open ( testfile) . unwrap ( ) ;
230
233
234
+ let mut target = config. target . clone ( ) ;
235
+ let mut per_prop_normalize_stdout: Vec < ( String , ( String , String ) ) > = Vec :: new ( ) ;
236
+ let mut per_prop_normalize_stderr: Vec < ( String , ( String , String ) ) > = Vec :: new ( ) ;
237
+
231
238
iter_header ( testfile, file, & mut |revision, ln| {
232
239
if revision. is_some ( ) && revision != cfg {
233
240
return ;
@@ -340,11 +347,16 @@ impl TestProps {
340
347
self . ignore_pass = config. parse_ignore_pass ( ln) ;
341
348
}
342
349
350
+ if let Some ( target_override) = config. parse_target_override ( ln) {
351
+ target = target_override;
352
+ }
353
+
343
354
if let Some ( rule) = config. parse_custom_normalization ( ln, "normalize-stdout" ) {
344
- self . normalize_stdout . push ( rule) ;
355
+ per_prop_normalize_stdout . push ( rule) ;
345
356
}
357
+
346
358
if let Some ( rule) = config. parse_custom_normalization ( ln, "normalize-stderr" ) {
347
- self . normalize_stderr . push ( rule) ;
359
+ per_prop_normalize_stderr . push ( rule) ;
348
360
}
349
361
350
362
if let Some ( code) = config. parse_failure_status ( ln) {
@@ -372,6 +384,17 @@ impl TestProps {
372
384
self . incremental = config. parse_incremental ( ln) ;
373
385
}
374
386
} ) ;
387
+ for ( prop, normalization) in per_prop_normalize_stdout {
388
+ if config. evaluate_prop_for_target ( & prop, & target) == EvaluatedProp :: Match {
389
+ self . normalize_stdout . push ( normalization) ;
390
+ }
391
+ }
392
+
393
+ for ( prop, normalization) in per_prop_normalize_stderr {
394
+ if config. evaluate_prop_for_target ( & prop, & target) == EvaluatedProp :: Match {
395
+ self . normalize_stderr . push ( normalization) ;
396
+ }
397
+ }
375
398
}
376
399
377
400
if self . failure_status == -1 {
@@ -650,14 +673,15 @@ impl Config {
650
673
}
651
674
}
652
675
653
- fn parse_custom_normalization ( & self , mut line : & str , prefix : & str ) -> Option < ( String , String ) > {
654
- if self . parse_cfg_name_directive ( line, prefix) == ParsedNameDirective :: Match {
655
- let from = parse_normalization_string ( & mut line) ?;
656
- let to = parse_normalization_string ( & mut line) ?;
657
- Some ( ( from, to) )
658
- } else {
659
- None
660
- }
676
+ fn parse_custom_normalization (
677
+ & self ,
678
+ mut line : & str ,
679
+ prefix : & str ,
680
+ ) -> Option < ( String , ( String , String ) ) > {
681
+ let prop = self . parse_prop_directive ( line, prefix) ?;
682
+ let from = parse_normalization_string ( & mut line) ?;
683
+ let to = parse_normalization_string ( & mut line) ?;
684
+ Some ( ( prop, ( from, to) ) )
661
685
}
662
686
663
687
fn parse_needs_matching_clang ( & self , line : & str ) -> bool {
@@ -670,7 +694,19 @@ impl Config {
670
694
671
695
/// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86`
672
696
/// or `normalize-stderr-32bit`.
673
- fn parse_cfg_name_directive ( & self , line : & str , prefix : & str ) -> ParsedNameDirective {
697
+ fn parse_prop_directive ( & self , line : & str , prefix : & str ) -> Option < String > {
698
+ if !line. as_bytes ( ) . starts_with ( prefix. as_bytes ( ) ) {
699
+ return None ;
700
+ }
701
+ if line. as_bytes ( ) . get ( prefix. len ( ) ) != Some ( & b'-' ) {
702
+ return None ;
703
+ }
704
+
705
+ let config = & line[ & prefix. len ( ) + 1 ..] . to_string ( ) ;
706
+ Some ( config. to_string ( ) )
707
+ }
708
+
709
+ fn evaluate_prop_for_target ( & self , prop : & str , target : & str ) -> EvaluatedProp {
674
710
// This matches optional whitespace, followed by a group containing a series of word
675
711
// characters (including '_' and '-'), followed optionally by a sequence consisting
676
712
// of a colon, optional whitespace, and another group containing word characters.
@@ -697,28 +733,21 @@ impl Config {
697
733
static ref CFG_REGEX : Regex = Regex :: new( r"^\s*([\w-]+)(?::\s*([\w-]+))?" ) . unwrap( ) ;
698
734
}
699
735
700
- if !line. as_bytes ( ) . starts_with ( prefix. as_bytes ( ) ) {
701
- return ParsedNameDirective :: NoMatch ;
702
- }
703
- if line. as_bytes ( ) . get ( prefix. len ( ) ) != Some ( & b'-' ) {
704
- return ParsedNameDirective :: NoMatch ;
705
- }
706
-
707
- let captures = CFG_REGEX . captures ( & line[ & prefix. len ( ) + 1 ..] ) . unwrap ( ) ;
736
+ let captures = CFG_REGEX . captures ( & prop) . unwrap ( ) ;
708
737
let name = captures. get ( 1 ) . unwrap ( ) . as_str ( ) ;
709
738
let maybe_value = captures. get ( 2 ) . map ( |v| v. as_str ( ) . trim ( ) ) ;
710
739
711
740
let is_match = name == "test" ||
712
- self . target == name || // triple
713
- util:: matches_os ( & self . target , name) || // target
714
- util:: matches_env ( & self . target , name) || // env
715
- self . target . ends_with ( name) || // target and env
716
- name == util:: get_arch ( & self . target ) || // architecture
717
- name == util:: get_pointer_width ( & self . target ) || // pointer width
741
+ target == name || // triple
742
+ util:: matches_os ( target, name) || // target
743
+ util:: matches_env ( target, name) || // env
744
+ target. ends_with ( name) || // target and env
745
+ name == util:: get_arch ( target) || // architecture
746
+ name == util:: get_pointer_width ( target) || // pointer width
718
747
name == self . stage_id . split ( '-' ) . next ( ) . unwrap ( ) || // stage
719
748
name == self . channel || // channel
720
- ( self . target != self . host && name == "cross-compile" ) ||
721
- ( name == "endian-big" && util:: is_big_endian ( & self . target ) ) ||
749
+ ( target != self . host && name == "cross-compile" ) ||
750
+ ( name == "endian-big" && util:: is_big_endian ( target) ) ||
722
751
( self . remote_test_client . is_some ( ) && name == "remote" ) ||
723
752
match self . compare_mode {
724
753
Some ( CompareMode :: Nll ) => name == "compare-mode-nll" ,
@@ -736,14 +765,17 @@ impl Config {
736
765
None => false ,
737
766
} ||
738
767
match name. strip_prefix ( "cfg-" ) {
739
- Some ( rustc_cfg_name) => util:: cfg_has ( & self . target_cfg , rustc_cfg_name, maybe_value) ,
768
+ Some ( rustc_cfg_name) => {
769
+ let cfg_data = util:: fetch_cfg_from_rustc_for_target ( & self . rustc_path , target) ;
770
+ util:: cfg_has ( & cfg_data, rustc_cfg_name, maybe_value)
771
+ } ,
740
772
None => false
741
773
} ;
742
774
743
- if is_match { ParsedNameDirective :: Match } else { ParsedNameDirective :: NoMatch }
775
+ if is_match { EvaluatedProp :: Match } else { EvaluatedProp :: NoMatch }
744
776
}
745
777
746
- fn has_cfg_prefix ( & self , line : & str , prefix : & str ) -> bool {
778
+ fn has_prop_prefix ( & self , line : & str , prefix : & str ) -> bool {
747
779
// returns whether this line contains this prefix or not. For prefix
748
780
// "ignore", returns true if line says "ignore-x86_64", "ignore-arch",
749
781
// "ignore-android" etc.
@@ -768,6 +800,21 @@ impl Config {
768
800
}
769
801
}
770
802
803
+ pub fn parse_target_override ( & self , line : & str ) -> Option < String > {
804
+ let flags = self . parse_name_value_directive ( line, "compile-flags" ) ?;
805
+ let ( _, tail) = flags. split_once ( "--target" ) ?;
806
+ if tail. starts_with ( |c : char | c. is_whitespace ( ) || c == '=' ) {
807
+ let tail = & tail[ 1 ..] ;
808
+ let target = match tail. split_once ( |c : char | c. is_whitespace ( ) ) {
809
+ Some ( ( target, _) ) => target,
810
+ None => & tail,
811
+ } ;
812
+ Some ( target. to_string ( ) )
813
+ } else {
814
+ None
815
+ }
816
+ }
817
+
771
818
pub fn find_rust_src_root ( & self ) -> Option < PathBuf > {
772
819
let mut path = self . src_base . clone ( ) ;
773
820
let path_postfix = Path :: new ( "src/etc/lldb_batchmode.py" ) ;
@@ -900,6 +947,10 @@ pub fn make_test_description<R: Read>(
900
947
let mut ignore = false ;
901
948
let mut should_fail = false ;
902
949
950
+ let mut target = config. target . clone ( ) ;
951
+ let mut ignored_props: Vec < String > = Vec :: new ( ) ;
952
+ let mut only_test_on_props: Vec < String > = Vec :: new ( ) ;
953
+
903
954
let rustc_has_profiler_support = env:: var_os ( "RUSTC_PROFILER_SUPPORT" ) . is_some ( ) ;
904
955
let rustc_has_sanitizer_support = env:: var_os ( "RUSTC_SANITIZER_SUPPORT" ) . is_some ( ) ;
905
956
let has_asm_support = util:: has_asm_support ( & config. target ) ;
@@ -908,7 +959,6 @@ pub fn make_test_description<R: Read>(
908
959
let has_msan = util:: MSAN_SUPPORTED_TARGETS . contains ( & & * config. target ) ;
909
960
let has_tsan = util:: TSAN_SUPPORTED_TARGETS . contains ( & & * config. target ) ;
910
961
let has_hwasan = util:: HWASAN_SUPPORTED_TARGETS . contains ( & & * config. target ) ;
911
- // for `-Z gcc-ld=lld`
912
962
let has_rust_lld = config
913
963
. compile_lib_path
914
964
. join ( "rustlib" )
@@ -921,15 +971,16 @@ pub fn make_test_description<R: Read>(
921
971
if revision. is_some ( ) && revision != cfg {
922
972
return ;
923
973
}
924
- ignore = match config. parse_cfg_name_directive ( ln, "ignore" ) {
925
- ParsedNameDirective :: Match => true ,
926
- ParsedNameDirective :: NoMatch => ignore,
927
- } ;
928
- if config. has_cfg_prefix ( ln, "only" ) {
929
- ignore = match config. parse_cfg_name_directive ( ln, "only" ) {
930
- ParsedNameDirective :: Match => ignore,
931
- ParsedNameDirective :: NoMatch => true ,
932
- } ;
974
+ if let Some ( target_override) = config. parse_target_override ( ln) {
975
+ target = target_override;
976
+ }
977
+ if let Some ( prop) = config. parse_prop_directive ( ln, "ignore" ) {
978
+ ignored_props. push ( prop) ;
979
+ }
980
+ if config. has_prop_prefix ( ln, "only" ) {
981
+ if let Some ( prop) = config. parse_prop_directive ( ln, "only" ) {
982
+ only_test_on_props. push ( prop) ;
983
+ }
933
984
}
934
985
ignore |= ignore_llvm ( config, ln) ;
935
986
ignore |=
@@ -954,6 +1005,19 @@ pub fn make_test_description<R: Read>(
954
1005
should_fail |= config. parse_name_directive ( ln, "should-fail" ) ;
955
1006
} ) ;
956
1007
1008
+ for prop in ignored_props {
1009
+ ignore = match config. evaluate_prop_for_target ( & prop, & target) {
1010
+ EvaluatedProp :: Match => true ,
1011
+ EvaluatedProp :: NoMatch => ignore,
1012
+ } ;
1013
+ }
1014
+ for prop in only_test_on_props {
1015
+ ignore = match config. evaluate_prop_for_target ( & prop, & target) {
1016
+ EvaluatedProp :: Match => ignore,
1017
+ EvaluatedProp :: NoMatch => true ,
1018
+ } ;
1019
+ }
1020
+
957
1021
// The `should-fail` annotation doesn't apply to pretty tests,
958
1022
// since we run the pretty printer across all tests by default.
959
1023
// If desired, we could add a `should-fail-pretty` annotation.
0 commit comments