Skip to content

Commit 57419ef

Browse files
committed
Port #[cfi_encoding] to attribute parser
1 parent d0835ad commit 57419ef

File tree

10 files changed

+91
-59
lines changed

10 files changed

+91
-59
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use super::prelude::*;
2+
pub(crate) struct CfiEncodingParser;
3+
impl<S: Stage> SingleAttributeParser<S> for CfiEncodingParser {
4+
const PATH: &[Symbol] = &[sym::cfi_encoding];
5+
const ALLOWED_TARGETS: AllowedTargets =
6+
AllowedTargets::AllowListWarnRest(&[Allow(Target::Fn), Allow(Target::Struct)]);
7+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
8+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
9+
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "encoding");
10+
11+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
12+
let Some(name_value) = args.name_value() else {
13+
cx.expected_name_value(cx.attr_span, Some(sym::cfi_encoding));
14+
return None;
15+
};
16+
17+
let Some(value_str) = name_value.value_as_str() else {
18+
cx.expected_string_literal(name_value.value_span, None);
19+
return None;
20+
};
21+
22+
Some(AttributeKind::CfiEncoding { attr_span: cx.attr_span, encoding: value_str })
23+
}
24+
}

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub(crate) mod allow_unstable;
3333
pub(crate) mod body;
3434
pub(crate) mod cfg;
3535
pub(crate) mod cfg_select;
36+
pub(crate) mod cfi_encoding;
3637
pub(crate) mod codegen_attrs;
3738
pub(crate) mod confusables;
3839
pub(crate) mod crate_level;

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::attributes::allow_unstable::{
1919
AllowConstFnUnstableParser, AllowInternalUnstableParser, UnstableFeatureBoundParser,
2020
};
2121
use crate::attributes::body::CoroutineParser;
22+
use crate::attributes::cfi_encoding::CfiEncodingParser;
2223
use crate::attributes::codegen_attrs::{
2324
ColdParser, CoverageParser, EiiExternItemParser, ExportNameParser, ForceTargetFeatureParser,
2425
NakedParser, NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser,
@@ -187,6 +188,7 @@ attribute_parsers!(
187188
// tidy-alphabetical-end
188189

189190
// tidy-alphabetical-start
191+
Single<CfiEncodingParser>,
190192
Single<CoverageParser>,
191193
Single<CrateNameParser>,
192194
Single<CustomMirParser>,

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,9 @@ pub enum AttributeKind {
703703
span: Span,
704704
},
705705

706+
/// Represents `#[cfi_encoding]`
707+
CfiEncoding { attr_span: Span, encoding: Symbol },
708+
706709
/// Represents `#[rustc_coinductive]`.
707710
Coinductive(Span),
708711

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ impl AttributeKind {
2626
AsPtr(..) => Yes,
2727
AutomaticallyDerived(..) => Yes,
2828
BodyStability { .. } => No,
29+
CfiEncoding { .. } => Yes,
2930
Coinductive(..) => No,
3031
Cold(..) => No,
3132
Confusables { .. } => Yes,

compiler/rustc_passes/src/check_attr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
297297
| AttributeKind::RustcPassIndirectlyInNonRusticAbis(..)
298298
| AttributeKind::PinV2(..)
299299
| AttributeKind::WindowsSubsystem(..)
300+
| AttributeKind::CfiEncoding { .. }
300301
) => { /* do nothing */ }
301302
Attribute::Unparsed(attr_item) => {
302303
style = Some(attr_item.style);
@@ -336,7 +337,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
336337
| sym::cfg_trace
337338
| sym::cfg_attr_trace
338339
// need to be fixed
339-
| sym::cfi_encoding // FIXME(cfi_encoding)
340340
| sym::instruction_set // broken on stable!!!
341341
| sym::patchable_function_entry // FIXME(patchable_function_entry)
342342
| sym::deprecated_safe // FIXME(deprecated_safe)

compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs

Lines changed: 38 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ use rustc_abi::{ExternAbi, Integer};
1111
use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, CASE_INSENSITIVE, ToBaseN};
1212
use rustc_data_structures::fx::FxHashMap;
1313
use rustc_hir as hir;
14+
use rustc_hir::attrs::AttributeKind;
15+
use rustc_hir::find_attr;
1416
use rustc_middle::bug;
1517
use rustc_middle::ty::layout::IntegerExt;
1618
use rustc_middle::ty::{
1719
self, Const, ExistentialPredicate, FloatTy, FnSig, GenericArg, GenericArgKind, GenericArgsRef,
1820
IntTy, List, Region, RegionKind, TermKind, Ty, TyCtxt, TypeFoldable, UintTy,
1921
};
2022
use rustc_span::def_id::DefId;
21-
use rustc_span::sym;
2223
use tracing::instrument;
2324

2425
use crate::cfi::typeid::TypeIdOptions;
@@ -446,36 +447,30 @@ pub(crate) fn encode_ty<'tcx>(
446447
ty::Adt(adt_def, args) => {
447448
let mut s = String::new();
448449
let def_id = adt_def.did();
449-
if let Some(cfi_encoding) = tcx.get_attr(def_id, sym::cfi_encoding) {
450+
if let Some((attr_span, encoding)) = find_attr!(tcx.get_all_attrs(def_id), AttributeKind::CfiEncoding { attr_span, encoding } => (attr_span, encoding))
451+
{
450452
// Use user-defined CFI encoding for type
451-
if let Some(value_str) = cfi_encoding.value_str() {
452-
let value_str = value_str.as_str().trim();
453-
if !value_str.is_empty() {
454-
s.push_str(value_str);
455-
// Don't compress user-defined builtin types (see
456-
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-builtin and
457-
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression).
458-
let builtin_types = [
459-
"v", "w", "b", "c", "a", "h", "s", "t", "i", "j", "l", "m", "x", "y",
460-
"n", "o", "f", "d", "e", "g", "z", "Dh",
461-
];
462-
if !builtin_types.contains(&value_str) {
463-
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
464-
}
465-
} else {
466-
#[allow(
467-
rustc::diagnostic_outside_of_impl,
468-
rustc::untranslatable_diagnostic
469-
)]
470-
tcx.dcx()
471-
.struct_span_err(
472-
cfi_encoding.span(),
473-
format!("invalid `cfi_encoding` for `{:?}`", ty.kind()),
474-
)
475-
.emit();
453+
let encoding = encoding.as_str().trim();
454+
if !encoding.is_empty() {
455+
s.push_str(encoding);
456+
// Don't compress user-defined builtin types (see
457+
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-builtin and
458+
// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression).
459+
let builtin_types = [
460+
"v", "w", "b", "c", "a", "h", "s", "t", "i", "j", "l", "m", "x", "y", "n",
461+
"o", "f", "d", "e", "g", "z", "Dh",
462+
];
463+
if !builtin_types.contains(&encoding) {
464+
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
476465
}
477466
} else {
478-
bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind());
467+
#[allow(rustc::diagnostic_outside_of_impl, rustc::untranslatable_diagnostic)]
468+
tcx.dcx()
469+
.struct_span_err(
470+
*attr_span,
471+
format!("invalid `cfi_encoding` for `{:?}`", ty.kind()),
472+
)
473+
.emit();
479474
}
480475
} else if options.contains(EncodeTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c() {
481476
// For cross-language LLVM CFI support, the encoding must be compatible at the FFI
@@ -508,30 +503,27 @@ pub(crate) fn encode_ty<'tcx>(
508503
ty::Foreign(def_id) => {
509504
// <length><name>, where <name> is <unscoped-name>
510505
let mut s = String::new();
511-
if let Some(cfi_encoding) = tcx.get_attr(*def_id, sym::cfi_encoding) {
506+
507+
if let Some((attr_span, encoding)) = find_attr!(tcx.get_all_attrs(*def_id), AttributeKind::CfiEncoding {attr_span, encoding} => (attr_span, encoding))
508+
{
512509
// Use user-defined CFI encoding for type
513-
if let Some(value_str) = cfi_encoding.value_str() {
514-
if !value_str.to_string().trim().is_empty() {
515-
s.push_str(value_str.to_string().trim());
516-
} else {
517-
#[allow(
518-
rustc::diagnostic_outside_of_impl,
519-
rustc::untranslatable_diagnostic
520-
)]
521-
tcx.dcx()
522-
.struct_span_err(
523-
cfi_encoding.span(),
524-
format!("invalid `cfi_encoding` for `{:?}`", ty.kind()),
525-
)
526-
.emit();
527-
}
510+
let encoding = encoding.as_str().trim();
511+
if !encoding.is_empty() {
512+
s.push_str(encoding);
528513
} else {
529-
bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind());
514+
#[allow(rustc::diagnostic_outside_of_impl, rustc::untranslatable_diagnostic)]
515+
tcx.dcx()
516+
.struct_span_err(
517+
*attr_span,
518+
format!("invalid `cfi_encoding` for `{:?}`", ty.kind()),
519+
)
520+
.emit();
530521
}
531522
} else {
532523
let name = tcx.item_name(*def_id).to_string();
533524
let _ = write!(s, "{}{}", name.len(), name);
534-
}
525+
};
526+
535527
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
536528
typeid.push_str(&s);
537529
}

compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66
77
use std::iter;
88

9-
use rustc_hir as hir;
10-
use rustc_hir::LangItem;
9+
use rustc_hir::attrs::AttributeKind;
10+
use rustc_hir::{self as hir, LangItem, find_attr};
1111
use rustc_middle::bug;
1212
use rustc_middle::ty::{
1313
self, AssocContainer, ExistentialPredicateStableCmpExt as _, Instance, IntTy, List, TraitRef,
1414
Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UintTy,
1515
};
1616
use rustc_span::def_id::DefId;
17-
use rustc_span::{DUMMY_SP, sym};
1817
use rustc_trait_selection::traits;
1918
use tracing::{debug, instrument};
2019

@@ -138,7 +137,10 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for TransformTy<'tcx> {
138137
{
139138
// Don't transform repr(transparent) types with an user-defined CFI encoding to
140139
// preserve the user-defined CFI encoding.
141-
if let Some(_) = self.tcx.get_attr(adt_def.did(), sym::cfi_encoding) {
140+
if find_attr!(
141+
self.tcx.get_all_attrs(adt_def.did()),
142+
AttributeKind::CfiEncoding { .. }
143+
) {
142144
return t;
143145
}
144146
let variant = adt_def.non_enum_variant();

tests/ui/attributes/malformed-attrs.stderr

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,6 @@ LL - #[must_not_suspend()]
5555
LL + #[must_not_suspend]
5656
|
5757

58-
error: malformed `cfi_encoding` attribute input
59-
--> $DIR/malformed-attrs.rs:140:1
60-
|
61-
LL | #[cfi_encoding]
62-
| ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]`
63-
6458
error: malformed `allow` attribute input
6559
--> $DIR/malformed-attrs.rs:184:1
6660
|
@@ -536,6 +530,15 @@ LL | #[rustc_layout_scalar_valid_range_end]
536530
| expected this to be a list
537531
| help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]`
538532

533+
error[E0539]: malformed `cfi_encoding` attribute input
534+
--> $DIR/malformed-attrs.rs:140:1
535+
|
536+
LL | #[cfi_encoding]
537+
| ^^^^^^^^^^^^^^^
538+
| |
539+
| expected this to be of the form `cfi_encoding = "..."`
540+
| help: must be of the form: `#[cfi_encoding = "encoding"]`
541+
539542
error[E0565]: malformed `marker` attribute input
540543
--> $DIR/malformed-attrs.rs:161:1
541544
|
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
error: malformed `cfi_encoding` attribute input
1+
error[E0539]: malformed `cfi_encoding` attribute input
22
--> $DIR/invalid-attr-encoding.rs:10:1
33
|
44
LL | #[cfi_encoding]
5-
| ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]`
5+
| ^^^^^^^^^^^^^^^
6+
| |
7+
| expected this to be of the form `cfi_encoding = "..."`
8+
| help: must be of the form: `#[cfi_encoding = "encoding"]`
69

710
error: aborting due to 1 previous error
811

12+
For more information about this error, try `rustc --explain E0539`.

0 commit comments

Comments
 (0)