@@ -2642,33 +2642,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2642
2642
} else if attr. check_name ( sym:: link_name) {
2643
2643
codegen_fn_attrs. link_name = attr. value_str ( ) ;
2644
2644
} else if attr. check_name ( sym:: link_ordinal) {
2645
- use syntax:: ast:: { Lit , LitIntType , LitKind } ;
2646
- let meta_item_list = attr. meta_item_list ( ) ;
2647
- let sole_meta_lit = if let Some ( meta_item_list) = & meta_item_list {
2648
- if meta_item_list. len ( ) == 1 {
2649
- meta_item_list. get ( 0 ) . and_then ( |item| item. literal ( ) )
2650
- } else {
2651
- None
2652
- }
2653
- } else {
2654
- None
2655
- } ;
2656
- if let Some ( Lit { node : LitKind :: Int ( ordinal, LitIntType :: Unsuffixed ) , .. } ) =
2657
- sole_meta_lit
2658
- {
2659
- if * ordinal <= std:: usize:: MAX as u128 {
2660
- codegen_fn_attrs. link_ordinal = Some ( * ordinal as usize ) ;
2661
- } else {
2662
- let msg = format ! (
2663
- "too large ordinal value in link_ordinal \
2664
- value: `{}`",
2665
- & ordinal
2666
- ) ;
2667
- tcx. sess . span_err ( attr. span , & msg) ;
2668
- }
2669
- } else {
2670
- let msg = "illegal ordinal format in link_ordinal" ;
2671
- tcx. sess . span_err ( attr. span , & msg) ;
2645
+ if let ordinal @ Some ( _) = check_link_ordinal ( tcx, attr) {
2646
+ codegen_fn_attrs. link_ordinal = ordinal;
2672
2647
}
2673
2648
}
2674
2649
}
@@ -2747,6 +2722,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2747
2722
// purpose functions as they wouldn't have the right target features
2748
2723
// enabled. For that reason we also forbid #[inline(always)] as it can't be
2749
2724
// respected.
2725
+
2750
2726
if codegen_fn_attrs. target_features . len ( ) > 0 {
2751
2727
if codegen_fn_attrs. inline == InlineAttr :: Always {
2752
2728
if let Some ( span) = inline_span {
@@ -2771,15 +2747,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2771
2747
codegen_fn_attrs. export_name = Some ( name) ;
2772
2748
codegen_fn_attrs. link_name = Some ( name) ;
2773
2749
}
2774
- if codegen_fn_attrs. link_name . is_some ( ) && codegen_fn_attrs. link_ordinal . is_some ( ) {
2775
- if let Some ( span) = inline_span {
2776
- tcx. sess . span_err (
2777
- span,
2778
- "cannot use `#[link_name]` with \
2779
- `#[link_ordinal]`",
2780
- ) ;
2781
- }
2782
- }
2750
+ check_link_name_xor_ordinal ( tcx, & codegen_fn_attrs, inline_span) ;
2783
2751
2784
2752
// Internal symbols to the standard library all have no_mangle semantics in
2785
2753
// that they have defined symbol names present in the function name. This
@@ -2790,3 +2758,44 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2790
2758
2791
2759
codegen_fn_attrs
2792
2760
}
2761
+
2762
+ fn check_link_ordinal ( tcx : TyCtxt < ' _ > , attr : & ast:: Attribute ) -> Option < usize > {
2763
+ use syntax:: ast:: { Lit , LitIntType , LitKind } ;
2764
+ let meta_item_list = attr. meta_item_list ( ) ;
2765
+ let meta_item_list: Option < & [ ast:: NestedMetaItem ] > = meta_item_list. as_ref ( ) . map ( Vec :: as_ref) ;
2766
+ let sole_meta_list = match meta_item_list {
2767
+ Some ( [ item] ) => item. literal ( ) ,
2768
+ _ => None ,
2769
+ } ;
2770
+ if let Some ( Lit { node : LitKind :: Int ( ordinal, LitIntType :: Unsuffixed ) , .. } ) = sole_meta_list {
2771
+ if * ordinal <= std:: usize:: MAX as u128 {
2772
+ Some ( * ordinal as usize )
2773
+ } else {
2774
+ let msg = format ! (
2775
+ "too large ordinal value in link_ordinal value: `{}`" ,
2776
+ & ordinal
2777
+ ) ;
2778
+ tcx. sess . span_err ( attr. span , & msg) ;
2779
+ None
2780
+ }
2781
+ } else {
2782
+ tcx. sess . span_err ( attr. span , "illegal ordinal format in link_ordinal" ) ;
2783
+ None
2784
+ }
2785
+ }
2786
+
2787
+ fn check_link_name_xor_ordinal (
2788
+ tcx : TyCtxt < ' _ > ,
2789
+ codegen_fn_attrs : & CodegenFnAttrs ,
2790
+ inline_span : Option < Span > ,
2791
+ ) {
2792
+ if codegen_fn_attrs. link_name . is_none ( ) || codegen_fn_attrs. link_ordinal . is_none ( ) {
2793
+ return ;
2794
+ }
2795
+ let msg = "cannot use `#[link_name]` with `#[link_ordinal]`" ;
2796
+ if let Some ( span) = inline_span {
2797
+ tcx. sess . span_err ( span, msg) ;
2798
+ } else {
2799
+ tcx. sess . err ( msg) ;
2800
+ }
2801
+ }
0 commit comments