From 6f8bc404f8ceea0b8981ae2afd5d4414d7a26004 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 5 Jul 2011 11:46:02 -0700 Subject: [PATCH] Error if the link attribute has duplicate items. Issue #614 --- src/comp/back/link.rs | 12 ++++++------ src/comp/front/attr.rs | 16 ++++++++++++++++ src/test/compile-fail/dup-link-name.rs | 7 +++++++ 3 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 src/test/compile-fail/dup-link-name.rs diff --git a/src/comp/back/link.rs b/src/comp/back/link.rs index 47168a3dd8c..12ada918edb 100644 --- a/src/comp/back/link.rs +++ b/src/comp/back/link.rs @@ -286,19 +286,19 @@ fn build_link_meta(&session::session sess, &ast::crate c, option::t[str] vers, vec[@ast::meta_item] cmh_items); - fn provided_link_metas(&ast::crate c) -> provided_metas { + fn provided_link_metas(&session::session sess, + &ast::crate c) -> provided_metas { let option::t[str] name = none; let option::t[str] vers = none; let vec[@ast::meta_item] cmh_items = []; - for (@ast::meta_item meta in - attr::find_linkage_metas(c.node.attrs)) { + auto linkage_metas = attr::find_linkage_metas(c.node.attrs); + attr::require_unique_names(sess, linkage_metas); + for (@ast::meta_item meta in linkage_metas) { alt (meta.node) { case (ast::meta_name_value("name", ?v)) { - // FIXME: Should probably warn about duplicate name items name = some(v); } case (ast::meta_name_value("vers", ?v)) { - // FIXME: Should probably warn about duplicate value items vers = some(v); } case (_) { @@ -361,7 +361,7 @@ fn build_link_meta(&session::session sess, &ast::crate c, }; } - auto provided_metas = provided_link_metas(c); + auto provided_metas = provided_link_metas(sess, c); auto name = crate_meta_name(sess, c, output, provided_metas); auto vers = crate_meta_vers(sess, c, provided_metas); auto extras_hash = crate_meta_extras_hash(sha, c, provided_metas); diff --git a/src/comp/front/attr.rs b/src/comp/front/attr.rs index 00e64e33f6b..acd24e8353e 100644 --- a/src/comp/front/attr.rs +++ b/src/comp/front/attr.rs @@ -1,9 +1,12 @@ // Functions dealing with attributes and meta_items import std::vec; +import std::str; +import std::map; import std::option; import syntax::ast; import util::common; +import driver::session; export attr_metas; export find_linkage_metas; @@ -12,6 +15,7 @@ export find_meta_items_by_name; export contains; export sort_meta_items; export remove_meta_items_by_name; +export require_unique_names; export get_attr_name; export mk_name_value_item; export mk_list_item; @@ -168,6 +172,18 @@ fn remove_meta_items_by_name(&vec[@ast::meta_item] items, ret vec::filter_map(filter, items); } +fn require_unique_names(&session::session sess, &vec[@ast::meta_item] metas) { + auto map = map::mk_hashmap[str, ()](str::hash, str::eq); + for (@ast::meta_item meta in metas) { + auto name = get_meta_item_name(meta); + if (map.contains_key(name)) { + sess.span_fatal(meta.span, + #fmt("duplicate meta item `%s`", name)); + } + map.insert(name, ()); + } +} + fn span[T](&T item) -> ast::spanned[T] { ret rec(node=item, span=rec(lo=0u, hi=0u)); } diff --git a/src/test/compile-fail/dup-link-name.rs b/src/test/compile-fail/dup-link-name.rs new file mode 100644 index 00000000000..7ef6314edb3 --- /dev/null +++ b/src/test/compile-fail/dup-link-name.rs @@ -0,0 +1,7 @@ +// xfail-stage0 +// error-pattern:duplicate meta item `name` + +#[link(name = "test", + name)]; + +fn main() {} \ No newline at end of file