Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_attr_parsing/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ attr_parsing_unstable_cfg_target_compact =
attr_parsing_unstable_feature_bound_incompatible_stability = item annotated with `#[unstable_feature_bound]` should not be stable
.help = If this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]`
attr_parsing_unsupported_instruction_set = target `{$current_target}` does not support `#[instruction_set({$instruction_set}::*)]`
attr_parsing_unsupported_literal_suggestion =
consider removing the prefix
Expand Down
73 changes: 73 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/instruction_set.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use rustc_hir::attrs::InstructionSetAttr;

use super::prelude::*;
use crate::session_diagnostics;

pub(crate) struct InstructionSetParser;

impl<S: Stage> SingleAttributeParser<S> for InstructionSetParser {
const PATH: &[Symbol] = &[sym::instruction_set];
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
Allow(Target::Fn),
Allow(Target::Closure),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Method(MethodKind::Trait { body: true })),
]);
const TEMPLATE: AttributeTemplate = template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute");
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
const POSSIBLE_SYMBOLS: &[Symbol] = &[sym::arm_a32, sym::arm_t32];
const POSSIBLE_ARM_SYMBOLS: &[Symbol] = &[sym::a32, sym::t32];
let Some(maybe_meta_item) = args.list().and_then(MetaItemListParser::single) else {
cx.expected_specific_argument(cx.attr_span, POSSIBLE_SYMBOLS);
return None;
};

let Some(meta_item) = maybe_meta_item.meta_item() else {
cx.expected_specific_argument(maybe_meta_item.span(), POSSIBLE_SYMBOLS);
return None;
};

let mut segments = meta_item.path().segments();

let Some(architecture) = segments.next() else {
cx.expected_specific_argument(meta_item.span(), POSSIBLE_SYMBOLS);
return None;
};

let Some(instruction_set) = segments.next() else {
cx.expected_specific_argument(architecture.span, POSSIBLE_SYMBOLS);
return None;
};

let instruction_set = match architecture.name {
sym::arm => {
if !cx.sess.target.has_thumb_interworking {
cx.dcx().emit_err(session_diagnostics::UnsupportedInstructionSet {
span: cx.attr_span,
instruction_set: sym::arm,
current_target: &cx.sess.opts.target_triple,
});
return None;
}
match instruction_set.name {
sym::a32 => InstructionSetAttr::ArmA32,
sym::t32 => InstructionSetAttr::ArmT32,
_ => {
cx.expected_specific_argument(instruction_set.span, POSSIBLE_ARM_SYMBOLS);
return None;
}
}
}
_ => {
cx.expected_specific_argument(architecture.span, POSSIBLE_SYMBOLS);
return None;
}
};

Some(AttributeKind::InstructionSet(instruction_set))
}
}
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/src/attributes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub(crate) mod deprecation;
pub(crate) mod doc;
pub(crate) mod dummy;
pub(crate) mod inline;
pub(crate) mod instruction_set;
pub(crate) mod link_attrs;
pub(crate) mod lint_helpers;
pub(crate) mod loop_match;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::doc::DocParser;
use crate::attributes::dummy::DummyParser;
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
use crate::attributes::instruction_set::InstructionSetParser;
use crate::attributes::link_attrs::{
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser,
LinkParser, LinkSectionParser, LinkageParser, StdInternalSymbolParser,
Expand Down Expand Up @@ -194,6 +195,7 @@ attribute_parsers!(
Single<ExportNameParser>,
Single<IgnoreParser>,
Single<InlineParser>,
Single<InstructionSetParser>,
Single<LinkNameParser>,
Single<LinkOrdinalParser>,
Single<LinkSectionParser>,
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rustc_feature::AttributeTemplate;
use rustc_hir::AttrPath;
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Span, Symbol};
use rustc_target::spec::TargetTuple;

use crate::fluent_generated as fluent;

Expand Down Expand Up @@ -926,3 +927,12 @@ pub(crate) struct DocAliasMalformed {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_unsupported_instruction_set)]
pub(crate) struct UnsupportedInstructionSet<'a> {
#[primary_span]
pub span: Span,
pub instruction_set: Symbol,
pub current_target: &'a TargetTuple,
}
8 changes: 0 additions & 8 deletions compiler/rustc_codegen_ssa/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to

codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}

codegen_ssa_bare_instruction_set = `#[instruction_set]` requires an argument

codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty

codegen_ssa_cgu_not_recorded =
Expand Down Expand Up @@ -90,8 +88,6 @@ codegen_ssa_incorrect_cgu_reuse_type =

codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient.

codegen_ssa_invalid_instruction_set = invalid instruction set specified

codegen_ssa_invalid_literal_value = invalid literal value
.label = value must be an integer between `0` and `255`

Expand Down Expand Up @@ -215,8 +211,6 @@ codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but

codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions

codegen_ssa_multiple_instruction_set = cannot specify more than one instruction set

codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times
.help = did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point

Expand Down Expand Up @@ -383,8 +377,6 @@ codegen_ssa_unstable_ctarget_feature =
unstable feature specified for `-Ctarget-feature`: `{$feature}`
.note = this feature is not stably supported; its behavior can change in the future

codegen_ssa_unsupported_instruction_set = target does not support `#[instruction_set]`

codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target

codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib)
Expand Down
41 changes: 4 additions & 37 deletions compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ use std::str::FromStr;
use rustc_abi::{Align, ExternAbi};
use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode};
use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
use rustc_hir::attrs::{
AttributeKind, InlineAttr, InstructionSetAttr, Linkage, RtsanSetting, UsedBy,
};
use rustc_hir::attrs::{AttributeKind, InlineAttr, Linkage, RtsanSetting, UsedBy};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items};
Expand Down Expand Up @@ -47,37 +45,6 @@ fn try_fn_sig<'tcx>(
}
}

// FIXME(jdonszelmann): remove when instruction_set becomes a parsed attr
fn parse_instruction_set_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> Option<InstructionSetAttr> {
let list = attr.meta_item_list()?;

match &list[..] {
[MetaItemInner::MetaItem(set)] => {
let segments = set.path.segments.iter().map(|x| x.ident.name).collect::<Vec<_>>();
match segments.as_slice() {
[sym::arm, sym::a32 | sym::t32] if !tcx.sess.target.has_thumb_interworking => {
tcx.dcx().emit_err(errors::UnsupportedInstructionSet { span: attr.span() });
None
}
[sym::arm, sym::a32] => Some(InstructionSetAttr::ArmA32),
[sym::arm, sym::t32] => Some(InstructionSetAttr::ArmT32),
_ => {
tcx.dcx().emit_err(errors::InvalidInstructionSet { span: attr.span() });
None
}
}
}
[] => {
tcx.dcx().emit_err(errors::BareInstructionSet { span: attr.span() });
None
}
_ => {
tcx.dcx().emit_err(errors::MultipleInstructionSet { span: attr.span() });
None
}
}
}

// FIXME(jdonszelmann): remove when patchable_function_entry becomes a parsed attr
fn parse_patchable_function_entry(
tcx: TyCtxt<'_>,
Expand Down Expand Up @@ -350,6 +317,9 @@ fn process_builtin_attrs(
codegen_fn_attrs.flags |= CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM;
}
}
AttributeKind::InstructionSet(instruction_set) => {
codegen_fn_attrs.instruction_set = Some(*instruction_set)
}
_ => {}
}
}
Expand All @@ -367,9 +337,6 @@ fn process_builtin_attrs(
codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED
}
sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL,
sym::instruction_set => {
codegen_fn_attrs.instruction_set = parse_instruction_set_attr(tcx, attr)
}
sym::patchable_function_entry => {
codegen_fn_attrs.patchable_function_entry =
parse_patchable_function_entry(tcx, attr);
Expand Down
28 changes: 0 additions & 28 deletions compiler/rustc_codegen_ssa/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,34 +136,6 @@ pub(crate) struct RequiresRustAbi {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(codegen_ssa_unsupported_instruction_set, code = E0779)]
pub(crate) struct UnsupportedInstructionSet {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(codegen_ssa_invalid_instruction_set, code = E0779)]
pub(crate) struct InvalidInstructionSet {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(codegen_ssa_bare_instruction_set, code = E0778)]
pub(crate) struct BareInstructionSet {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(codegen_ssa_multiple_instruction_set, code = E0779)]
pub(crate) struct MultipleInstructionSet {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(codegen_ssa_expected_name_value_pair)]
pub(crate) struct ExpectedNameValuePair {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_error_codes/src/error_codes/E0778.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#### Note: this error code is no longer emitted by the compiler
The `instruction_set` attribute was malformed.

Erroneous code example:

```compile_fail,E0778
```compile_fail
#![feature(isa_attribute)]
#[instruction_set()] // error: expected one argument
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_error_codes/src/error_codes/E0779.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#### Note: this error code is no longer emitted by the compiler
An unknown argument was given to the `instruction_set` attribute.

Erroneous code example:

```compile_fail,E0779
```compile_fail
#![feature(isa_attribute)]

#[instruction_set(intel::x64)] // error: invalid argument
Expand Down
15 changes: 14 additions & 1 deletion compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,17 @@ impl InlineAttr {
}
}

#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)]
#[derive(
Copy,
Clone,
Encodable,
Decodable,
Debug,
PartialEq,
Eq,
HashStable_Generic,
PrintAttribute
)]
pub enum InstructionSetAttr {
ArmA32,
ArmT32,
Expand Down Expand Up @@ -804,6 +814,9 @@ pub enum AttributeKind {
/// Represents `#[inline]` and `#[rustc_force_inline]`.
Inline(InlineAttr, Span),

/// Represents `#[instruction_set]`
InstructionSet(InstructionSetAttr),

/// Represents `#[link]`.
Link(ThinVec<LinkEntry>, Span),

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ impl AttributeKind {
Fundamental { .. } => Yes,
Ignore { .. } => No,
Inline(..) => No,
InstructionSet(..) => No,
Link(..) => No,
LinkName { .. } => Yes, // Needed for rustdoc
LinkOrdinal { .. } => No,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::Dummy
| AttributeKind::RustcBuiltinMacro { .. }
| AttributeKind::Ignore { .. }
| AttributeKind::InstructionSet(..)
| AttributeKind::Path(..)
| AttributeKind::NoImplicitPrelude(..)
| AttributeKind::AutomaticallyDerived(..)
Expand Down Expand Up @@ -343,7 +344,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::cfg_attr_trace
// need to be fixed
| sym::cfi_encoding // FIXME(cfi_encoding)
| sym::instruction_set // broken on stable!!!
| sym::patchable_function_entry // FIXME(patchable_function_entry)
| sym::deprecated_safe // FIXME(deprecated_safe)
// internal
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,8 @@ symbols! {
arith_offset,
arm,
arm64ec,
arm_a32: "arm::a32",
arm_t32: "arm::t32",
arm_target_feature,
array,
as_dash_needed: "as-needed",
Expand Down
31 changes: 31 additions & 0 deletions tests/ui/attributes/instruction-set.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//@ add-minicore
//@ compile-flags: --target armv5te-none-eabi
//@ needs-llvm-components: arm

#![crate_type = "lib"]
#![feature(no_core, lang_items)]
#![no_core]

extern crate minicore;
use minicore::*;


#[instruction_set(arm::a32)]
fn foo() {
}

#[instruction_set(arm)]
//~^ ERROR malformed `instruction_set` attribute input [E0539]
fn bar() {
}

#[instruction_set(arm::)]
//~^ ERROR expected identifier, found `<eof>`
fn bazz() {
}

#[instruction_set(arm::magic)]
//~^ ERROR malformed `instruction_set` attribute input [E0539]
fn bazzer() {

}
Loading
Loading