Skip to content

Commit 73dbdfb

Browse files
committed
Port #[cfi_encoding] to attribute parser
1 parent 38c6672 commit 73dbdfb

File tree

11 files changed

+84
-63
lines changed

11 files changed

+84
-63
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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 = AllowedTargets::AllowListWarnRest(&[
6+
Allow(Target::Struct),
7+
Allow(Target::ForeignTy),
8+
Allow(Target::Enum),
9+
Allow(Target::Union),
10+
]);
11+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
12+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
13+
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "encoding");
14+
15+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
16+
let Some(name_value) = args.name_value() else {
17+
cx.expected_name_value(cx.attr_span, Some(sym::cfi_encoding));
18+
return None;
19+
};
20+
21+
let Some(value_str) = name_value.value_as_str() else {
22+
cx.expected_string_literal(name_value.value_span, None);
23+
return None;
24+
};
25+
26+
if value_str.as_str().trim().is_empty() {
27+
cx.expected_non_empty_string_literal(name_value.value_span);
28+
return None;
29+
}
30+
31+
Some(AttributeKind::CfiEncoding { encoding: value_str })
32+
}
33+
}

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 { 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
@@ -298,6 +298,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
298298
| AttributeKind::PinV2(..)
299299
| AttributeKind::WindowsSubsystem(..)
300300
| AttributeKind::ThreadLocal
301+
| AttributeKind::CfiEncoding { .. }
301302
) => { /* do nothing */ }
302303
Attribute::Unparsed(attr_item) => {
303304
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: 20 additions & 49 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,20 @@ 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(encoding) = find_attr!(tcx.get_all_attrs(def_id), AttributeKind::CfiEncoding { encoding } => encoding)
451+
{
452+
let encoding = encoding.as_str();
450453
// 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();
476-
}
477-
} else {
478-
bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind());
454+
s.push_str(&encoding);
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", "n", "o",
460+
"f", "d", "e", "g", "z", "Dh",
461+
];
462+
if !builtin_types.contains(&encoding) {
463+
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
479464
}
480465
} else if options.contains(EncodeTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c() {
481466
// For cross-language LLVM CFI support, the encoding must be compatible at the FFI
@@ -508,30 +493,16 @@ pub(crate) fn encode_ty<'tcx>(
508493
ty::Foreign(def_id) => {
509494
// <length><name>, where <name> is <unscoped-name>
510495
let mut s = String::new();
511-
if let Some(cfi_encoding) = tcx.get_attr(*def_id, sym::cfi_encoding) {
496+
497+
if let Some(encoding) = find_attr!(tcx.get_all_attrs(*def_id), AttributeKind::CfiEncoding {encoding} => encoding)
498+
{
512499
// 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-
}
528-
} else {
529-
bug!("encode_ty: invalid `cfi_encoding` for `{:?}`", ty.kind());
530-
}
500+
s.push_str(encoding.as_str());
531501
} else {
532502
let name = tcx.item_name(*def_id).to_string();
533503
let _ = write!(s, "{}{}", name.len(), name);
534504
}
505+
535506
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
536507
typeid.push_str(&s);
537508
}

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
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
};
16+
use rustc_span::DUMMY_SP;
1617
use rustc_span::def_id::DefId;
17-
use rustc_span::{DUMMY_SP, sym};
1818
use rustc_trait_selection::traits;
1919
use tracing::{debug, instrument};
2020

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

tests/ui/attributes/malformed-attrs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub fn test3() {}
137137
//~^ ERROR malformed
138138
#[must_not_suspend()]
139139
//~^ ERROR malformed
140-
#[cfi_encoding]
140+
#[cfi_encoding = ""]
141141
//~^ ERROR malformed
142142
struct Test;
143143

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
|
@@ -530,6 +524,15 @@ LL | #[rustc_layout_scalar_valid_range_end]
530524
| expected this to be a list
531525
| help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]`
532526

527+
error[E0539]: malformed `cfi_encoding` attribute input
528+
--> $DIR/malformed-attrs.rs:140:1
529+
|
530+
LL | #[cfi_encoding = ""]
531+
| ^^^^^^^^^^^^^^^^^--^
532+
| | |
533+
| | string is not allowed to be empty
534+
| help: must be of the form: `#[cfi_encoding = "encoding"]`
535+
533536
error[E0565]: malformed `marker` attribute input
534537
--> $DIR/malformed-attrs.rs:161:1
535538
|

0 commit comments

Comments
 (0)