Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature gate for raw_dylib. #63948

Merged
merged 5 commits into from
Oct 7, 2019
Merged
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
6 changes: 6 additions & 0 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2669,6 +2669,11 @@ pub struct CodegenFnAttrs {
/// probably isn't set when this is set, this is for foreign items while
/// `#[export_name]` is for Rust-defined functions.
pub link_name: Option<Symbol>,
/// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an
/// imported function has in the dynamic library. Note that this must not
/// be set when `link_name` is set. This is for foreign items with the
/// "raw-dylib" kind.
pub link_ordinal: Option<usize>,
/// The `#[target_feature(enable = "...")]` attribute and the enabled
/// features (only enabled features are supported right now).
pub target_features: Vec<Symbol>,
Expand Down Expand Up @@ -2728,6 +2733,7 @@ impl CodegenFnAttrs {
optimize: OptimizeAttr::None,
export_name: None,
link_name: None,
link_ordinal: None,
target_features: vec![],
linkage: None,
link_section: None,
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ pub enum NativeLibraryKind {
NativeStaticNobundle,
/// macOS-specific
NativeFramework,
/// Windows dynamic library without import library.
NativeRawDylib,
/// default way to specify a dynamic library
NativeUnknown,
}
Expand Down
16 changes: 13 additions & 3 deletions src/librustc_codegen_ssa/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
NativeLibraryKind::NativeStatic => {}
NativeLibraryKind::NativeStaticNobundle |
NativeLibraryKind::NativeFramework |
NativeLibraryKind::NativeRawDylib |
NativeLibraryKind::NativeUnknown => continue,
}
if let Some(name) = lib.name {
Expand Down Expand Up @@ -883,7 +884,8 @@ pub fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLibrary
Some(format!("-framework {}", name))
},
// These are included, no need to print them
NativeLibraryKind::NativeStatic => None,
NativeLibraryKind::NativeStatic |
NativeLibraryKind::NativeRawDylib => None,
}
})
.collect();
Expand Down Expand Up @@ -1293,7 +1295,11 @@ pub fn add_local_native_libraries(cmd: &mut dyn Linker,
NativeLibraryKind::NativeUnknown => cmd.link_dylib(name),
NativeLibraryKind::NativeFramework => cmd.link_framework(name),
NativeLibraryKind::NativeStaticNobundle => cmd.link_staticlib(name),
NativeLibraryKind::NativeStatic => cmd.link_whole_staticlib(name, &search_path)
NativeLibraryKind::NativeStatic => cmd.link_whole_staticlib(name, &search_path),
NativeLibraryKind::NativeRawDylib => {
// FIXME(#58713): Proper handling for raw dylibs.
bug!("raw_dylib feature not yet implemented");
},
}
}
}
Expand Down Expand Up @@ -1678,7 +1684,11 @@ pub fn add_upstream_native_libraries(
// ignore statically included native libraries here as we've
// already included them when we included the rust library
// previously
NativeLibraryKind::NativeStatic => {}
NativeLibraryKind::NativeStatic => {},
NativeLibraryKind::NativeRawDylib => {
// FIXME(#58713): Proper handling for raw dylibs.
bug!("raw_dylib feature not yet implemented");
},
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,11 @@ pub fn provide(providers: &mut Providers<'_>) {
// resolve! Does this work? Unsure! That's what the issue is about
*providers = Providers {
is_dllimport_foreign_item: |tcx, id| {
tcx.native_library_kind(id) == Some(NativeLibraryKind::NativeUnknown)
match tcx.native_library_kind(id) {
Some(NativeLibraryKind::NativeUnknown) |
Some(NativeLibraryKind::NativeRawDylib) => true,
_ => false,
}
},
is_statically_included_foreign_item: |tcx, id| {
match tcx.native_library_kind(id) {
Expand Down
9 changes: 9 additions & 0 deletions src/librustc_metadata/native_libs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
"static-nobundle" => cstore::NativeStaticNobundle,
"dylib" => cstore::NativeUnknown,
"framework" => cstore::NativeFramework,
"raw-dylib" => cstore::NativeRawDylib,
k => {
struct_span_err!(self.tcx.sess, item.span(), E0458,
"unknown kind: `{}`", k)
Expand Down Expand Up @@ -169,6 +170,14 @@ impl Collector<'tcx> {
GateIssue::Language,
"kind=\"static-nobundle\" is unstable");
}
if lib.kind == cstore::NativeRawDylib &&
!self.tcx.features().raw_dylib {
feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
sym::raw_dylib,
span.unwrap_or_else(|| syntax_pos::DUMMY_SP),
GateIssue::Language,
"kind=\"raw-dylib\" is unstable");
}
self.libs.push(lib);
}

Expand Down
53 changes: 53 additions & 0 deletions src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2560,6 +2560,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
let whitelist = tcx.target_features_whitelist(LOCAL_CRATE);

let mut inline_span = None;
let mut link_ordinal_span = None;
for attr in attrs.iter() {
if attr.check_name(sym::cold) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
Expand Down Expand Up @@ -2641,6 +2642,11 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
}
} else if attr.check_name(sym::link_name) {
codegen_fn_attrs.link_name = attr.value_str();
} else if attr.check_name(sym::link_ordinal) {
link_ordinal_span = Some(attr.span);
if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) {
codegen_fn_attrs.link_ordinal = ordinal;
}
}
}

Expand Down Expand Up @@ -2718,6 +2724,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
// purpose functions as they wouldn't have the right target features
// enabled. For that reason we also forbid #[inline(always)] as it can't be
// respected.

if codegen_fn_attrs.target_features.len() > 0 {
if codegen_fn_attrs.inline == InlineAttr::Always {
if let Some(span) = inline_span {
Expand All @@ -2742,6 +2749,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
codegen_fn_attrs.export_name = Some(name);
codegen_fn_attrs.link_name = Some(name);
}
check_link_name_xor_ordinal(tcx, &codegen_fn_attrs, link_ordinal_span);

// Internal symbols to the standard library all have no_mangle semantics in
// that they have defined symbol names present in the function name. This
Expand All @@ -2752,3 +2760,48 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {

codegen_fn_attrs
}

fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<usize> {
use syntax::ast::{Lit, LitIntType, LitKind};
let meta_item_list = attr.meta_item_list();
let meta_item_list: Option<&[ast::NestedMetaItem]> = meta_item_list.as_ref().map(Vec::as_ref);
let sole_meta_list = match meta_item_list {
Some([item]) => item.literal(),
_ => None,
};
if let Some(Lit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) = sole_meta_list {
if *ordinal <= std::usize::MAX as u128 {
Some(*ordinal as usize)
} else {
let msg = format!(
"ordinal value in `link_ordinal` is too large: `{}`",
&ordinal
);
tcx.sess.struct_span_err(attr.span, &msg)
.note("the value may not exceed `std::usize::MAX`")
.emit();
None
}
} else {
tcx.sess.struct_span_err(attr.span, "illegal ordinal format in `link_ordinal`")
.note("an unsuffixed integer value, e.g., `1`, is expected")
.emit();
None
}
}

fn check_link_name_xor_ordinal(
tcx: TyCtxt<'_>,
codegen_fn_attrs: &CodegenFnAttrs,
inline_span: Option<Span>,
) {
if codegen_fn_attrs.link_name.is_none() || codegen_fn_attrs.link_ordinal.is_none() {
return;
}
let msg = "cannot use `#[link_name]` with `#[link_ordinal]`";
if let Some(span) = inline_span {
tcx.sess.span_err(span, msg);
} else {
tcx.sess.err(msg);
}
}
4 changes: 4 additions & 0 deletions src/libsyntax/feature_gate/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,9 @@ declare_features! (
/// Allows the definition of `const extern fn` and `const unsafe extern fn`.
(active, const_extern_fn, "1.40.0", Some(64926), None),

// Allows the use of raw-dylibs (RFC 2627).
(active, raw_dylib, "1.40.0", Some(58713), None),

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
Expand All @@ -536,4 +539,5 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
sym::const_generics,
sym::or_patterns,
sym::let_chains,
sym::raw_dylib,
];
4 changes: 4 additions & 0 deletions src/libsyntax/feature_gate/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
"the `link_args` attribute is experimental and not portable across platforms, \
it is recommended to use `#[link(name = \"foo\")] instead",
),
gated!(
Centril marked this conversation as resolved.
Show resolved Hide resolved
link_ordinal, Whitelisted, template!(List: "ordinal"), raw_dylib,
experimental!(link_ordinal)
),
Centril marked this conversation as resolved.
Show resolved Hide resolved

// Plugins:
(
Expand Down
2 changes: 2 additions & 0 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ symbols! {
link_cfg,
link_llvm_intrinsics,
link_name,
link_ordinal,
link_section,
LintPass,
lint_reasons,
Expand Down Expand Up @@ -531,6 +532,7 @@ symbols! {
RangeInclusive,
RangeTo,
RangeToInclusive,
raw_dylib,
raw_identifiers,
Ready,
reason,
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#[link(name="foo")]
extern {
#[link_ordinal(42)]
//~^ ERROR: the `#[link_ordinal]` attribute is an experimental feature
fn foo();
}

fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib-2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0658]: the `#[link_ordinal]` attribute is an experimental feature
--> $DIR/feature-gate-raw-dylib-2.rs:3:5
|
LL | #[link_ordinal(42)]
| ^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/58713
= help: add `#![feature(raw_dylib)]` to the crate attributes to enable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.
5 changes: 5 additions & 0 deletions src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[link(name="foo", kind="raw-dylib")]
//~^ ERROR: kind="raw-dylib" is unstable
extern {}

fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0658]: kind="raw-dylib" is unstable
--> $DIR/feature-gate-raw-dylib.rs:1:1
|
LL | #[link(name="foo", kind="raw-dylib")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/58713
= help: add `#![feature(raw_dylib)]` to the crate attributes to enable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.
12 changes: 12 additions & 0 deletions src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![feature(raw_dylib)]
//~^ WARN the feature `raw_dylib` is incomplete and may cause the compiler to crash

#[link(name="foo")]
extern {
#[link_name="foo"]
#[link_ordinal(42)]
//~^ ERROR cannot use `#[link_name]` with `#[link_ordinal]`
fn foo();
}

fn main() {}
16 changes: 16 additions & 0 deletions src/test/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
warning: the feature `raw_dylib` is incomplete and may cause the compiler to crash
--> $DIR/link-ordinal-and-name.rs:1:12
|
LL | #![feature(raw_dylib)]
| ^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error: cannot use `#[link_name]` with `#[link_ordinal]`
--> $DIR/link-ordinal-and-name.rs:7:5
|
LL | #[link_ordinal(42)]
| ^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

11 changes: 11 additions & 0 deletions src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![feature(raw_dylib)]
//~^ WARN the feature `raw_dylib` is incomplete and may cause the compiler to crash

#[link(name="foo")]
extern {
#[link_ordinal("JustMonika")]
//~^ ERROR illegal ordinal format in `link_ordinal`
fn foo();
}

fn main() {}
18 changes: 18 additions & 0 deletions src/test/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
warning: the feature `raw_dylib` is incomplete and may cause the compiler to crash
--> $DIR/link-ordinal-invalid-format.rs:1:12
|
LL | #![feature(raw_dylib)]
| ^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error: illegal ordinal format in `link_ordinal`
--> $DIR/link-ordinal-invalid-format.rs:6:5
|
LL | #[link_ordinal("JustMonika")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: an unsuffixed integer value, e.g., `1`, is expected

error: aborting due to previous error

11 changes: 11 additions & 0 deletions src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![feature(raw_dylib)]
//~^ WARN the feature `raw_dylib` is incomplete and may cause the compiler to crash

#[link(name="foo")]
extern {
#[link_ordinal(18446744073709551616)]
//~^ ERROR ordinal value in `link_ordinal` is too large: `18446744073709551616`
fn foo();
}

fn main() {}
18 changes: 18 additions & 0 deletions src/test/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
warning: the feature `raw_dylib` is incomplete and may cause the compiler to crash
--> $DIR/link-ordinal-too-large.rs:1:12
|
LL | #![feature(raw_dylib)]
| ^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error: ordinal value in `link_ordinal` is too large: `18446744073709551616`
--> $DIR/link-ordinal-too-large.rs:6:5
|
LL | #[link_ordinal(18446744073709551616)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the value may not exceed `std::usize::MAX`

error: aborting due to previous error