@@ -14,8 +14,8 @@ use crate::context::CodegenCx;
14
14
use crate :: errors:: { MissingFeatures , SanitizerMemtagRequiresMte , TargetFeatureDisableOrEnable } ;
15
15
use crate :: llvm:: AttributePlace :: Function ;
16
16
use crate :: llvm:: { self , AllocKindFlags , Attribute , AttributeKind , AttributePlace , MemoryEffects } ;
17
+ use crate :: llvm_util;
17
18
use crate :: value:: Value ;
18
- use crate :: { attributes, llvm_util} ;
19
19
20
20
pub ( crate ) fn apply_to_llfn ( llfn : & Value , idx : AttributePlace , attrs : & [ & Attribute ] ) {
21
21
if !attrs. is_empty ( ) {
@@ -324,13 +324,18 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute {
324
324
llvm:: CreateAttrStringValue ( llcx, "alloc-family" , "__rust_alloc" )
325
325
}
326
326
327
- /// Helper for `FnAbi::apply_attrs_llfn `:
327
+ /// Helper for `FnAbi::apply_attrs_* `:
328
328
/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
329
329
/// 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.
330
334
pub ( crate ) fn llfn_attrs_from_instance < ' ll , ' tcx > (
331
335
cx : & CodegenCx < ' ll , ' tcx > ,
332
- llfn : & ' ll Value ,
333
336
instance : ty:: Instance < ' tcx > ,
337
+ declare_llfn : Option < & ' ll Value > ,
338
+ apply_attrs : impl Fn ( AttributePlace , & [ & Attribute ] ) ,
334
339
) {
335
340
let codegen_fn_attrs = cx. tcx . codegen_fn_attrs ( instance. def_id ( ) ) ;
336
341
@@ -445,7 +450,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
445
450
to_add. push ( create_alloc_family_attr ( cx. llcx ) ) ;
446
451
// apply to argument place instead of function
447
452
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] ) ;
449
454
to_add. push ( llvm:: CreateAllocSizeAttr ( cx. llcx , 0 ) ) ;
450
455
let mut flags = AllocKindFlags :: Alloc | AllocKindFlags :: Aligned ;
451
456
if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: ALLOCATOR ) {
@@ -456,7 +461,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
456
461
to_add. push ( llvm:: CreateAllocKindAttr ( cx. llcx , flags) ) ;
457
462
// apply to return place instead of function (unlike all other attributes applied in this function)
458
463
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] ) ;
460
465
}
461
466
if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: REALLOCATOR ) {
462
467
to_add. push ( create_alloc_family_attr ( cx. llcx ) ) ;
@@ -466,26 +471,28 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
466
471
) ) ;
467
472
// applies to argument place instead of function place
468
473
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] ) ;
470
475
// apply to argument place instead of function
471
476
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] ) ;
473
478
to_add. push ( llvm:: CreateAllocSizeAttr ( cx. llcx , 3 ) ) ;
474
479
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] ) ;
476
481
}
477
482
if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: DEALLOCATOR ) {
478
483
to_add. push ( create_alloc_family_attr ( cx. llcx ) ) ;
479
484
to_add. push ( llvm:: CreateAllocKindAttr ( cx. llcx , AllocKindFlags :: Free ) ) ;
480
485
// applies to argument place instead of function place
481
486
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] ) ;
483
488
}
484
489
if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: CMSE_NONSECURE_ENTRY ) {
485
490
to_add. push ( llvm:: CreateAttrString ( cx. llcx , "cmse_nonsecure_entry" ) ) ;
486
491
}
487
492
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
+ }
489
496
}
490
497
if let Some ( backchain) = backchain_attr ( cx) {
491
498
to_add. push ( backchain) ;
@@ -503,24 +510,27 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
503
510
let function_features =
504
511
codegen_fn_attrs. target_features . iter ( ) . map ( |f| f. name . as_str ( ) ) . collect :: < Vec < & str > > ( ) ;
505
512
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
+ }
524
534
}
525
535
526
536
let function_features = function_features
@@ -562,7 +572,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
562
572
to_add. push ( llvm:: CreateAttrStringValue ( cx. llcx , "target-features" , & target_features) ) ;
563
573
}
564
574
565
- attributes :: apply_to_llfn ( llfn , Function , & to_add) ;
575
+ apply_attrs ( Function , & to_add) ;
566
576
}
567
577
568
578
fn wasm_import_module ( tcx : TyCtxt < ' _ > , id : DefId ) -> Option < & String > {
0 commit comments