mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 23:25:24 +02:00
gccrs: Correctly emit warning on invalid attributes
We were emitting warning even on attribute that were then removed by the cfgstrip pass. We cannot move the cfg strip pass before the attribute checking because we need to first emit malformed input error messages. This means the attribute checking pass must know if an attribute input may be removed later down the line. gcc/rust/ChangeLog: * ast/rust-ast.cc (MetaItemPathExpr::to_attribute): Remove cast to literal. (AttrInputMetaItemContainer::separate_cfg_attrs): Remove PathExpr specific code. * expand/rust-cfg-strip.cc (expand_cfg_attrs): Remove the whole attribute if condition's result is false. * util/rust-attributes.cc (AttributeChecker::visit): Remove specific code section for meta item container. Do not check input if configuration does not match condition. gcc/testsuite/ChangeLog: * rust/compile/attr_malformed_path.rs: Filter existing test to x86_64 exclusively, add two new tests that appear when visiting the resulting expression. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
This commit is contained in:
committed by
Arthur Cohen
parent
0903f9bbe6
commit
ab9ea3ecfc
@@ -4200,10 +4200,8 @@ MetaListNameValueStr::to_attribute () const
|
||||
Attribute
|
||||
MetaItemPathExpr::to_attribute () const
|
||||
{
|
||||
rust_assert (expr->is_literal ());
|
||||
auto &lit = static_cast<LiteralExpr &> (*expr);
|
||||
return Attribute (path, std::unique_ptr<AttrInputLiteral> (
|
||||
new AttrInputLiteral (lit)));
|
||||
auto input = std::make_unique<AttrInputExpr> (expr->clone_expr ());
|
||||
return Attribute (path, std::move (input));
|
||||
}
|
||||
|
||||
std::vector<Attribute>
|
||||
@@ -4219,13 +4217,9 @@ AttrInputMetaItemContainer::separate_cfg_attrs () const
|
||||
|
||||
for (auto it = items.begin () + 1; it != items.end (); ++it)
|
||||
{
|
||||
if ((*it)->get_kind () == MetaItemInner::Kind::MetaItem
|
||||
&& static_cast<MetaItem &> (**it).get_item_kind ()
|
||||
== MetaItem::ItemKind::PathExpr
|
||||
&& !static_cast<MetaItemPathExpr &> (**it).get_expr ().is_literal ())
|
||||
continue;
|
||||
auto &item = **it;
|
||||
|
||||
Attribute attr = (*it)->to_attribute ();
|
||||
Attribute attr = item.to_attribute ();
|
||||
if (attr.is_empty ())
|
||||
{
|
||||
/* TODO should this be an error that causes us to chuck out
|
||||
|
||||
@@ -93,6 +93,9 @@ expand_cfg_attrs (AST::AttrVec &attrs)
|
||||
|
||||
if (attr.check_cfg_predicate (session))
|
||||
{
|
||||
// Key has been found we need to remove the conditional part of
|
||||
// the attribute and insert the content back
|
||||
|
||||
// split off cfg_attr
|
||||
AST::AttrVec new_attrs = attr.separate_cfg_attrs ();
|
||||
|
||||
@@ -110,6 +113,12 @@ expand_cfg_attrs (AST::AttrVec &attrs)
|
||||
*/
|
||||
i--;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Key has not been found, remove the whole attribute
|
||||
attrs.erase (attrs.begin () + i);
|
||||
i--;
|
||||
}
|
||||
|
||||
/* do something - if feature (first token in tree) is in fact enabled,
|
||||
* make tokens listed afterwards into attributes. i.e.: for
|
||||
|
||||
@@ -553,34 +553,28 @@ check_lint_attribute (const AST::Attribute &attribute, const char *name)
|
||||
void
|
||||
AttributeChecker::visit (AST::Attribute &attribute)
|
||||
{
|
||||
if (!attribute.empty_input ())
|
||||
auto &session = Session::get_instance ();
|
||||
if (attribute.get_path () == Values::Attributes::CFG_ATTR)
|
||||
{
|
||||
const auto &attr_input = attribute.get_attr_input ();
|
||||
auto type = attr_input.get_attr_input_type ();
|
||||
if (type == AST::AttrInput::AttrInputType::TOKEN_TREE)
|
||||
{
|
||||
const auto &option = static_cast<const AST::DelimTokenTree &> (
|
||||
attribute.get_attr_input ());
|
||||
std::unique_ptr<AST::AttrInputMetaItemContainer> meta_item (
|
||||
option.parse_to_meta_item ());
|
||||
AST::DefaultASTVisitor::visit (meta_item);
|
||||
}
|
||||
if (!attribute.is_parsed_to_meta_item ())
|
||||
attribute.parse_attr_to_meta_item ();
|
||||
if (!attribute.check_cfg_predicate (session))
|
||||
return; // Do not emit errors for attribute that'll get stripped.
|
||||
}
|
||||
|
||||
auto result_opt = identify_builtin (attribute);
|
||||
if (auto builtin = identify_builtin (attribute))
|
||||
{
|
||||
auto result = builtin.value ();
|
||||
// TODO: Add checks here for each builtin attribute
|
||||
// TODO: Have an enum of builtins as well, switching on strings is
|
||||
// annoying and costly
|
||||
if (result.name == Attrs::DOC)
|
||||
check_doc_attribute (attribute);
|
||||
else if (result.name == Attrs::DEPRECATED)
|
||||
check_deprecated_attribute (attribute);
|
||||
}
|
||||
|
||||
// This checker does not check non-builtin attributes
|
||||
if (!result_opt.has_value ())
|
||||
return;
|
||||
auto result = result_opt.value ();
|
||||
|
||||
// TODO: Add checks here for each builtin attribute
|
||||
// TODO: Have an enum of builtins as well, switching on strings is annoying
|
||||
// and costly
|
||||
if (result.name == Attrs::DOC)
|
||||
check_doc_attribute (attribute);
|
||||
else if (result.name == Attrs::DEPRECATED)
|
||||
check_deprecated_attribute (attribute);
|
||||
AST::DefaultASTVisitor::visit (attribute);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -3,4 +3,6 @@
|
||||
|
||||
#[cfg_attr(target_arch = "x86_64", path = (target_arch = "x86", path = "x86.rs"))]
|
||||
mod imp {}
|
||||
// { dg-error "malformed .path. attribute input" "" { target *-*-* } .-2 }
|
||||
// { dg-error "malformed .path. attribute input" "" { target { x86_64-*-* && { lp64 } } } .-2 }
|
||||
// { dg-error "cannot find value .target_arch. in this scope" "" { target { x86_64-*-* && { lp64 } } } .-3 }
|
||||
// { dg-error "cannot find value .path. in this scope" "" { target { x86_64-*-* && { lp64 } } } .-4 }
|
||||
|
||||
Reference in New Issue
Block a user