+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
/* 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));
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.
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,
/* 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)
{
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;
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);
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
{
+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.
{ 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
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)
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" } */
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
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
#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
--- /dev/null
+// { 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;
+}