Error if the link attribute has duplicate items. Issue #614

This commit is contained in:
Brian Anderson 2011-07-05 11:46:02 -07:00
parent 4349eaed84
commit 6f8bc404f8
3 changed files with 29 additions and 6 deletions

View File

@ -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);

View File

@ -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));
}

View File

@ -0,0 +1,7 @@
// xfail-stage0
// error-pattern:duplicate meta item `name`
#[link(name = "test",
name)];
fn main() {}