]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Implement C++17 [[maybe_unused]] attribute.
authorJason Merrill <jason@redhat.com>
Mon, 25 Apr 2016 17:21:49 +0000 (13:21 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 25 Apr 2016 17:21:49 +0000 (13:21 -0400)
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

13 files changed:
gcc/ChangeLog
gcc/attribs.c
gcc/attribs.h
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c-family/c-lex.c
gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/c-c++-common/attributes-enum-2.c
gcc/testsuite/c-c++-common/cpp/pr63831-1.c
gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C
gcc/testsuite/g++.dg/cpp1z/maybe_unused1.C [new file with mode: 0644]

index 6d2ce22f966e1a8d941f62728a02566683c38b1d..954238cd80aa9764636526fa4d4c0118e2a968b2 100644 (file)
@@ -1,3 +1,8 @@
+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
index 16996e9f28309882b514279fb5e98530d7b9607d..9a886214ec40696f85328f29bfe8db32f82694d5 100644 (file)
@@ -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));
index 9e64a7a7e807cb587751a52f2fab0eb142ba3716..23d30435d1d2721d0abc92d21b6e1692b34e683a 100644 (file)
@@ -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
index 085d16ab689b9a8262faace3970dd8cd52151738..af601678982940c94eec5bdbc9a3782eb9d16819 100644 (file)
@@ -1,3 +1,10 @@
+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.
index cae2faf5c4f28060ecd0818c93f3babf9ed8878c..1edc0bc65bbfeb2cdc807b99511cab245032fb3b 100644 (file)
@@ -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;
index 663e457dd52b877c28bbb59a807d2a02b4f514f3..4c43a354fefa1b71c3bc3fcf96818c2fc5be21ff 100644 (file)
@@ -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);
index 96da4fc974ec86e704c9c9a0648bdb53f91032b2..6b020a41e599936bdec6ae11f3d10a84903e4217 100644 (file)
@@ -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
     {
index 3a3373e3806a51975fbe3a166e066ea2fb15b957..e9c50d663fed528e824f008bd16c8c226065201f 100644 (file)
@@ -1,3 +1,8 @@
+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.
index 112c8c7a565e27f451694671e198d48e20d40e0a..381c24faa3d2915da30af362c174b3555dfef1e2 100644 (file)
@@ -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)
index f143f15f6e8c088d0a5b03111c5422e7f5c4a695..131dd549f36afb23cd952e358b296ea0bdceb01d 100644 (file)
@@ -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" } */
index c9e7756406de43bbf1df3b1cc143b35448dcf878..c7cad0489fa1ec895a5997e9dd444491778c2658 100644 (file)
@@ -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
index 74c6f2978dfd97f55369d432a31c67123b94a787..fe7a4c23290ab89e0df6d996bd12788b6dca1953 100644 (file)
 #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
diff --git a/gcc/testsuite/g++.dg/cpp1z/maybe_unused1.C b/gcc/testsuite/g++.dg/cpp1z/maybe_unused1.C
new file mode 100644 (file)
index 0000000..eb8b51e
--- /dev/null
@@ -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;
+}