From f14bc54b06ef300fd3a7bf2b2493e78c6136312b Mon Sep 17 00:00:00 2001 From: Graham Fawcett Date: Fri, 16 Dec 2011 11:04:11 -0500 Subject: [PATCH] allow #[link_args] with #[nolink]. For now, fail if two modules link same lib, and second has link_args. I think it should undefined to have multiple modules that link in the same library, but provide different link arguments. Unfortunately we don't track link_args by module -- they are just appended as discovered into the crate store -- but for now, it should be an error to provide link_args on a module that's already been included (with or without link_args). --- src/comp/metadata/creader.rs | 33 +++++++++++-------- src/comp/metadata/cstore.rs | 2 +- .../compile-fail/nolink-with-link-args.rs | 11 +++++++ src/test/compile-fail/redundant-link-args.rs | 17 ++++++++++ 4 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 src/test/compile-fail/nolink-with-link-args.rs create mode 100644 src/test/compile-fail/redundant-link-args.rs diff --git a/src/comp/metadata/creader.rs b/src/comp/metadata/creader.rs index a79329ea5a3d..9f74f7afece1 100644 --- a/src/comp/metadata/creader.rs +++ b/src/comp/metadata/creader.rs @@ -60,23 +60,28 @@ fn visit_item(e: env, i: @ast::item) { let cstore = e.sess.get_cstore(); let native_name = i.ident; - if vec::len(attr::find_attrs_by_name(i.attrs, "nolink")) > 0u { - ret; + let already_added = false; + if vec::len(attr::find_attrs_by_name(i.attrs, "nolink")) == 0u { + alt attr::get_meta_item_value_str_by_name(i.attrs, "link_name") { + some(nn) { native_name = nn; } + none. { } + } + if native_name == "" { + e.sess.span_fatal(i.span, + "empty #[link_name] not allowed; use #[nolink]."); + } + already_added = !cstore::add_used_library(cstore, native_name); } - alt attr::get_meta_item_value_str_by_name(i.attrs, "link_name") { - some(nn) { native_name = nn; } - none. { } + let link_args = attr::find_attrs_by_name(i.attrs, "link_args"); + if vec::len(link_args) > 0u && already_added { + e.sess.span_fatal(i.span, "library '" + native_name + + "' already added: can't specify link_args."); } - if native_name == "" { - e.sess.span_fatal(i.span, - "empty #[link_name] not allowed; use #[nolink]."); - } - if !cstore::add_used_library(cstore, native_name) { ret; } - for a: ast::attribute in - attr::find_attrs_by_name(i.attrs, "link_args") { - + for a: ast::attribute in link_args { alt attr::get_meta_item_value_str(attr::attr_meta(a)) { - some(linkarg) { cstore::add_used_link_args(cstore, linkarg); } + some(linkarg) { + cstore::add_used_link_args(cstore, linkarg); + } none. {/* fallthrough */ } } } diff --git a/src/comp/metadata/cstore.rs b/src/comp/metadata/cstore.rs index b1e2692584c7..ae7119fbeed6 100644 --- a/src/comp/metadata/cstore.rs +++ b/src/comp/metadata/cstore.rs @@ -90,7 +90,7 @@ fn get_used_crate_files(cstore: cstore) -> [str] { } fn add_used_library(cstore: cstore, lib: str) -> bool { - if lib == "" { ret false; } + assert lib != ""; if vec::member(lib, p(cstore).used_libraries) { ret false; } p(cstore).used_libraries += [lib]; diff --git a/src/test/compile-fail/nolink-with-link-args.rs b/src/test/compile-fail/nolink-with-link-args.rs new file mode 100644 index 000000000000..07efff7571c3 --- /dev/null +++ b/src/test/compile-fail/nolink-with-link-args.rs @@ -0,0 +1,11 @@ +// error-pattern:aFdEfSeVEE + +/* We're testing that link_args are indeed passed when nolink is specified. +So we try to compile with junk link_args and make sure they are visible in +the compiler output. */ + +#[link_args = "aFdEfSeVEEE"] +#[nolink] +native mod m1 { } + +fn main() { } \ No newline at end of file diff --git a/src/test/compile-fail/redundant-link-args.rs b/src/test/compile-fail/redundant-link-args.rs new file mode 100644 index 000000000000..ca06125880e3 --- /dev/null +++ b/src/test/compile-fail/redundant-link-args.rs @@ -0,0 +1,17 @@ +// error-pattern:library 'm' already added: can't specify link_args. + +/* I think it should undefined to have multiple modules that link in the same + library, but provide different link arguments. Unfortunately we don't track + link_args by module -- they are just appended as discovered into the crate + store -- but for now, it should be an error to provide link_args on a module + that's already been included (with or without link_args). */ + +#[link_name= "m"] +#[link_args="-foo"] // this could have been elided. +native mod m1 { +} + +#[link_name= "m"] +#[link_args="-bar"] // this is the actual error trigger. +native mod m2 { +}