Add more pedwarns for [[]] C attributes on types.
authorJoseph Myers <joseph@codesourcery.com>
Wed, 20 Nov 2019 00:13:51 +0000 (00:13 +0000)
committerJoseph Myers <jsm28@gcc.gnu.org>
Wed, 20 Nov 2019 00:13:51 +0000 (00:13 +0000)
The standard [[]] attributes currently defined in C2x are all not
valid on types not being defined at the time.

Use on such types results in a warning from attribs.c about attributes
appertaining to types (the warning that I think is bogus in general
for both C and C++, applying as it does to all [[]] attributes
including gnu:: ones that are perfectly meaningful on types not being
defined and work fine when __attribute__ syntax is used instead).  If
that warning is removed (as I intend to do in a subsequent patch),
warnings may or may not result from the attribute handlers, depending
on whether those particular attribute handlers consider the attributes
meaningful in such a context.  In C, however, the rules about where
each [[]] attribute is valid are constraints, so a pedwarn, not a
warning, is required.

Because some handlers are shared between standard and gnu::
attributes, there can be cases that are valid for the GNU attribute
variant but not for the standard one.  So in general it is not correct
to rely on the attribute handlers to give all required pedwarns
(although in some cases, a pedwarn in the attribute handler is in
appropriate way of diagnosing an invalid use); they not have the
information about whether the attribute was a gnu:: one and can
legitimately accept a wider range of uses for the gnu:: attributes.

This patch ensures appropriate diagnostics for invalid uses of C2x
standard attributes on types, and so helps pave the way for the
subsequent removal of the bogus check in attribs.c, by adding a check
run in the front end before calling decl_attributes; this check
removes the attributes from the list after calling pedwarn to avoid
subsequent duplicate warnings.

Bootstrapped with no regressions for x86_64-pc-linux-gnu.

gcc/c:
* c-decl.c (c_warn_type_attributes): New function.
(groktypename, grokdeclarator, finish_declspecs): Call
c_warn_type_attributes before applying attributes to types.
* c-tree.h (c_warn_type_attributes): Declare.

gcc/testsuite:
* gcc.dg/c2x-attr-deprecated-2.c, gcc.dg/c2x-attr-fallthrough-2.c,
gcc.dg/c2x-attr-maybe_unused-2.c: Expect errors for invalid uses
of standard attributes on types.  Add more tests of invalid uses
on types.

From-SVN: r278471

gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/c/c-tree.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/c2x-attr-deprecated-2.c
gcc/testsuite/gcc.dg/c2x-attr-fallthrough-2.c
gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-2.c

index fff7dc6328ab645ad5f28af284353ad80ab510f9..3f42e40896a5e433e94a1f438aa33ca11050962e 100644 (file)
@@ -1,3 +1,10 @@
+2019-11-20  Joseph Myers  <joseph@codesourcery.com>
+
+       * c-decl.c (c_warn_type_attributes): New function.
+       (groktypename, grokdeclarator, finish_declspecs): Call
+       c_warn_type_attributes before applying attributes to types.
+       * c-tree.h (c_warn_type_attributes): Declare.
+
 2019-11-19  Joseph Myers  <joseph@codesourcery.com>
 
        * c-decl.c (c_warn_unused_attributes): Use pedwarn not warning for
index 746339d12edc7519e21aa7dbe0712010da274416..d153de2e2ad0d3dfd0a5d989dc5dcde80e67e6a7 100644 (file)
@@ -4525,6 +4525,26 @@ c_warn_unused_attributes (tree attrs)
       warning (OPT_Wattributes, "%qE attribute ignored",
               get_attribute_name (t));
 }
+
+/* Warn for standard attributes being applied to a type that is not
+   being defined, where that is a constraint violation, and return a
+   list of attributes with them removed.  */
+
+tree
+c_warn_type_attributes (tree attrs)
+{
+  tree *attr_ptr = &attrs;
+  while (*attr_ptr)
+    if (get_attribute_namespace (*attr_ptr) == NULL_TREE)
+      {
+       pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
+                get_attribute_name (*attr_ptr));
+       *attr_ptr = TREE_CHAIN (*attr_ptr);
+      }
+    else
+      attr_ptr = &TREE_CHAIN (*attr_ptr);
+  return attrs;
+}
 \f
 /* Called when a declaration is seen that contains no names to declare.
    If its type is a reference to a structure, union or enum inherited
@@ -4883,6 +4903,7 @@ groktypename (struct c_type_name *type_name, tree *expr,
                         DEPRECATED_NORMAL);
 
   /* Apply attributes.  */
+  attrs = c_warn_type_attributes (attrs);
   decl_attributes (&type, attrs, 0);
 
   return type;
@@ -6295,10 +6316,13 @@ grokdeclarator (const struct c_declarator *declarator,
            if (cxx11_attribute_p (attrs) && inner_decl->kind == cdk_id)
              returned_attrs = chainon (returned_attrs, attrs);
            else
-             returned_attrs = decl_attributes (&type,
-                                               chainon (returned_attrs,
-                                                        attrs),
-                                               attr_flags);
+             {
+               attrs = c_warn_type_attributes (attrs);
+               returned_attrs = decl_attributes (&type,
+                                                 chainon (returned_attrs,
+                                                          attrs),
+                                                 attr_flags);
+             }
            break;
          }
        case cdk_array:
@@ -11676,6 +11700,7 @@ finish_declspecs (struct c_declspecs *specs)
     }
   if (specs->type != NULL)
     {
+      specs->postfix_attrs = c_warn_type_attributes (specs->postfix_attrs);
       decl_attributes (&specs->type, specs->postfix_attrs, 0);
       specs->postfix_attrs = NULL_TREE;
     }
index 67c8f45af450db86a91d733d539b1ee38312e48f..dffefa3fd1a549071cf04d6e691b6083b5ac9ea9 100644 (file)
@@ -596,6 +596,7 @@ extern tree c_builtin_function (tree);
 extern tree c_builtin_function_ext_scope (tree);
 extern tree c_simulate_builtin_function_decl (tree);
 extern void c_warn_unused_attributes (tree);
+extern tree c_warn_type_attributes (tree);
 extern void shadow_tag (const struct c_declspecs *);
 extern void shadow_tag_warned (const struct c_declspecs *, int);
 extern tree start_enum (location_t, struct c_enum_contents *, tree);
index 2cc8db5717097d61fae4af336afadd9474ff5c76..37fbda183dec458e99c663ae8884d89c530bcdc7 100644 (file)
@@ -1,3 +1,10 @@
+2019-11-20  Joseph Myers  <joseph@codesourcery.com>
+
+       * gcc.dg/c2x-attr-deprecated-2.c, gcc.dg/c2x-attr-fallthrough-2.c,
+       gcc.dg/c2x-attr-maybe_unused-2.c: Expect errors for invalid uses
+       of standard attributes on types.  Add more tests of invalid uses
+       on types.
+
 2019-11-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/92414
index 0f0b1749ae4fdc24dcd5f0a9f10239705f480adc..44f2cc9bd138f715e44233733fcd7ef1914dc32f 100644 (file)
@@ -7,14 +7,13 @@
 
 [[deprecated]]; /* { dg-error "ignored" } */
 
-int [[deprecated]] var; /* { dg-warning "ignored" } */
-/* { dg-message "that appertains to a type-specifier" "appertains" { target *-*-* } .-1 } */
+int [[deprecated]] var; /* { dg-error "ignored" } */
 
-int array_with_dep_type[2] [[deprecated]]; /* { dg-warning "ignored" } */
-/* { dg-message "that appertains to a type-specifier" "appertains" { target *-*-* } .-1 } */
+int array_with_dep_type[2] [[deprecated]]; /* { dg-error "ignored" } */
 
-void fn_with_dep_type () [[deprecated]]; /* { dg-warning "ignored" } */
-/* { dg-message "that appertains to a type-specifier" "appertains" { target *-*-* } .-1 } */
+void fn_with_dep_type () [[deprecated]]; /* { dg-error "ignored" } */
+
+int z = sizeof (int [[__deprecated__]]); /* { dg-error "ignored" } */
 
 void
 f (void)
index 33e3ec282279c2b1ea53d1f6ea4ce81edd343f14..0e36adccc9eed068d03c67e3c998fc81f0cc502a 100644 (file)
@@ -4,11 +4,13 @@
 
 [[fallthrough]]; /* { dg-error "'fallthrough' attribute at top level" } */
 
-int [[fallthrough]] x; /* { dg-warning "ignored" } */
-/* { dg-message "that appertains to a type-specifier" "appertains" { target *-*-* } .-1 } */
+int [[fallthrough]] x; /* { dg-error "ignored" } */
 
-int g () [[fallthrough]]; /* { dg-warning "ignored" } */
-/* { dg-message "that appertains to a type-specifier" "appertains" { target *-*-* } .-1 } */
+int g () [[fallthrough]]; /* { dg-error "ignored" } */
+
+int array[2] [[fallthrough]]; /* { dg-error "ignored" } */
+
+int z = sizeof (int [[fallthrough]]); /* { dg-error "ignored" } */
 
 int
 f (int a)
index 7f06581f949ac482e580dad5d6671e35d96f7560..a749639192e8bfb2e61345e665d815c6d22bd1c7 100644 (file)
@@ -7,14 +7,13 @@
 
 [[maybe_unused]]; /* { dg-error "ignored" } */
 
-int [[maybe_unused]] var; /* { dg-warning "ignored" } */
-/* { dg-message "that appertains to a type-specifier" "appertains" { target *-*-* } .-1 } */
+int [[maybe_unused]] var; /* { dg-error "ignored" } */
 
-int array_with_dep_type[2] [[maybe_unused]]; /* { dg-warning "ignored" } */
-/* { dg-message "that appertains to a type-specifier" "appertains" { target *-*-* } .-1 } */
+int array_with_dep_type[2] [[maybe_unused]]; /* { dg-error "ignored" } */
 
-void fn_with_dep_type () [[maybe_unused]]; /* { dg-warning "ignored" } */
-/* { dg-message "that appertains to a type-specifier" "appertains" { target *-*-* } .-1 } */
+void fn_with_dep_type () [[maybe_unused]]; /* { dg-error "ignored" } */
+
+int z = sizeof (int [[__maybe_unused__]]); /* { dg-error "ignored" } */
 
 void
 f (void)