aboutsummaryrefslogtreecommitdiff
path: root/gcc/attribs.c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2019-06-19 21:27:45 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2019-06-19 21:27:45 +0000
commit1bf32c1141e230743f9248f7f7bf8aab91823df5 (patch)
treecf0c040fd768f2b12fa1f83eb56a3b2f9c9153ee /gcc/attribs.c
parent4b4a26731e96522a76a6f9fc6a253d41a29238ef (diff)
downloadgcc-1bf32c1141e230743f9248f7f7bf8aab91823df5.zip
gcc-1bf32c1141e230743f9248f7f7bf8aab91823df5.tar.gz
gcc-1bf32c1141e230743f9248f7f7bf8aab91823df5.tar.bz2
PR c++/60364 - noreturn after first decl not diagnosed.
* attribs.c (get_attribute_namespace): No longer static. (decl_attributes): Avoid shadowing. Preserve the C++11 form for C++11 attributes. (attr_noreturn_exclusions): Make it extern. * attribs.h (get_attribute_namespace): Declare. * tree-inline.c (function_attribute_inlinable_p): Use get_attribute_name. * c-attribs.c (handle_noreturn_attribute): No longer static. * c-common.h (handle_noreturn_attribute, attr_noreturn_exclusions): Declare. * c-format.c (check_function_format): Use get_attribute_name. * decl.c (duplicate_decls): Give an error when a function is declared [[noreturn]] after its first declaration. * parser.c (cp_parser_std_attribute): Don't treat C++11 noreturn attribute as equivalent to GNU's. * tree.c (std_attribute_table): Add noreturn. * g++.dg/warn/noreturn-8.C: New test. * g++.dg/warn/noreturn-9.C: New test. * g++.dg/warn/noreturn-10.C: New test. * g++.dg/warn/noreturn-11.C: New test. From-SVN: r272486
Diffstat (limited to 'gcc/attribs.c')
-rw-r--r--gcc/attribs.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 4441922..8e54016 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -340,7 +340,7 @@ lookup_attribute_spec (const_tree name)
Please read the comments of cxx11_attribute_p to understand the
format of attributes. */
-static tree
+tree
get_attribute_namespace (const_tree attr)
{
if (cxx11_attribute_p (attr))
@@ -469,7 +469,6 @@ tree
decl_attributes (tree *node, tree attributes, int flags,
tree last_decl /* = NULL_TREE */)
{
- tree a;
tree returned_attrs = NULL_TREE;
if (TREE_TYPE (*node) == error_mark_node || attributes == error_mark_node)
@@ -548,22 +547,23 @@ decl_attributes (tree *node, tree attributes, int flags,
/* Note that attributes on the same declaration are not necessarily
in the same order as in the source. */
- for (a = attributes; a; a = TREE_CHAIN (a))
+ for (tree attr = attributes; attr; attr = TREE_CHAIN (attr))
{
- tree ns = get_attribute_namespace (a);
- tree name = get_attribute_name (a);
- tree args = TREE_VALUE (a);
+ tree ns = get_attribute_namespace (attr);
+ tree name = get_attribute_name (attr);
+ tree args = TREE_VALUE (attr);
tree *anode = node;
const struct attribute_spec *spec
= lookup_scoped_attribute_spec (ns, name);
int fn_ptr_quals = 0;
tree fn_ptr_tmp = NULL_TREE;
+ const bool cxx11_attr_p = cxx11_attribute_p (attr);
if (spec == NULL)
{
if (!(flags & (int) ATTR_FLAG_BUILT_IN))
{
- if (ns == NULL_TREE || !cxx11_attribute_p (a))
+ if (ns == NULL_TREE || !cxx11_attr_p)
warning (OPT_Wattributes, "%qE attribute directive ignored",
name);
else
@@ -584,7 +584,7 @@ decl_attributes (tree *node, tree attributes, int flags,
gcc_assert (is_attribute_p (spec->name, name));
if (TYPE_P (*node)
- && cxx11_attribute_p (a)
+ && cxx11_attr_p
&& !(flags & ATTR_FLAG_TYPE_IN_PLACE))
{
/* This is a c++11 attribute that appertains to a
@@ -707,8 +707,7 @@ decl_attributes (tree *node, tree attributes, int flags,
if (spec->handler != NULL)
{
- int cxx11_flag =
- cxx11_attribute_p (a) ? ATTR_FLAG_CXX11 : 0;
+ int cxx11_flag = (cxx11_attr_p ? ATTR_FLAG_CXX11 : 0);
/* Pass in an array of the current declaration followed
by the last pushed/merged declaration if one exists.
@@ -756,17 +755,23 @@ decl_attributes (tree *node, tree attributes, int flags,
if (a == NULL_TREE)
{
/* This attribute isn't already in the list. */
+ tree r;
+ /* Preserve the C++11 form. */
+ if (cxx11_attr_p)
+ r = tree_cons (build_tree_list (ns, name), args, old_attrs);
+ else
+ r = tree_cons (name, args, old_attrs);
+
if (DECL_P (*anode))
- DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
+ DECL_ATTRIBUTES (*anode) = r;
else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
{
- TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
+ TYPE_ATTRIBUTES (*anode) = r;
/* If this is the main variant, also push the attributes
out to the other variants. */
if (*anode == TYPE_MAIN_VARIANT (*anode))
{
- tree variant;
- for (variant = *anode; variant;
+ for (tree variant = *anode; variant;
variant = TYPE_NEXT_VARIANT (variant))
{
if (TYPE_ATTRIBUTES (variant) == old_attrs)
@@ -780,9 +785,7 @@ decl_attributes (tree *node, tree attributes, int flags,
}
}
else
- *anode = build_type_attribute_variant (*anode,
- tree_cons (name, args,
- old_attrs));
+ *anode = build_type_attribute_variant (*anode, r);
}
}