Port #[cfi_encoding] to attribute parser
This commit is contained in:
parent
38c667265b
commit
d719a49b28
11 changed files with 83 additions and 63 deletions
33
compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs
Normal file
33
compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
use super::prelude::*;
|
||||
pub(crate) struct CfiEncodingParser;
|
||||
impl<S: Stage> SingleAttributeParser<S> for CfiEncodingParser {
|
||||
const PATH: &[Symbol] = &[sym::cfi_encoding];
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
|
||||
Allow(Target::Struct),
|
||||
Allow(Target::ForeignTy),
|
||||
Allow(Target::Enum),
|
||||
Allow(Target::Union),
|
||||
]);
|
||||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "encoding");
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
|
||||
let Some(name_value) = args.name_value() else {
|
||||
cx.expected_name_value(cx.attr_span, Some(sym::cfi_encoding));
|
||||
return None;
|
||||
};
|
||||
|
||||
let Some(value_str) = name_value.value_as_str() else {
|
||||
cx.expected_string_literal(name_value.value_span, None);
|
||||
return None;
|
||||
};
|
||||
|
||||
if value_str.as_str().trim().is_empty() {
|
||||
cx.expected_non_empty_string_literal(name_value.value_span);
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(AttributeKind::CfiEncoding { encoding: value_str })
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ pub(crate) mod allow_unstable;
|
|||
pub(crate) mod body;
|
||||
pub(crate) mod cfg;
|
||||
pub(crate) mod cfg_select;
|
||||
pub(crate) mod cfi_encoding;
|
||||
pub(crate) mod codegen_attrs;
|
||||
pub(crate) mod confusables;
|
||||
pub(crate) mod crate_level;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use crate::attributes::allow_unstable::{
|
|||
AllowConstFnUnstableParser, AllowInternalUnstableParser, UnstableFeatureBoundParser,
|
||||
};
|
||||
use crate::attributes::body::CoroutineParser;
|
||||
use crate::attributes::cfi_encoding::CfiEncodingParser;
|
||||
use crate::attributes::codegen_attrs::{
|
||||
ColdParser, CoverageParser, EiiExternItemParser, ExportNameParser, ForceTargetFeatureParser,
|
||||
NakedParser, NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser,
|
||||
|
|
@ -187,6 +188,7 @@ attribute_parsers!(
|
|||
// tidy-alphabetical-end
|
||||
|
||||
// tidy-alphabetical-start
|
||||
Single<CfiEncodingParser>,
|
||||
Single<CoverageParser>,
|
||||
Single<CrateNameParser>,
|
||||
Single<CustomMirParser>,
|
||||
|
|
|
|||
|
|
@ -703,6 +703,9 @@ pub enum AttributeKind {
|
|||
span: Span,
|
||||
},
|
||||
|
||||
/// Represents `#[cfi_encoding]`
|
||||
CfiEncoding { encoding: Symbol },
|
||||
|
||||
/// Represents `#[rustc_coinductive]`.
|
||||
Coinductive(Span),
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ impl AttributeKind {
|
|||
AsPtr(..) => Yes,
|
||||
AutomaticallyDerived(..) => Yes,
|
||||
BodyStability { .. } => No,
|
||||
CfiEncoding { .. } => Yes,
|
||||
Coinductive(..) => No,
|
||||
Cold(..) => No,
|
||||
Confusables { .. } => Yes,
|
||||
|
|
|
|||
|
|
@ -298,6 +298,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| AttributeKind::PinV2(..)
|
||||
| AttributeKind::WindowsSubsystem(..)
|
||||
| AttributeKind::ThreadLocal
|
||||
| AttributeKind::CfiEncoding { .. }
|
||||
) => { /* do nothing */ }
|
||||
Attribute::Unparsed(attr_item) => {
|
||||
style = Some(attr_item.style);
|
||||
|
|
@ -336,7 +337,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| sym::cfg_trace
|
||||
| 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)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ use rustc_abi::{ExternAbi, Integer};
|
|||
use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, CASE_INSENSITIVE, ToBaseN};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_hir::find_attr;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::IntegerExt;
|
||||
use rustc_middle::ty::{
|
||||
|
|
@ -18,7 +20,6 @@ use rustc_middle::ty::{
|
|||
IntTy, List, Region, RegionKind, TermKind, Ty, TyCtxt, TypeFoldable, UintTy,
|
||||
};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::sym;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::cfi::typeid::TypeIdOptions;
|
||||
|
|
@ -446,36 +447,20 @@ pub(crate) fn encode_ty<'tcx>(
|
|||
ty::Adt(adt_def, args) => {
|
||||
let mut s = String::new();
|
||||
let def_id = adt_def.did();
|
||||
if let Some(cfi_encoding) = tcx.get_attr(def_id, sym::cfi_encoding) {
|
||||
if let Some(encoding) = find_attr!(tcx.get_all_attrs(def_id), AttributeKind::CfiEncoding { encoding } => encoding)
|
||||
{
|
||||
let encoding = encoding.as_str().trim();
|
||||
// Use user-defined CFI encoding for type
|
||||
if let Some(value_str) = cfi_encoding.value_str() {
|
||||
let value_str = value_str.as_str().trim();
|
||||
if !value_str.is_empty() {
|
||||
s.push_str(value_str);
|
||||
// Don't compress user-defined builtin types (see
|
||||
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-builtin and
|
||||
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression).
|
||||
let builtin_types = [
|
||||
"v", "w", "b", "c", "a", "h", "s", "t", "i", "j", "l", "m", "x", "y",
|
||||
"n", "o", "f", "d", "e", "g", "z", "Dh",
|
||||
];
|
||||
if !builtin_types.contains(&value_str) {
|
||||
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
|
||||
}
|
||||
} else {
|
||||
#[allow(
|
||||
rustc::diagnostic_outside_of_impl,
|
||||
rustc::untranslatable_diagnostic
|
||||
)]
|
||||
tcx.dcx()
|
||||
.struct_span_err(
|
||||
cfi_encoding.span(),
|
||||
format!("invalid `cfi_encoding` for `{:?}`", ty.kind()),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
} else {
|
||||
bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind());
|
||||
s.push_str(&encoding);
|
||||
// Don't compress user-defined builtin types (see
|
||||
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-builtin and
|
||||
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression).
|
||||
let builtin_types = [
|
||||
"v", "w", "b", "c", "a", "h", "s", "t", "i", "j", "l", "m", "x", "y", "n", "o",
|
||||
"f", "d", "e", "g", "z", "Dh",
|
||||
];
|
||||
if !builtin_types.contains(&encoding) {
|
||||
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
|
||||
}
|
||||
} else if options.contains(EncodeTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c() {
|
||||
// For cross-language LLVM CFI support, the encoding must be compatible at the FFI
|
||||
|
|
@ -508,26 +493,11 @@ pub(crate) fn encode_ty<'tcx>(
|
|||
ty::Foreign(def_id) => {
|
||||
// <length><name>, where <name> is <unscoped-name>
|
||||
let mut s = String::new();
|
||||
if let Some(cfi_encoding) = tcx.get_attr(*def_id, sym::cfi_encoding) {
|
||||
|
||||
if let Some(encoding) = find_attr!(tcx.get_all_attrs(*def_id), AttributeKind::CfiEncoding {encoding} => encoding)
|
||||
{
|
||||
// Use user-defined CFI encoding for type
|
||||
if let Some(value_str) = cfi_encoding.value_str() {
|
||||
if !value_str.to_string().trim().is_empty() {
|
||||
s.push_str(value_str.to_string().trim());
|
||||
} else {
|
||||
#[allow(
|
||||
rustc::diagnostic_outside_of_impl,
|
||||
rustc::untranslatable_diagnostic
|
||||
)]
|
||||
tcx.dcx()
|
||||
.struct_span_err(
|
||||
cfi_encoding.span(),
|
||||
format!("invalid `cfi_encoding` for `{:?}`", ty.kind()),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
} else {
|
||||
bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind());
|
||||
}
|
||||
s.push_str(encoding.as_str().trim());
|
||||
} else {
|
||||
let name = tcx.item_name(*def_id).to_string();
|
||||
let _ = write!(s, "{}{}", name.len(), name);
|
||||
|
|
|
|||
|
|
@ -6,15 +6,15 @@
|
|||
|
||||
use std::iter;
|
||||
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_hir::{self as hir, LangItem, find_attr};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::{
|
||||
self, AssocContainer, ExistentialPredicateStableCmpExt as _, Instance, IntTy, List, TraitRef,
|
||||
Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UintTy,
|
||||
};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{DUMMY_SP, sym};
|
||||
use rustc_trait_selection::traits;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
|
|
@ -138,7 +138,10 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for TransformTy<'tcx> {
|
|||
{
|
||||
// Don't transform repr(transparent) types with an user-defined CFI encoding to
|
||||
// preserve the user-defined CFI encoding.
|
||||
if let Some(_) = self.tcx.get_attr(adt_def.did(), sym::cfi_encoding) {
|
||||
if find_attr!(
|
||||
self.tcx.get_all_attrs(adt_def.did()),
|
||||
AttributeKind::CfiEncoding { .. }
|
||||
) {
|
||||
return t;
|
||||
}
|
||||
let variant = adt_def.non_enum_variant();
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ pub fn test3() {}
|
|||
//~^ ERROR malformed
|
||||
#[must_not_suspend()]
|
||||
//~^ ERROR malformed
|
||||
#[cfi_encoding]
|
||||
#[cfi_encoding = ""]
|
||||
//~^ ERROR malformed
|
||||
struct Test;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,12 +55,6 @@ LL - #[must_not_suspend()]
|
|||
LL + #[must_not_suspend]
|
||||
|
|
||||
|
||||
error: malformed `cfi_encoding` attribute input
|
||||
--> $DIR/malformed-attrs.rs:140:1
|
||||
|
|
||||
LL | #[cfi_encoding]
|
||||
| ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]`
|
||||
|
||||
error: malformed `allow` attribute input
|
||||
--> $DIR/malformed-attrs.rs:184:1
|
||||
|
|
||||
|
|
@ -530,6 +524,15 @@ LL | #[rustc_layout_scalar_valid_range_end]
|
|||
| expected this to be a list
|
||||
| help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]`
|
||||
|
||||
error[E0539]: malformed `cfi_encoding` attribute input
|
||||
--> $DIR/malformed-attrs.rs:140:1
|
||||
|
|
||||
LL | #[cfi_encoding = ""]
|
||||
| ^^^^^^^^^^^^^^^^^--^
|
||||
| | |
|
||||
| | string is not allowed to be empty
|
||||
| help: must be of the form: `#[cfi_encoding = "encoding"]`
|
||||
|
||||
error[E0565]: malformed `marker` attribute input
|
||||
--> $DIR/malformed-attrs.rs:161:1
|
||||
|
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
error: malformed `cfi_encoding` attribute input
|
||||
error[E0539]: malformed `cfi_encoding` attribute input
|
||||
--> $DIR/invalid-attr-encoding.rs:10:1
|
||||
|
|
||||
LL | #[cfi_encoding]
|
||||
| ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]`
|
||||
| ^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| expected this to be of the form `cfi_encoding = "..."`
|
||||
| help: must be of the form: `#[cfi_encoding = "encoding"]`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0539`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue