From 4bde92c17674ba5ac8de4123e0c1023d1e29a60f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 5 Mar 2018 08:12:13 -0800 Subject: [PATCH] rustc: Fix ICE with `#[target_feature]` on module This commit fixes an ICE in rustc when `#[target_feature]` was applied to items other than functions due to the way the feature was validated. --- src/librustc/hir/check_attr.rs | 8 +++++++- src/librustc_typeck/collect.rs | 1 + src/test/ui/target-feature-wrong.rs | 4 ++++ src/test/ui/target-feature-wrong.stderr | 11 ++++++++++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index d22703452605b..d7194e9c2cabb 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -47,7 +47,13 @@ struct CheckAttrVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { /// Check any attribute. fn check_attributes(&self, item: &hir::Item, target: Target) { - self.tcx.trans_fn_attrs(self.tcx.hir.local_def_id(item.id)); + if target == Target::Fn { + self.tcx.trans_fn_attrs(self.tcx.hir.local_def_id(item.id)); + } else if let Some(a) = item.attrs.iter().find(|a| a.check_name("target_feature")) { + self.tcx.sess.struct_span_err(a.span, "attribute should be applied to a function") + .span_label(item.span, "not a function") + .emit(); + } for attr in &item.attrs { if let Some(name) = attr.name() { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1a7d8bb56780e..5fc69035db039 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1883,6 +1883,7 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt .emit(); } } else if attr.check_name("target_feature") { + // handle deprecated #[target_feature = "..."] if let Some(val) = attr.value_str() { for feat in val.as_str().split(",").map(|f| f.trim()) { if !feat.is_empty() && !feat.contains('\0') { diff --git a/src/test/ui/target-feature-wrong.rs b/src/test/ui/target-feature-wrong.rs index e70d549ed573a..c1e6245d24be8 100644 --- a/src/test/ui/target-feature-wrong.rs +++ b/src/test/ui/target-feature-wrong.rs @@ -29,6 +29,10 @@ unsafe fn foo() {} //~^ ERROR: can only be applied to `unsafe` function fn bar() {} +#[target_feature(enable = "sse2")] +//~^ ERROR: should be applied to a function +mod another {} + fn main() { unsafe { foo(); diff --git a/src/test/ui/target-feature-wrong.stderr b/src/test/ui/target-feature-wrong.stderr index 07bad48259111..0fa6910f2bb3f 100644 --- a/src/test/ui/target-feature-wrong.stderr +++ b/src/test/ui/target-feature-wrong.stderr @@ -28,5 +28,14 @@ error: #[target_feature(..)] can only be applied to `unsafe` function LL | #[target_feature(enable = "sse2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: attribute should be applied to a function + --> $DIR/target-feature-wrong.rs:32:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | //~^ ERROR: should be applied to a function +LL | mod another {} + | -------------- not a function + +error: aborting due to 5 previous errors