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> 2016-04-25 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* config/rs6000/rs6000-builtin.def: Correct pasto error for * config/rs6000/rs6000-builtin.def: Correct pasto error for
......
...@@ -130,7 +130,7 @@ register_scoped_attributes (const struct attribute_spec * attributes, ...@@ -130,7 +130,7 @@ register_scoped_attributes (const struct attribute_spec * attributes,
/* We don't have any namespace NS yet. Create one. */ /* We don't have any namespace NS yet. Create one. */
scoped_attributes sa; scoped_attributes sa;
if (!attributes_table.is_empty ()) if (attributes_table.is_empty ())
attributes_table.create (64); attributes_table.create (64);
memset (&sa, 0, sizeof (sa)); memset (&sa, 0, sizeof (sa));
......
...@@ -38,4 +38,7 @@ extern tree get_attribute_name (const_tree); ...@@ -38,4 +38,7 @@ extern tree get_attribute_name (const_tree);
extern void apply_tm_attr (tree, tree); extern void apply_tm_attr (tree, tree);
extern tree make_attribute (const char *, const char *, 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 #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> 2016-04-22 Jason Merrill <jason@redhat.com>
* c-cppbuiltin.c (c_cpp_builtins): Fix __cpp_range_based_for. * 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 *); ...@@ -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_flatten_attribute (tree *, tree, tree, int, bool *);
static tree handle_error_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_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, static tree handle_externally_visible_attribute (tree *, tree, tree, int,
bool *); bool *);
static tree handle_no_reorder_attribute (tree *, tree, tree, int, 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), ...@@ -7033,7 +7032,7 @@ handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
/* Handle a "unused" attribute; arguments as in /* Handle a "unused" attribute; arguments as in
struct attribute_spec.handler. */ struct attribute_spec.handler. */
static tree tree
handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args), handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
int flags, bool *no_add_attrs) int flags, bool *no_add_attrs)
{ {
...@@ -7044,6 +7043,7 @@ handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args), ...@@ -7044,6 +7043,7 @@ handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
if (TREE_CODE (decl) == PARM_DECL if (TREE_CODE (decl) == PARM_DECL
|| VAR_OR_FUNCTION_DECL_P (decl) || VAR_OR_FUNCTION_DECL_P (decl)
|| TREE_CODE (decl) == LABEL_DECL || TREE_CODE (decl) == LABEL_DECL
|| TREE_CODE (decl) == CONST_DECL
|| TREE_CODE (decl) == TYPE_DECL) || TREE_CODE (decl) == TYPE_DECL)
{ {
TREE_USED (decl) = 1; TREE_USED (decl) = 1;
......
...@@ -790,6 +790,7 @@ extern void check_function_arguments_recurse (void (*) ...@@ -790,6 +790,7 @@ extern void check_function_arguments_recurse (void (*)
unsigned HOST_WIDE_INT); unsigned HOST_WIDE_INT);
extern bool check_builtin_function_arguments (tree, int, tree *); extern bool check_builtin_function_arguments (tree, int, tree *);
extern void check_function_format (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_attribute (tree *, tree, tree, int, bool *);
extern tree handle_format_arg_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); extern bool attribute_takes_identifier_p (const_tree);
......
...@@ -340,23 +340,26 @@ c_common_has_attribute (cpp_reader *pfile) ...@@ -340,23 +340,26 @@ c_common_has_attribute (cpp_reader *pfile)
attr_name = NULL_TREE; attr_name = NULL_TREE;
} }
} }
} else
if (attr_name)
{
init_attributes ();
const struct attribute_spec *attr = lookup_attribute_spec (attr_name);
if (attr)
{ {
if (TREE_CODE (attr_name) == TREE_LIST) /* Some standard attributes need special handling. */
attr_name = TREE_VALUE (attr_name);
if (is_attribute_p ("noreturn", attr_name)) if (is_attribute_p ("noreturn", attr_name))
result = 200809; result = 200809;
else if (is_attribute_p ("deprecated", attr_name)) else if (is_attribute_p ("deprecated", attr_name))
result = 201309; result = 201309;
else else if (is_attribute_p ("maybe_unused", attr_name))
result = 1; 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)
result = 1;
}
} }
else else
{ {
......
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> 2016-04-22 Jason Merrill <jason@redhat.com>
* parser.c (cp_parser_perform_range_for_lookup): Decay the array. * parser.c (cp_parser_perform_range_for_lookup): Decay the array.
......
...@@ -3548,6 +3548,16 @@ const struct attribute_spec cxx_attribute_table[] = ...@@ -3548,6 +3548,16 @@ const struct attribute_spec cxx_attribute_table[] =
{ NULL, 0, 0, false, false, false, NULL, false } { 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 /* Handle a "java_interface" attribute; arguments as in
struct attribute_spec.handler. */ struct attribute_spec.handler. */
static tree static tree
...@@ -4026,6 +4036,7 @@ void ...@@ -4026,6 +4036,7 @@ void
init_tree (void) init_tree (void)
{ {
list_hash_table = hash_table<list_hasher>::create_ggc (61); 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) /* Returns the kind of special function that DECL (a FUNCTION_DECL)
......
...@@ -6,7 +6,7 @@ enum E { ...@@ -6,7 +6,7 @@ enum E {
A __attribute__((foo)), /* { dg-warning "ignored" } */ A __attribute__((foo)), /* { dg-warning "ignored" } */
B __attribute__((cold)), /* { dg-warning "ignored" } */ B __attribute__((cold)), /* { dg-warning "ignored" } */
C __attribute__((const)), /* { dg-warning "ignored" } */ C __attribute__((const)), /* { dg-warning "ignored" } */
D __attribute__((unused)), /* { dg-warning "ignored" } */ D __attribute__((unused)),
E __attribute__((flatten)), /* { dg-warning "ignored" } */ E __attribute__((flatten)), /* { dg-warning "ignored" } */
F __attribute__((tm)), /* { dg-warning "ignored" } */ F __attribute__((tm)), /* { dg-warning "ignored" } */
G __attribute__((common)), /* { dg-warning "ignored" } */ G __attribute__((common)), /* { dg-warning "ignored" } */
......
...@@ -17,10 +17,10 @@ T3 t3; ...@@ -17,10 +17,10 @@ T3 t3;
T4 t4; T4 t4;
T5 t5; T5 t5;
#ifdef __cplusplus #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 T7[__has_attribute (gnu::alloc_size) == 1 ? 1 : -1];
typedef char T8[__has_attribute (gnu::non_existent_attribuuuute) == 0 ? 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; typedef char T9;
#endif #endif
#define d2 gnu::deprecated #define d2 gnu::deprecated
...@@ -47,10 +47,10 @@ T13 t13; ...@@ -47,10 +47,10 @@ T13 t13;
T14 t14; T14 t14;
T15 t15; T15 t15;
#ifdef __cplusplus #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 T17[__has_cpp_attribute (gnu::alloc_size) == 1 ? 1 : -1];
typedef char T18[__has_cpp_attribute (gnu::non_existent_attribuuuute) == 0 ? 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; typedef char T19;
#endif #endif
#define d2 gnu::deprecated #define d2 gnu::deprecated
......
...@@ -343,3 +343,13 @@ ...@@ -343,3 +343,13 @@
#elif __cpp_hex_float != 201603 #elif __cpp_hex_float != 201603
# error "__cpp_hex_float != 201603" # error "__cpp_hex_float != 201603"
#endif #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