commit 0c140407be1dbcb43fa4e2047d5aa65cb5ac5ff8
Author: Jason Merrill <jason@redhat.com>
Date: Tue Mar 8 16:27:45 2016 -0500
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.
@@ -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
@@ -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,23 +340,26 @@ c_common_has_attribute (cpp_reader *pfile)
attr_name = NULL_TREE;
}
}
- }
- if (attr_name)
- {
- init_attributes ();
- const struct attribute_spec *attr = lookup_attribute_spec (attr_name);
- if (attr)
+ else
{
- if (TREE_CODE (attr_name) == TREE_LIST)
- attr_name = TREE_VALUE (attr_name);
+ /* 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
- result = 1;
+ 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)
+ result = 1;
+ }
}
else
{
@@ -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
new file mode 100644
@@ -0,0 +1,17 @@
+// { 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;
+}