@@ -2604,33 +2604,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2604
2604
} else if attr. check_name ( sym:: link_name) {
2605
2605
codegen_fn_attrs. link_name = attr. value_str ( ) ;
2606
2606
} else if attr. check_name ( sym:: link_ordinal) {
2607
- use syntax:: ast:: { Lit , LitIntType , LitKind } ;
2608
- let meta_item_list = attr. meta_item_list ( ) ;
2609
- let sole_meta_lit = if let Some ( meta_item_list) = & meta_item_list {
2610
- if meta_item_list. len ( ) == 1 {
2611
- meta_item_list. get ( 0 ) . and_then ( |item| item. literal ( ) )
2612
- } else {
2613
- None
2614
- }
2615
- } else {
2616
- None
2617
- } ;
2618
- if let Some ( Lit { node : LitKind :: Int ( ordinal, LitIntType :: Unsuffixed ) , .. } ) =
2619
- sole_meta_lit
2620
- {
2621
- if * ordinal <= std:: usize:: MAX as u128 {
2622
- codegen_fn_attrs. link_ordinal = Some ( * ordinal as usize ) ;
2623
- } else {
2624
- let msg = format ! (
2625
- "too large ordinal value in link_ordinal \
2626
- value: `{}`",
2627
- & ordinal
2628
- ) ;
2629
- tcx. sess . span_err ( attr. span , & msg) ;
2630
- }
2631
- } else {
2632
- let msg = "illegal ordinal format in link_ordinal" ;
2633
- tcx. sess . span_err ( attr. span , & msg) ;
2607
+ if let ordinal @ Some ( _) = check_link_ordinal ( tcx, attr) {
2608
+ codegen_fn_attrs. link_ordinal = ordinal;
2634
2609
}
2635
2610
}
2636
2611
}
@@ -2709,6 +2684,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2709
2684
// purpose functions as they wouldn't have the right target features
2710
2685
// enabled. For that reason we also forbid #[inline(always)] as it can't be
2711
2686
// respected.
2687
+
2712
2688
if codegen_fn_attrs. target_features . len ( ) > 0 {
2713
2689
if codegen_fn_attrs. inline == InlineAttr :: Always {
2714
2690
if let Some ( span) = inline_span {
@@ -2733,15 +2709,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2733
2709
codegen_fn_attrs. export_name = Some ( name) ;
2734
2710
codegen_fn_attrs. link_name = Some ( name) ;
2735
2711
}
2736
- if codegen_fn_attrs. link_name . is_some ( ) && codegen_fn_attrs. link_ordinal . is_some ( ) {
2737
- if let Some ( span) = inline_span {
2738
- tcx. sess . span_err (
2739
- span,
2740
- "cannot use `#[link_name]` with \
2741
- `#[link_ordinal]`",
2742
- ) ;
2743
- }
2744
- }
2712
+ check_link_name_xor_ordinal ( tcx, & codegen_fn_attrs, inline_span) ;
2745
2713
2746
2714
// Internal symbols to the standard library all have no_mangle semantics in
2747
2715
// that they have defined symbol names present in the function name. This
@@ -2752,3 +2720,44 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2752
2720
2753
2721
codegen_fn_attrs
2754
2722
}
2723
+
2724
+ fn check_link_ordinal ( tcx : TyCtxt < ' _ > , attr : & ast:: Attribute ) -> Option < usize > {
2725
+ use syntax:: ast:: { Lit , LitIntType , LitKind } ;
2726
+ let meta_item_list = attr. meta_item_list ( ) ;
2727
+ let meta_item_list: Option < & [ ast:: NestedMetaItem ] > = meta_item_list. as_ref ( ) . map ( Vec :: as_ref) ;
2728
+ let sole_meta_list = match meta_item_list {
2729
+ Some ( [ item] ) => item. literal ( ) ,
2730
+ _ => None ,
2731
+ } ;
2732
+ if let Some ( Lit { node : LitKind :: Int ( ordinal, LitIntType :: Unsuffixed ) , .. } ) = sole_meta_list {
2733
+ if * ordinal <= std:: usize:: MAX as u128 {
2734
+ Some ( * ordinal as usize )
2735
+ } else {
2736
+ let msg = format ! (
2737
+ "too large ordinal value in link_ordinal value: `{}`" ,
2738
+ & ordinal
2739
+ ) ;
2740
+ tcx. sess . span_err ( attr. span , & msg) ;
2741
+ None
2742
+ }
2743
+ } else {
2744
+ tcx. sess . span_err ( attr. span , "illegal ordinal format in link_ordinal" ) ;
2745
+ None
2746
+ }
2747
+ }
2748
+
2749
+ fn check_link_name_xor_ordinal (
2750
+ tcx : TyCtxt < ' _ > ,
2751
+ codegen_fn_attrs : & CodegenFnAttrs ,
2752
+ inline_span : Option < Span > ,
2753
+ ) {
2754
+ if codegen_fn_attrs. link_name . is_none ( ) || codegen_fn_attrs. link_ordinal . is_none ( ) {
2755
+ return ;
2756
+ }
2757
+ let msg = "cannot use `#[link_name]` with `#[link_ordinal]`" ;
2758
+ if let Some ( span) = inline_span {
2759
+ tcx. sess . span_err ( span, msg) ;
2760
+ } else {
2761
+ tcx. sess . err ( msg) ;
2762
+ }
2763
+ }
0 commit comments