@@ -224,23 +224,34 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
224224 if !tcx. is_closure ( did. to_def_id ( ) )
225225 && tcx. fn_sig ( did) . skip_binder ( ) . unsafety ( ) == hir:: Unsafety :: Normal
226226 {
227- // The `#[target_feature]` attribute is allowed on
228- // WebAssembly targets on all functions, including safe
229- // ones. Other targets have conditions on the usage of
230- // `#[target_feature]` because on most targets
231- // execution of instructions that are not supported is
232- // considered undefined behavior. For WebAssembly which is a
233- // 100% safe target at execution time it's not possible to
234- // execute undefined instructions, and even if a future
235- // feature was added in some form for this it would be a
236- // deterministic trap. There is no undefined behavior when
237- // executing WebAssembly so `#[target_feature]` is allowed
238- // on safe functions (but again, only for WebAssembly)
239- //
240- // Note that this is also allowed if `actually_rustdoc` so
241- // if a target is documenting some wasm-specific code then
242- // it's not spuriously denied.
243- if !( tcx. sess . target . is_like_wasm || tcx. sess . opts . actually_rustdoc ) {
227+ if tcx. sess . target . is_like_wasm || tcx. sess . opts . actually_rustdoc {
228+ // The `#[target_feature]` attribute is allowed on
229+ // WebAssembly targets on all functions, including safe
230+ // ones. Other targets require that `#[target_feature]` is
231+ // only applied to unsafe functions (pending the
232+ // `target_feature_11` feature) because on most targets
233+ // execution of instructions that are not supported is
234+ // considered undefined behavior. For WebAssembly which is a
235+ // 100% safe target at execution time it's not possible to
236+ // execute undefined instructions, and even if a future
237+ // feature was added in some form for this it would be a
238+ // deterministic trap. There is no undefined behavior when
239+ // executing WebAssembly so `#[target_feature]` is allowed
240+ // on safe functions (but again, only for WebAssembly)
241+ //
242+ // Note that this is also allowed if `actually_rustdoc` so
243+ // if a target is documenting some wasm-specific code then
244+ // it's not spuriously denied.
245+ } else if !tcx. features ( ) . target_feature_11 {
246+ let mut err = feature_err (
247+ & tcx. sess . parse_sess ,
248+ sym:: target_feature_11,
249+ attr. span ,
250+ "`#[target_feature(..)]` can only be applied to `unsafe` functions" ,
251+ ) ;
252+ err. span_label ( tcx. def_span ( did) , "not an `unsafe` function" ) ;
253+ err. emit ( ) ;
254+ } else {
244255 check_target_feature_trait_unsafe ( tcx, did, attr. span ) ;
245256 }
246257 }
@@ -467,7 +478,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
467478 } ) ;
468479
469480 // #73631: closures inherit `#[target_feature]` annotations
470- if tcx. is_closure ( did. to_def_id ( ) ) {
481+ if tcx. features ( ) . target_feature_11 && tcx . is_closure ( did. to_def_id ( ) ) {
471482 let owner_id = tcx. parent ( did. to_def_id ( ) ) ;
472483 if tcx. def_kind ( owner_id) . has_codegen_attrs ( ) {
473484 codegen_fn_attrs
0 commit comments