Implement ffi_returns_twice attribute
This commit is contained in:
parent
bcfb5e8ac3
commit
c4b46ace55
13 changed files with 79 additions and 0 deletions
|
@ -2518,6 +2518,9 @@ bitflags! {
|
|||
/// `#[used]`: indicates that LLVM can't eliminate this function (but the
|
||||
/// linker can!).
|
||||
const USED = 1 << 9;
|
||||
/// #[ffi_returns_twice], indicates that an extern function can return
|
||||
/// multiple times
|
||||
const FFI_RETURNS_TWICE = 1 << 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -223,6 +223,9 @@ pub fn from_fn_attrs(
|
|||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::COLD) {
|
||||
Attribute::Cold.apply_llfn(Function, llfn);
|
||||
}
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_RETURNS_TWICE) {
|
||||
Attribute::ReturnsTwice.apply_llfn(Function, llfn);
|
||||
}
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
|
||||
naked(llfn, true);
|
||||
}
|
||||
|
|
|
@ -114,6 +114,7 @@ pub enum Attribute {
|
|||
SanitizeMemory = 22,
|
||||
NonLazyBind = 23,
|
||||
OptimizeNone = 24,
|
||||
ReturnsTwice = 25,
|
||||
}
|
||||
|
||||
/// LLVMIntPredicate
|
||||
|
|
|
@ -2388,6 +2388,18 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
|
|||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR;
|
||||
} else if attr.check_name("unwind") {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::UNWIND;
|
||||
} else if attr.check_name("ffi_returns_twice") {
|
||||
if tcx.is_foreign_item(id) {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE;
|
||||
} else {
|
||||
// `#[ffi_returns_twice]` is only allowed `extern fn`s
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
attr.span,
|
||||
E0723,
|
||||
"`#[ffi_returns_twice]` may only be used on `extern fn`s"
|
||||
).emit();
|
||||
}
|
||||
} else if attr.check_name("rustc_allocator_nounwind") {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND;
|
||||
} else if attr.check_name("naked") {
|
||||
|
|
|
@ -4738,4 +4738,5 @@ register_diagnostics! {
|
|||
E0698, // type inside generator must be known in this context
|
||||
E0719, // duplicate values for associated type binding
|
||||
E0722, // Malformed #[optimize] attribute
|
||||
E0723, // `#[ffi_returns_twice]` is only allowed in `extern fn`
|
||||
}
|
||||
|
|
|
@ -290,6 +290,9 @@ declare_features! (
|
|||
// The `repr(i128)` annotation for enums.
|
||||
(active, repr128, "1.16.0", Some(35118), None),
|
||||
|
||||
// Allows the use of `#[ffi_returns_twice]` on extern functions.
|
||||
(active, ffi_returns_twice, "1.34.0", Some(58314), None),
|
||||
|
||||
// The `unadjusted` ABI; perma-unstable.
|
||||
//
|
||||
// rustc internal
|
||||
|
@ -1128,6 +1131,11 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu
|
|||
"the `#[naked]` attribute \
|
||||
is an experimental feature",
|
||||
cfg_fn!(naked_functions))),
|
||||
("ffi_returns_twice", Whitelisted, template!(Word), Gated(Stability::Unstable,
|
||||
"ffi_returns_twice",
|
||||
"the `#[ffi_returns_twice]` attribute \
|
||||
is an experimental feature",
|
||||
cfg_fn!(ffi_returns_twice))),
|
||||
("target_feature", Whitelisted, template!(List: r#"enable = "name""#), Ungated),
|
||||
("export_name", Whitelisted, template!(NameValueStr: "name"), Ungated),
|
||||
("inline", Whitelisted, template!(Word, List: "always|never"), Ungated),
|
||||
|
|
|
@ -190,6 +190,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
|
|||
return Attribute::NonLazyBind;
|
||||
case OptimizeNone:
|
||||
return Attribute::OptimizeNone;
|
||||
case ReturnsTwice:
|
||||
return Attribute::ReturnsTwice;
|
||||
}
|
||||
report_fatal_error("bad AttributeKind");
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ enum LLVMRustAttribute {
|
|||
SanitizeMemory = 22,
|
||||
NonLazyBind = 23,
|
||||
OptimizeNone = 24,
|
||||
ReturnsTwice = 25,
|
||||
};
|
||||
|
||||
typedef struct OpaqueRustString *RustStringRef;
|
||||
|
|
15
src/test/codegen/ffi-returns-twice.rs
Normal file
15
src/test/codegen/ffi-returns-twice.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// compile-flags: -C no-prepopulate-passes
|
||||
#![crate_type = "lib"]
|
||||
#![feature(ffi_returns_twice)]
|
||||
|
||||
extern {
|
||||
// CHECK-LABEL: @foo()
|
||||
// CHECK: attributes #1 = { {{.*}}returns_twice{{.*}} }
|
||||
#[no_mangle]
|
||||
#[ffi_returns_twice]
|
||||
pub fn foo();
|
||||
}
|
||||
|
||||
pub fn bar() {
|
||||
unsafe { foo() }
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
// ignore-tidy-linelength
|
||||
#![crate_type = "lib"]
|
||||
|
||||
extern {
|
||||
#[ffi_returns_twice] //~ ERROR the `#[ffi_returns_twice]` attribute is an experimental feature (see issue #58314)
|
||||
pub fn foo();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
error[E0658]: the `#[ffi_returns_twice]` attribute is an experimental feature (see issue #58314)
|
||||
--> $DIR/feature-gate-ffi_returns_twice.rs:5:5
|
||||
|
|
||||
LL | #[ffi_returns_twice] //~ ERROR the `#[ffi_returns_twice]` attribute is an experimental feature (see issue #58314)
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(ffi_returns_twice)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
6
src/test/ui/ffi_returns_twice.rs
Normal file
6
src/test/ui/ffi_returns_twice.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
// ignore-tidy-linelength
|
||||
#![feature(ffi_returns_twice)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
#[ffi_returns_twice] //~ ERROR `#[ffi_returns_twice]` may only be used on `extern fn`s
|
||||
pub fn foo() {}
|
9
src/test/ui/ffi_returns_twice.stderr
Normal file
9
src/test/ui/ffi_returns_twice.stderr
Normal file
|
@ -0,0 +1,9 @@
|
|||
error[E0723]: `#[ffi_returns_twice]` may only be used on `extern fn`s
|
||||
--> $DIR/ffi_returns_twice.rs:5:1
|
||||
|
|
||||
LL | #[ffi_returns_twice] //~ ERROR `#[ffi_returns_twice]` may only be used on `extern fn`s
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0723`.
|
Loading…
Add table
Reference in a new issue