Commit d067e05f by Jason Merrill Committed by Jason Merrill

Implement C++17 [[maybe_unused]] attribute.

gcc/
	* attribs.c (register_scoped_attributes): Fix logic.
	* attribs.h: Declare register_scoped_attributes.
c-family/
	* c-common.c (handle_unused_attribute): Accept CONST_DECL.
	No longer static.
	* c-common.h: Declare it.
	* c-lex.c (c_common_has_attribute): Add maybe_unused.
cp/
	* tree.c (std_attribute_table): New.
	(init_tree): Register it.

From-SVN: r235414
parent 4dfaa963
2016-04-25 Jason Merrill <jason@redhat.com>
* attribs.c (register_scoped_attributes): Fix logic.
* attribs.h: Declare register_scoped_attributes.
2016-04-25 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* config/rs6000/rs6000-builtin.def: Correct pasto error for
......
......@@ -130,7 +130,7 @@ register_scoped_attributes (const struct attribute_spec * attributes,
/* We don't have any namespace NS yet. Create one. */
scoped_attributes sa;
if (!attributes_table.is_empty ())
if (attributes_table.is_empty ())
attributes_table.create (64);
memset (&sa, 0, sizeof (sa));
......
......@@ -38,4 +38,7 @@ extern tree get_attribute_name (const_tree);
extern void apply_tm_attr (tree, tree);
extern tree make_attribute (const char *, const char *, tree);
extern struct scoped_attributes* register_scoped_attributes (const struct attribute_spec *,
const char *);
#endif // GCC_ATTRIBS_H
2016-04-25 Jason Merrill <jason@redhat.com>
* c-common.c (handle_unused_attribute): Accept CONST_DECL.
No longer static.
* c-common.h: Declare it.
* c-lex.c (c_common_has_attribute): Add maybe_unused.
2016-04-22 Jason Merrill <jason@redhat.com>
* c-cppbuiltin.c (c_cpp_builtins): Fix __cpp_range_based_for.
......
......@@ -327,7 +327,6 @@ static tree handle_artificial_attribute (tree *, tree, tree, int, bool *);
static tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
static tree handle_error_attribute (tree *, tree, tree, int, bool *);
static tree handle_used_attribute (tree *, tree, tree, int, bool *);
static tree handle_unused_attribute (tree *, tree, tree, int, bool *);
static tree handle_externally_visible_attribute (tree *, tree, tree, int,
bool *);
static tree handle_no_reorder_attribute (tree *, tree, tree, int,
......@@ -7033,7 +7032,7 @@ handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
/* Handle a "unused" attribute; arguments as in
struct attribute_spec.handler. */
static tree
tree
handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
int flags, bool *no_add_attrs)
{
......@@ -7044,6 +7043,7 @@ handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
if (TREE_CODE (decl) == PARM_DECL
|| VAR_OR_FUNCTION_DECL_P (decl)
|| TREE_CODE (decl) == LABEL_DECL
|| TREE_CODE (decl) == CONST_DECL
|| TREE_CODE (decl) == TYPE_DECL)
{
TREE_USED (decl) = 1;
......
......@@ -790,6 +790,7 @@ extern void check_function_arguments_recurse (void (*)
unsigned HOST_WIDE_INT);
extern bool check_builtin_function_arguments (tree, int, tree *);
extern void check_function_format (tree, int, tree *);
extern tree handle_unused_attribute (tree *, tree, tree, int, bool *);
extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
extern bool attribute_takes_identifier_p (const_tree);
......
......@@ -340,24 +340,27 @@ c_common_has_attribute (cpp_reader *pfile)
attr_name = NULL_TREE;
}
}
else
{
/* Some standard attributes need special handling. */
if (is_attribute_p ("noreturn", attr_name))
result = 200809;
else if (is_attribute_p ("deprecated", attr_name))
result = 201309;
else if (is_attribute_p ("maybe_unused", attr_name))
result = 201603;
if (result)
attr_name = NULL_TREE;
}
}
if (attr_name)
{
init_attributes ();
const struct attribute_spec *attr = lookup_attribute_spec (attr_name);
if (attr)
{
if (TREE_CODE (attr_name) == TREE_LIST)
attr_name = TREE_VALUE (attr_name);
if (is_attribute_p ("noreturn", attr_name))
result = 200809;
else if (is_attribute_p ("deprecated", attr_name))
result = 201309;
else
result = 1;
}
}
}
else
{
cpp_error (pfile, CPP_DL_ERROR,
......
2016-04-25 Jason Merrill <jason@redhat.com>
* tree.c (std_attribute_table): New.
(init_tree): Register it.
2016-04-22 Jason Merrill <jason@redhat.com>
* parser.c (cp_parser_perform_range_for_lookup): Decay the array.
......
......@@ -3548,6 +3548,16 @@ const struct attribute_spec cxx_attribute_table[] =
{ NULL, 0, 0, false, false, false, NULL, false }
};
/* Table of C++ standard attributes. */
const struct attribute_spec std_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
affects_type_identity } */
{ "maybe_unused", 0, 0, false, false, false,
handle_unused_attribute, false },
{ NULL, 0, 0, false, false, false, NULL, false }
};
/* Handle a "java_interface" attribute; arguments as in
struct attribute_spec.handler. */
static tree
......@@ -4026,6 +4036,7 @@ void
init_tree (void)
{
list_hash_table = hash_table<list_hasher>::create_ggc (61);
register_scoped_attributes (std_attribute_table, NULL);
}
/* Returns the kind of special function that DECL (a FUNCTION_DECL)
......
......@@ -6,7 +6,7 @@ enum E {
A __attribute__((foo)), /* { dg-warning "ignored" } */
B __attribute__((cold)), /* { dg-warning "ignored" } */
C __attribute__((const)), /* { dg-warning "ignored" } */
D __attribute__((unused)), /* { dg-warning "ignored" } */
D __attribute__((unused)),
E __attribute__((flatten)), /* { dg-warning "ignored" } */
F __attribute__((tm)), /* { dg-warning "ignored" } */
G __attribute__((common)), /* { dg-warning "ignored" } */
......
......@@ -17,10 +17,10 @@ T3 t3;
T4 t4;
T5 t5;
#ifdef __cplusplus
typedef char T6[__has_attribute (gnu::__noreturn__) == 200809 ? 1 : -1];
typedef char T6[__has_attribute (gnu::__noreturn__) ? 1 : -1];
typedef char T7[__has_attribute (gnu::alloc_size) == 1 ? 1 : -1];
typedef char T8[__has_attribute (gnu::non_existent_attribuuuute) == 0 ? 1 : -1];
#if __has_attribute (gnu::noreturn) == 200809
#if __has_attribute (gnu::noreturn)
typedef char T9;
#endif
#define d2 gnu::deprecated
......@@ -47,10 +47,10 @@ T13 t13;
T14 t14;
T15 t15;
#ifdef __cplusplus
typedef char T16[__has_cpp_attribute (gnu::__noreturn__) == 200809 ? 1 : -1];
typedef char T16[__has_cpp_attribute (gnu::__noreturn__) ? 1 : -1];
typedef char T17[__has_cpp_attribute (gnu::alloc_size) == 1 ? 1 : -1];
typedef char T18[__has_cpp_attribute (gnu::non_existent_attribuuuute) == 0 ? 1 : -1];
#if __has_cpp_attribute (gnu::noreturn) == 200809
#if __has_cpp_attribute (gnu::noreturn)
typedef char T19;
#endif
#define d2 gnu::deprecated
......
......@@ -343,3 +343,13 @@
#elif __cpp_hex_float != 201603
# error "__cpp_hex_float != 201603"
#endif
#ifdef __has_cpp_attribute
# if ! __has_cpp_attribute(maybe_unused)
# error "__has_cpp_attribute(maybe_unused)"
# elif __has_cpp_attribute(maybe_unused) != 201603
# error "__has_cpp_attribute(maybe_unused) != 201603"
# endif
#else
# error "__has_cpp_attribute"
#endif
// { dg-do compile { target c++11 } }
// { dg-options "-Wunused -Wextra" }
[[maybe_unused]] static void f() { }
enum [[maybe_unused]] E {
e [[maybe_unused]]
};
struct [[maybe_unused]] A {
[[maybe_unused]] static int i;
};
void g([[maybe_unused]] int i) {
[[maybe_unused]] typedef int T;
[[maybe_unused]] int j;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment