@@ -150,7 +150,15 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
150
150
} )
151
151
. collect :: < Vec < _ > > ( ) ;
152
152
153
+ if let Err ( error) = check_attr_whitelist ( & f. attrs , WhiteListCaller :: Entry ) {
154
+ return error;
155
+ }
156
+
157
+ let ( ref cfgs, ref attrs) = extract_cfgs ( f. attrs . clone ( ) ) ;
158
+
153
159
quote ! (
160
+ #( #cfgs) *
161
+ #( #attrs) *
154
162
#[ doc( hidden) ]
155
163
#[ export_name = "main" ]
156
164
pub unsafe extern "C" fn #tramp_ident( ) {
@@ -286,6 +294,10 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
286
294
. into ( ) ;
287
295
}
288
296
297
+ if let Err ( error) = check_attr_whitelist ( & f. attrs , WhiteListCaller :: Exception ) {
298
+ return error;
299
+ }
300
+
289
301
let fspan = f. span ( ) ;
290
302
let ident = f. sig . ident . clone ( ) ;
291
303
@@ -343,7 +355,11 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
343
355
let tramp_ident = Ident :: new ( & format ! ( "{}_trampoline" , f. sig. ident) , Span :: call_site ( ) ) ;
344
356
let ident = & f. sig . ident ;
345
357
358
+ let ( ref cfgs, ref attrs) = extract_cfgs ( f. attrs . clone ( ) ) ;
359
+
346
360
quote ! (
361
+ #( #cfgs) *
362
+ #( #attrs) *
347
363
#[ doc( hidden) ]
348
364
#[ export_name = #ident_s]
349
365
pub unsafe extern "C" fn #tramp_ident( ) {
@@ -396,7 +412,11 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
396
412
let tramp_ident = Ident :: new ( & format ! ( "{}_trampoline" , f. sig. ident) , Span :: call_site ( ) ) ;
397
413
let ident = & f. sig . ident ;
398
414
415
+ let ( ref cfgs, ref attrs) = extract_cfgs ( f. attrs . clone ( ) ) ;
416
+
399
417
quote ! (
418
+ #( #cfgs) *
419
+ #( #attrs) *
400
420
#[ doc( hidden) ]
401
421
#[ export_name = "HardFault" ]
402
422
#[ link_section = ".HardFault.user" ]
@@ -481,7 +501,11 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
481
501
} )
482
502
. collect :: < Vec < _ > > ( ) ;
483
503
504
+ let ( ref cfgs, ref attrs) = extract_cfgs ( f. attrs . clone ( ) ) ;
505
+
484
506
quote ! (
507
+ #( #cfgs) *
508
+ #( #attrs) *
485
509
#[ doc( hidden) ]
486
510
#[ export_name = #ident_s]
487
511
pub unsafe extern "C" fn #tramp_ident( ) {
@@ -650,7 +674,15 @@ pub fn interrupt(args: TokenStream, input: TokenStream) -> TokenStream {
650
674
} )
651
675
. collect :: < Vec < _ > > ( ) ;
652
676
677
+ if let Err ( error) = check_attr_whitelist ( & f. attrs , WhiteListCaller :: Interrupt ) {
678
+ return error;
679
+ }
680
+
681
+ let ( ref cfgs, ref attrs) = extract_cfgs ( f. attrs . clone ( ) ) ;
682
+
653
683
quote ! (
684
+ #( #cfgs) *
685
+ #( #attrs) *
654
686
#[ doc( hidden) ]
655
687
#[ export_name = #ident_s]
656
688
pub unsafe extern "C" fn #tramp_ident( ) {
@@ -724,6 +756,10 @@ pub fn pre_init(args: TokenStream, input: TokenStream) -> TokenStream {
724
756
. into ( ) ;
725
757
}
726
758
759
+ if let Err ( error) = check_attr_whitelist ( & f. attrs , WhiteListCaller :: PreInit ) {
760
+ return error;
761
+ }
762
+
727
763
// XXX should we blacklist other attributes?
728
764
let attrs = f. attrs ;
729
765
let ident = f. sig . ident ;
@@ -790,6 +826,53 @@ fn extract_cfgs(attrs: Vec<Attribute>) -> (Vec<Attribute>, Vec<Attribute>) {
790
826
( cfgs, not_cfgs)
791
827
}
792
828
829
+ enum WhiteListCaller {
830
+ Entry ,
831
+ Exception ,
832
+ Interrupt ,
833
+ PreInit ,
834
+ }
835
+
836
+ fn check_attr_whitelist ( attrs : & [ Attribute ] , caller : WhiteListCaller ) -> Result < ( ) , TokenStream > {
837
+ let whitelist = & [
838
+ "doc" ,
839
+ "link_section" ,
840
+ "cfg" ,
841
+ "allow" ,
842
+ "warn" ,
843
+ "deny" ,
844
+ "forbid" ,
845
+ "cold" ,
846
+ ] ;
847
+
848
+ ' o: for attr in attrs {
849
+ for val in whitelist {
850
+ if eq ( & attr, & val) {
851
+ continue ' o;
852
+ }
853
+ }
854
+
855
+ let err_str = match caller {
856
+ WhiteListCaller :: Entry => "this attribute is not allowed on a cortex-m-rt entry point" ,
857
+ WhiteListCaller :: Exception => {
858
+ "this attribute is not allowed on an exception handler controlled by cortex-m-rt"
859
+ }
860
+ WhiteListCaller :: Interrupt => {
861
+ "this attribute is not allowed on an interrupt handler controlled by cortex-m-rt"
862
+ }
863
+ WhiteListCaller :: PreInit => {
864
+ "this attribute is not allowed on a pre-init controlled by cortex-m-rt"
865
+ }
866
+ } ;
867
+
868
+ return Err ( parse:: Error :: new ( attr. span ( ) , & err_str)
869
+ . to_compile_error ( )
870
+ . into ( ) ) ;
871
+ }
872
+
873
+ Ok ( ( ) )
874
+ }
875
+
793
876
/// Returns `true` if `attr.path` matches `name`
794
877
fn eq ( attr : & Attribute , name : & str ) -> bool {
795
878
attr. style == AttrStyle :: Outer && attr. path . is_ident ( name)
0 commit comments