@@ -14,8 +14,8 @@ use crate::context::CodegenCx;
1414use crate :: errors:: { MissingFeatures , SanitizerMemtagRequiresMte , TargetFeatureDisableOrEnable } ;
1515use crate :: llvm:: AttributePlace :: Function ;
1616use crate :: llvm:: { self , AllocKindFlags , Attribute , AttributeKind , AttributePlace , MemoryEffects } ;
17+ use crate :: llvm_util;
1718use crate :: value:: Value ;
18- use crate :: { attributes, llvm_util} ;
1919
2020pub ( crate ) fn apply_to_llfn ( llfn : & Value , idx : AttributePlace , attrs : & [ & Attribute ] ) {
2121 if !attrs. is_empty ( ) {
@@ -324,13 +324,18 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute {
324324 llvm:: CreateAttrStringValue ( llcx, "alloc-family" , "__rust_alloc" )
325325}
326326
327- /// Helper for `FnAbi::apply_attrs_llfn `:
327+ /// Helper for `FnAbi::apply_attrs_* `:
328328/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
329329/// attributes.
330+ ///
331+ /// `apply_attrs` is called to apply the attributes, so this can be used both for declarations and
332+ /// calls. However, some things are not represented as attributes and can only be set on
333+ /// declarations, so `declare_llfn` should be `Some` if this is a declaration.
330334pub ( crate ) fn llfn_attrs_from_instance < ' ll , ' tcx > (
331335 cx : & CodegenCx < ' ll , ' tcx > ,
332- llfn : & ' ll Value ,
333336 instance : ty:: Instance < ' tcx > ,
337+ declare_llfn : Option < & ' ll Value > ,
338+ apply_attrs : impl Fn ( AttributePlace , & [ & Attribute ] ) ,
334339) {
335340 let codegen_fn_attrs = cx. tcx . codegen_fn_attrs ( instance. def_id ( ) ) ;
336341
@@ -445,7 +450,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
445450 to_add. push ( create_alloc_family_attr ( cx. llcx ) ) ;
446451 // apply to argument place instead of function
447452 let alloc_align = AttributeKind :: AllocAlign . create_attr ( cx. llcx ) ;
448- attributes :: apply_to_llfn ( llfn , AttributePlace :: Argument ( 1 ) , & [ alloc_align] ) ;
453+ apply_attrs ( AttributePlace :: Argument ( 1 ) , & [ alloc_align] ) ;
449454 to_add. push ( llvm:: CreateAllocSizeAttr ( cx. llcx , 0 ) ) ;
450455 let mut flags = AllocKindFlags :: Alloc | AllocKindFlags :: Aligned ;
451456 if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: ALLOCATOR ) {
@@ -456,7 +461,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
456461 to_add. push ( llvm:: CreateAllocKindAttr ( cx. llcx , flags) ) ;
457462 // apply to return place instead of function (unlike all other attributes applied in this function)
458463 let no_alias = AttributeKind :: NoAlias . create_attr ( cx. llcx ) ;
459- attributes :: apply_to_llfn ( llfn , AttributePlace :: ReturnValue , & [ no_alias] ) ;
464+ apply_attrs ( AttributePlace :: ReturnValue , & [ no_alias] ) ;
460465 }
461466 if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: REALLOCATOR ) {
462467 to_add. push ( create_alloc_family_attr ( cx. llcx ) ) ;
@@ -466,26 +471,28 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
466471 ) ) ;
467472 // applies to argument place instead of function place
468473 let allocated_pointer = AttributeKind :: AllocatedPointer . create_attr ( cx. llcx ) ;
469- attributes :: apply_to_llfn ( llfn , AttributePlace :: Argument ( 0 ) , & [ allocated_pointer] ) ;
474+ apply_attrs ( AttributePlace :: Argument ( 0 ) , & [ allocated_pointer] ) ;
470475 // apply to argument place instead of function
471476 let alloc_align = AttributeKind :: AllocAlign . create_attr ( cx. llcx ) ;
472- attributes :: apply_to_llfn ( llfn , AttributePlace :: Argument ( 2 ) , & [ alloc_align] ) ;
477+ apply_attrs ( AttributePlace :: Argument ( 2 ) , & [ alloc_align] ) ;
473478 to_add. push ( llvm:: CreateAllocSizeAttr ( cx. llcx , 3 ) ) ;
474479 let no_alias = AttributeKind :: NoAlias . create_attr ( cx. llcx ) ;
475- attributes :: apply_to_llfn ( llfn , AttributePlace :: ReturnValue , & [ no_alias] ) ;
480+ apply_attrs ( AttributePlace :: ReturnValue , & [ no_alias] ) ;
476481 }
477482 if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: DEALLOCATOR ) {
478483 to_add. push ( create_alloc_family_attr ( cx. llcx ) ) ;
479484 to_add. push ( llvm:: CreateAllocKindAttr ( cx. llcx , AllocKindFlags :: Free ) ) ;
480485 // applies to argument place instead of function place
481486 let allocated_pointer = AttributeKind :: AllocatedPointer . create_attr ( cx. llcx ) ;
482- attributes :: apply_to_llfn ( llfn , AttributePlace :: Argument ( 0 ) , & [ allocated_pointer] ) ;
487+ apply_attrs ( AttributePlace :: Argument ( 0 ) , & [ allocated_pointer] ) ;
483488 }
484489 if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: CMSE_NONSECURE_ENTRY ) {
485490 to_add. push ( llvm:: CreateAttrString ( cx. llcx , "cmse_nonsecure_entry" ) ) ;
486491 }
487492 if let Some ( align) = codegen_fn_attrs. alignment {
488- llvm:: set_alignment ( llfn, align) ;
493+ if let Some ( llfn) = declare_llfn {
494+ llvm:: set_alignment ( llfn, align) ;
495+ }
489496 }
490497 if let Some ( backchain) = backchain_attr ( cx) {
491498 to_add. push ( backchain) ;
@@ -503,24 +510,27 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
503510 let function_features =
504511 codegen_fn_attrs. target_features . iter ( ) . map ( |f| f. name . as_str ( ) ) . collect :: < Vec < & str > > ( ) ;
505512
506- if let Some ( f) = llvm_util:: check_tied_features (
507- cx. tcx . sess ,
508- & function_features. iter ( ) . map ( |f| ( * f, true ) ) . collect ( ) ,
509- ) {
510- let span = cx
511- . tcx
512- . get_attrs ( instance. def_id ( ) , sym:: target_feature)
513- . next ( )
514- . map_or_else ( || cx. tcx . def_span ( instance. def_id ( ) ) , |a| a. span ) ;
515- cx. tcx
516- . dcx ( )
517- . create_err ( TargetFeatureDisableOrEnable {
518- features : f,
519- span : Some ( span) ,
520- missing_features : Some ( MissingFeatures ) ,
521- } )
522- . emit ( ) ;
523- return ;
513+ // HACK: Avoid emitting the lint twice.
514+ if declare_llfn. is_some ( ) {
515+ if let Some ( f) = llvm_util:: check_tied_features (
516+ cx. tcx . sess ,
517+ & function_features. iter ( ) . map ( |f| ( * f, true ) ) . collect ( ) ,
518+ ) {
519+ let span = cx
520+ . tcx
521+ . get_attrs ( instance. def_id ( ) , sym:: target_feature)
522+ . next ( )
523+ . map_or_else ( || cx. tcx . def_span ( instance. def_id ( ) ) , |a| a. span ) ;
524+ cx. tcx
525+ . dcx ( )
526+ . create_err ( TargetFeatureDisableOrEnable {
527+ features : f,
528+ span : Some ( span) ,
529+ missing_features : Some ( MissingFeatures ) ,
530+ } )
531+ . emit ( ) ;
532+ return ;
533+ }
524534 }
525535
526536 let function_features = function_features
@@ -562,7 +572,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
562572 to_add. push ( llvm:: CreateAttrStringValue ( cx. llcx , "target-features" , & target_features) ) ;
563573 }
564574
565- attributes :: apply_to_llfn ( llfn , Function , & to_add) ;
575+ apply_attrs ( Function , & to_add) ;
566576}
567577
568578fn wasm_import_module ( tcx : TyCtxt < ' _ > , id : DefId ) -> Option < & String > {
0 commit comments