@@ -2641,6 +2641,35 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
26412641 }
26422642 } else if attr. check_name ( sym:: link_name) {
26432643 codegen_fn_attrs. link_name = attr. value_str ( ) ;
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) ;
2672+ }
26442673 }
26452674 }
26462675
@@ -2742,6 +2771,15 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
27422771 codegen_fn_attrs. export_name = Some ( name) ;
27432772 codegen_fn_attrs. link_name = Some ( name) ;
27442773 }
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+ }
27452783
27462784 // Internal symbols to the standard library all have no_mangle semantics in
27472785 // that they have defined symbol names present in the function name. This
0 commit comments