public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-5123] attribs: Implement -Wno-attributes=vendor::attr [PR101940]
@ 2021-11-10 14:26 Marek Polacek
  0 siblings, 0 replies; only message in thread
From: Marek Polacek @ 2021-11-10 14:26 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a1ad0d84d7fcbcaa7a697290387b911eb7e1bd46

commit r12-5123-ga1ad0d84d7fcbcaa7a697290387b911eb7e1bd46
Author: Marek Polacek <polacek@redhat.com>
Date:   Thu Sep 9 09:17:27 2021 -0400

    attribs: Implement -Wno-attributes=vendor::attr [PR101940]
    
    It is desirable for -Wattributes to warn about e.g.
    
    [[deprecate]] void g(); // typo, should warn
    
    However, -Wattributes also warns about vendor-specific attributes
    (that's because lookup_scoped_attribute_spec -> find_attribute_namespace
    finds nothing), which, with -Werror, causes grief.  We don't want the
    -Wattributes warning for
    
    [[company::attr]] void f();
    
    GCC warns because it doesn't know the "company" namespace; it only knows
    the "gnu" and "omp" namespaces.  We could entirely disable warning about
    attributes in unknown scopes but then the compiler would also miss typos
    like
    
      [[company::attrx]] void f();
    
    or
    
      [[gmu::warn_used_result]] int write();
    
    so that is not a viable solution.  A workaround is to use a #pragma:
    
      #pragma GCC diagnostic push
      #pragma GCC diagnostic ignored "-Wattributes"
      [[company::attr]] void f() {}
      #pragma GCC diagnostic pop
    
    but that's a mouthful and awkward to use and could also hide typos.  In
    fact, any macro-based solution doesn't seem like a way forward.
    
    This patch implements -Wno-attributes=, which takes these arguments:
    
    company::attr
    company::
    
    This option should go well with using @file: the user could have a file
    containing
    -Wno-attributes=vendor::attr1,vendor::attr2
    and then invoke gcc with '@attrs' or similar.
    
    I've also added a new pragma which has the same effect:
    
    The pragma along with the new option should help with various static
    analysis tools.
    
            PR c++/101940
    
    gcc/ChangeLog:
    
            * attribs.c (struct scoped_attributes): Add a bool member.
            (lookup_scoped_attribute_spec): Forward declare.
            (register_scoped_attributes): New bool parameter, defaulted to
            false.  Use it.
            (handle_ignored_attributes_option): New function.
            (free_attr_data): New function.
            (init_attributes): Call handle_ignored_attributes_option.
            (attr_namespace_ignored_p): New function.
            (decl_attributes): Check attr_namespace_ignored_p before
            warning.
            * attribs.h (free_attr_data): Declare.
            (register_scoped_attributes): Adjust declaration.
            (handle_ignored_attributes_option): Declare.
            (canonicalize_attr_name): New function template.
            (canonicalize_attr_name): Use it.
            * common.opt (Wattributes=): New option with a variable.
            * doc/extend.texi: Document #pragma GCC diagnostic ignored_attributes.
            * doc/invoke.texi: Document -Wno-attributes=.
            * opts.c (common_handle_option) <case OPT_Wattributes_>: Handle.
            * plugin.h (register_scoped_attributes): Adjust declaration.
            * toplev.c (compile_file): Call free_attr_data.
    
    gcc/c-family/ChangeLog:
    
            * c-pragma.c (handle_pragma_diagnostic): Handle #pragma GCC diagnostic
            ignored_attributes.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/Wno-attributes-1.c: New test.
            * c-c++-common/Wno-attributes-2.c: New test.
            * c-c++-common/Wno-attributes-3.c: New test.

Diff:
---
 gcc/attribs.c                                 | 127 +++++++++++++++++++++++++-
 gcc/attribs.h                                 |  28 +++++-
 gcc/c-family/c-pragma.c                       |  37 +++++++-
 gcc/common.opt                                |   9 +-
 gcc/doc/extend.texi                           |  19 ++++
 gcc/doc/invoke.texi                           |  20 ++++
 gcc/opts.c                                    |  20 ++++
 gcc/plugin.h                                  |   4 +-
 gcc/testsuite/c-c++-common/Wno-attributes-1.c |  55 +++++++++++
 gcc/testsuite/c-c++-common/Wno-attributes-2.c |  56 ++++++++++++
 gcc/testsuite/c-c++-common/Wno-attributes-3.c |   9 ++
 gcc/toplev.c                                  |   2 +
 12 files changed, 374 insertions(+), 12 deletions(-)

diff --git a/gcc/attribs.c b/gcc/attribs.c
index 83fafc98b7d..0284e5bf2fd 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -87,6 +87,8 @@ struct scoped_attributes
   const char *ns;
   vec<attribute_spec> attributes;
   hash_table<attribute_hasher> *attribute_hash;
+  /* True if we should not warn about unknown attributes in this NS.  */
+  bool ignored_p;
 };
 
 /* The table of scope attributes.  */
@@ -95,6 +97,8 @@ static vec<scoped_attributes> attributes_table;
 static scoped_attributes* find_attribute_namespace (const char*);
 static void register_scoped_attribute (const struct attribute_spec *,
 				       scoped_attributes *);
+static const struct attribute_spec *lookup_scoped_attribute_spec (const_tree,
+								  const_tree);
 
 static bool attributes_initialized = false;
 
@@ -121,12 +125,14 @@ extract_attribute_substring (struct substring *str)
 
 /* Insert an array of attributes ATTRIBUTES into a namespace.  This
    array must be NULL terminated.  NS is the name of attribute
-   namespace.  The function returns the namespace into which the
-   attributes have been registered.  */
+   namespace.  IGNORED_P is true iff all unknown attributes in this
+   namespace should be ignored for the purposes of -Wattributes.  The
+   function returns the namespace into which the attributes have been
+   registered.  */
 
 scoped_attributes *
 register_scoped_attributes (const struct attribute_spec *attributes,
-			    const char *ns)
+			    const char *ns, bool ignored_p /*=false*/)
 {
   scoped_attributes *result = NULL;
 
@@ -144,9 +150,12 @@ register_scoped_attributes (const struct attribute_spec *attributes,
       memset (&sa, 0, sizeof (sa));
       sa.ns = ns;
       sa.attributes.create (64);
+      sa.ignored_p = ignored_p;
       result = attributes_table.safe_push (sa);
       result->attribute_hash = new hash_table<attribute_hasher> (200);
     }
+  else
+    result->ignored_p |= ignored_p;
 
   /* Really add the attributes to their namespace now.  */
   for (unsigned i = 0; attributes[i].name != NULL; ++i)
@@ -224,6 +233,99 @@ check_attribute_tables (void)
 				 attribute_tables[j][l].name));
 }
 
+/* Used to stash pointers to allocated memory so that we can free them at
+   the end of parsing of all TUs. */
+static vec<attribute_spec *> ignored_attributes_table;
+
+/* Parse arguments V of -Wno-attributes=.
+   Currently we accept:
+     vendor::attr
+     vendor::
+   This functions also registers the parsed attributes so that we don't
+   warn that we don't recognize them.  */
+
+void
+handle_ignored_attributes_option (vec<char *> *v)
+{
+  if (v == nullptr)
+    return;
+
+  for (auto opt : v)
+    {
+      char *cln = strstr (opt, "::");
+      /* We don't accept '::attr'.  */
+      if (cln == nullptr || cln == opt)
+	{
+	  error ("wrong argument to ignored attributes");
+	  inform (input_location, "valid format is %<ns::attr%> or %<ns::%>");
+	  continue;
+	}
+      const char *vendor_start = opt;
+      ptrdiff_t vendor_len = cln - opt;
+      const char *attr_start = cln + 2;
+      /* This could really use rawmemchr :(.  */
+      ptrdiff_t attr_len = strchr (attr_start, '\0') - attr_start;
+      /* Verify that they look valid.  */
+      auto valid_p = [](const char *const s, ptrdiff_t len) {
+	bool ok = false;
+
+	for (int i = 0; i < len; ++i)
+	  if (ISALNUM (s[i]))
+	    ok = true;
+	  else if (s[i] != '_')
+	    return false;
+
+	return ok;
+      };
+      if (!valid_p (vendor_start, vendor_len))
+	{
+	  error ("wrong argument to ignored attributes");
+	  continue;
+	}
+      canonicalize_attr_name (vendor_start, vendor_len);
+      /* We perform all this hijinks so that we don't have to copy OPT.  */
+      tree vendor_id = get_identifier_with_length (vendor_start, vendor_len);
+      const char *attr;
+      /* In the "vendor::" case, we should ignore *any* attribute coming
+	 from this attribute namespace.  */
+      if (attr_len > 0)
+	{
+	  if (!valid_p (attr_start, attr_len))
+	    {
+	      error ("wrong argument to ignored attributes");
+	      continue;
+	    }
+	  canonicalize_attr_name (attr_start, attr_len);
+	  tree attr_id = get_identifier_with_length (attr_start, attr_len);
+	  attr = IDENTIFIER_POINTER (attr_id);
+	  /* If we've already seen this vendor::attr, ignore it.  Attempting to
+	     register it twice would lead to a crash.  */
+	  if (lookup_scoped_attribute_spec (vendor_id, attr_id))
+	    continue;
+	}
+      else
+	attr = nullptr;
+      /* Create a table with extra attributes which we will register.
+	 We can't free it here, so squirrel away the pointers.  */
+      attribute_spec *table = new attribute_spec[2];
+      ignored_attributes_table.safe_push (table);
+      table[0] = { attr, 0, 0, false, false, false, false, nullptr, nullptr };
+      table[1] = { nullptr, 0, 0, false, false, false, false, nullptr,
+		   nullptr };
+      register_scoped_attributes (table, IDENTIFIER_POINTER (vendor_id), !attr);
+    }
+}
+
+/* Free data we might have allocated when adding extra attributes.  */
+
+void
+free_attr_data ()
+{
+  for (auto x : ignored_attributes_table)
+    delete[] x;
+  ignored_attributes_table.release ();
+}
+
 /* Initialize attribute tables, and make some sanity checks if checking is
    enabled.  */
 
@@ -252,6 +354,9 @@ init_attributes (void)
     /* Put all the GNU attributes into the "gnu" namespace.  */
     register_scoped_attributes (attribute_tables[i], "gnu");
 
+  vec<char *> *ignored = (vec<char *> *) flag_ignored_attributes;
+  handle_ignored_attributes_option (ignored);
+
   invoke_plugin_callbacks (PLUGIN_ATTRIBUTES, NULL);
   attributes_initialized = true;
 }
@@ -456,6 +561,19 @@ diag_attr_exclusions (tree last_decl, tree node, tree attrname,
   return found;
 }
 
+/* Return true iff we should not complain about unknown attributes
+   coming from the attribute namespace NS.  This is the case for
+   the -Wno-attributes=ns:: command-line option.  */
+
+static bool
+attr_namespace_ignored_p (tree ns)
+{
+  if (ns == NULL_TREE)
+    return false;
+  scoped_attributes *r = find_attribute_namespace (IDENTIFIER_POINTER (ns));
+  return r && r->ignored_p;
+}
+
 /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
    which is either a DECL (including a TYPE_DECL) or a TYPE.  If a DECL,
    it should be modified in place; if a TYPE, a copy should be created
@@ -556,7 +674,8 @@ decl_attributes (tree *node, tree attributes, int flags,
 
       if (spec == NULL)
 	{
-	  if (!(flags & (int) ATTR_FLAG_BUILT_IN))
+	  if (!(flags & (int) ATTR_FLAG_BUILT_IN)
+	      && !attr_namespace_ignored_p (ns))
 	    {
 	      if (ns == NULL_TREE || !cxx11_attr_p)
 		warning (OPT_Wattributes, "%qE attribute directive ignored",
diff --git a/gcc/attribs.h b/gcc/attribs.h
index 138c509bce1..ba657881940 100644
--- a/gcc/attribs.h
+++ b/gcc/attribs.h
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 #define GCC_ATTRIBS_H
 
 extern const struct attribute_spec *lookup_attribute_spec (const_tree);
+extern void free_attr_data ();
 extern void init_attributes (void);
 
 /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
@@ -40,12 +41,14 @@ 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 *);
+							     const char *,
+							     bool = false);
 
 extern char *sorted_attr_string (tree);
 extern bool common_function_versions (tree, tree);
 extern tree make_dispatcher_decl (const tree);
 extern bool is_function_default_version (const tree);
+extern void handle_ignored_attributes_option (vec<char *> *);
 
 /* Return a type like TTYPE except that its TYPE_ATTRIBUTES
    is ATTRIBUTE.
@@ -114,17 +117,34 @@ extern unsigned decls_mismatched_attributes (tree, tree, tree,
 
 extern void maybe_diag_alias_attributes (tree, tree);
 
+/* For a given string S of length L, strip leading and trailing '_' characters
+   so that we have a canonical form of attribute names.  NB: This function may
+   change S and L.  */
+
+template <typename T>
+inline bool
+canonicalize_attr_name (const char *&s, T &l)
+{
+  if (l > 4 && s[0] == '_' && s[1] == '_' && s[l - 1] == '_' && s[l - 2] == '_')
+    {
+      s += 2;
+      l -= 4;
+      return true;
+    }
+  return false;
+}
+
 /* For a given IDENTIFIER_NODE, strip leading and trailing '_' characters
    so that we have a canonical form of attribute names.  */
 
 static inline tree
 canonicalize_attr_name (tree attr_name)
 {
-  const size_t l = IDENTIFIER_LENGTH (attr_name);
+  size_t l = IDENTIFIER_LENGTH (attr_name);
   const char *s = IDENTIFIER_POINTER (attr_name);
 
-  if (l > 4 && s[0] == '_' && s[1] == '_' && s[l - 1] == '_' && s[l - 2] == '_')
-    return get_identifier_with_length (s + 2, l - 4);
+  if (canonicalize_attr_name (s, l))
+    return get_identifier_with_length (s, l);
 
   return attr_name;
 }
diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c
index b2ad991008a..3663eb1cfbb 100644
--- a/gcc/c-family/c-pragma.c
+++ b/gcc/c-family/c-pragma.c
@@ -771,7 +771,7 @@ handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
   if (token != CPP_NAME)
     {
       warning_at (loc, OPT_Wpragmas,
-		  "missing [error|warning|ignored|push|pop]"
+		  "missing [error|warning|ignored|push|pop|ignored_attributes]"
 		  " after %<#pragma GCC diagnostic%>");
       return;
     }
@@ -794,10 +794,43 @@ handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
       diagnostic_pop_diagnostics (global_dc, input_location);
       return;
     }
+  else if (strcmp (kind_string, "ignored_attributes") == 0)
+    {
+      token = pragma_lex (&x, &loc);
+      if (token != CPP_STRING)
+	{
+	  warning_at (loc, OPT_Wpragmas,
+		      "missing attribute name after %<#pragma GCC diagnostic "
+		      "ignored_attributes%>");
+	  return;
+	}
+      char *args = xstrdup (TREE_STRING_POINTER (x));
+      const size_t l = strlen (args);
+      if (l == 0)
+	{
+	  warning_at (loc, OPT_Wpragmas, "missing argument to %<#pragma GCC "
+		      "diagnostic ignored_attributes%>");
+	  free (args);
+	  return;
+	}
+      else if (args[l - 1] == ',')
+	{
+	  warning_at (loc, OPT_Wpragmas, "trailing %<,%> in arguments for "
+		      "%<#pragma GCC diagnostic ignored_attributes%>");
+	  free (args);
+	  return;
+	}
+      auto_vec<char *> v;
+      for (char *p = strtok (args, ","); p; p = strtok (NULL, ","))
+	v.safe_push (p);
+      handle_ignored_attributes_option (&v);
+      free (args);
+      return;
+    }
   else
     {
       warning_at (loc, OPT_Wpragmas,
-		  "expected [error|warning|ignored|push|pop]"
+		  "expected [error|warning|ignored|push|pop|ignored_attributes]"
 		  " after %<#pragma GCC diagnostic%>");
       return;
     }
diff --git a/gcc/common.opt b/gcc/common.opt
index 1a5b9bfcca9..de9b848eda5 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -83,7 +83,7 @@ int flag_gen_aux_info = 0
 Variable
 int flag_shlib
 
-; These two are really VEC(char_p,heap) *.
+; These three are really VEC(char_p,heap) *.
 
 Variable
 void *flag_instrument_functions_exclude_functions
@@ -91,6 +91,9 @@ void *flag_instrument_functions_exclude_functions
 Variable
 void *flag_instrument_functions_exclude_files
 
+Variable
+void *flag_ignored_attributes
+
 ; Generic structs (e.g. templates not explicitly specialized)
 ; may not have a compilation unit associated with them, and so
 ; may need to be treated differently from ordinary structs.
@@ -549,6 +552,10 @@ Wattributes
 Common Var(warn_attributes) Init(1) Warning
 Warn about inappropriate attribute usage.
 
+Wattributes=
+Common Joined
+Do not warn about specified attributes.
+
 Wattribute-alias
 Common Alias(Wattribute_alias=, 1, 0) Warning
 Warn about type safety and similar errors and mismatches in declarations with alias attributes.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index eee4c6737bb..6e6c580e329 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -23767,6 +23767,25 @@ restored.
   foo(d);                       /* depends on command-line options */
 @end smallexample
 
+@item #pragma GCC diagnostic ignored_attributes
+
+Similarly to @option{-Wno-attributes=}, this pragma allows users to suppress
+warnings about unknown scoped attributes (in C++11 and C2X).  For example,
+@code{#pragma GCC diagnostic ignored_attributes "vendor::attr"} disables
+warning about the following declaration:
+
+@smallexample
+[[vendor::attr]] void f();
+@end smallexample
+
+whereas @code{#pragma GCC diagnostic ignored_attributes "vendor::"} prevents
+warning about both of these declarations:
+
+@smallexample
+[[vendor::safe]] void f();
+[[vendor::unsafe]] void f2();
+@end smallexample
+
 @end table
 
 GCC also offers a simple mechanism for printing messages during
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index c3ff4945bdc..a7c4d24a762 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -8707,6 +8707,26 @@ unrecognized attributes, function attributes applied to variables,
 etc.  This does not stop errors for incorrect use of supported
 attributes.
 
+Additionally, using @option{-Wno-attributes=}, it is possible to suppress
+warnings about unknown scoped attributes (in C++11 and C2X).  For example,
+@option{-Wno-attributes=vendor::attr} disables warning about the following
+declaration:
+
+@smallexample
+[[vendor::attr]] void f();
+@end smallexample
+
+It is also possible to disable warning about all attributes in a namespace
+using @option{-Wno-attributes=vendor::} which prevents warning about both
+of these declarations:
+
+@smallexample
+[[vendor::safe]] void f();
+[[vendor::unsafe]] void f2();
+@end smallexample
+
+Note that @option{-Wno-attributes=} does not imply @option{-Wno-attributes}.
+
 @item -Wno-builtin-declaration-mismatch
 @opindex Wno-builtin-declaration-mismatch
 @opindex Wbuiltin-declaration-mismatch
diff --git a/gcc/opts.c b/gcc/opts.c
index caed6255500..175b4635bb4 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2611,6 +2611,26 @@ common_handle_option (struct gcc_options *opts,
       /* Currently handled in a prescan.  */
       break;
 
+    case OPT_Wattributes_:
+      if (lang_mask == CL_DRIVER)
+	break;
+
+      if (value)
+	{
+	  error_at (loc, "arguments ignored for %<-Wattributes=%>; use "
+		    "%<-Wno-attributes=%> instead");
+	  break;
+	}
+      else if (arg[strlen (arg) - 1] == ',')
+	{
+	  error_at (loc, "trailing %<,%> in arguments for "
+		    "%<-Wno-attributes=%>");
+	  break;
+	}
+
+      add_comma_separated_to_vector (&opts->x_flag_ignored_attributes, arg);
+      break;
+
     case OPT_Werror:
       dc->warning_as_error_requested = value;
       break;
diff --git a/gcc/plugin.h b/gcc/plugin.h
index 1640e253ca5..5556763d1bf 100644
--- a/gcc/plugin.h
+++ b/gcc/plugin.h
@@ -197,7 +197,9 @@ invoke_plugin_callbacks (int event ATTRIBUTE_UNUSED,
 /* In attribs.c.  */
 
 extern void register_attribute (const struct attribute_spec *attr);
+/* The default argument for the third parameter is given in attribs.h.  */
 extern struct scoped_attributes* register_scoped_attributes (const struct attribute_spec *,
-							     const char *);
+							     const char *,
+							     bool);
 
 #endif /* PLUGIN_H */
diff --git a/gcc/testsuite/c-c++-common/Wno-attributes-1.c b/gcc/testsuite/c-c++-common/Wno-attributes-1.c
new file mode 100644
index 00000000000..aac1a69fd85
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wno-attributes-1.c
@@ -0,0 +1,55 @@
+/* PR c++/101940 */
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c++11" { target c++ } } */
+/* { dg-additional-options "-Wno-attributes=company::,yoyodyne::attr" } */
+/* { dg-additional-options "-Wno-attributes=c1::attr,c1::attr,c1::__attr__" } */
+/* { dg-additional-options "-Wno-attributes=c2::,c2::attr" } */
+/* { dg-additional-options "-Wno-attributes=c3::attr,c3::" } */
+/* { dg-additional-options "-Wno-attributes=x::" } */
+/* { dg-additional-options "-Wno-attributes=yoyodyne::attr_new" } */
+/* { dg-additional-options "-Wno-attributes=c4::__attr__" } */
+/* { dg-additional-options "-Wno-attributes=c5::attr" } */
+/* { dg-additional-options "-Wno-attributes=__c6__::attr" } */
+
+[[company::attr]] void f1();
+[[company::attr2]] void f2();
+
+[[yoyodyne::attr]] void f3();
+[[yoyodyne::__attr__]] void f3__();
+[[yoyodyne::attrx]] void f4(); /* { dg-warning "ignored" } */
+[[yoyodyne::__attrx__]] void f4__(); /* { dg-warning "ignored" } */
+
+[[c1::attr]] void f5();
+
+[[c2::attr]] void f6();
+[[c2::attrx]] void f7();
+[[c2::__attr__]] void f6__();
+[[c2::__attrx__]] void f7__();
+
+[[c3::attr]] void f8();
+[[c3::attrx]] void f9();
+
+[[x::x]] void f10();
+
+[[yoyodyne::attr_new]] void f11();
+[[yoyodyne::__attr_new__]] void f11__();
+[[yoyodyne::attr_mew]] void f12(); /* { dg-warning "ignored" } */
+[[yoyodyne::__attr_mew__]] void f12__(); /* { dg-warning "ignored" } */
+
+[[c4::attr]] void f13();
+[[c4::__attr__]] void f13__();
+[[c4::attrx]] void f14(); /* { dg-warning "ignored" } */
+
+[[c5::attr]] void f15();
+[[c5::__attr__]] void f15__();
+[[__c5__::attr]] void __f15();
+[[__c5__::__attr__]] void __f15__();
+[[c5::attrx]] void f15x(); /* { dg-warning "ignored" } */
+[[__c5__::attrx]] void f15x(); /* { dg-warning "ignored" } */
+
+[[c6::attr]] void f16();
+[[c6::__attr__]] void f16__();
+[[__c6__::attr]] void __f16();
+[[__c6__::__attr__]] void __f16__();
+[[c6::attrx]] void f16x(); /* { dg-warning "ignored" } */
+[[__c6__::attrx]] void f16x(); /* { dg-warning "ignored" } */
diff --git a/gcc/testsuite/c-c++-common/Wno-attributes-2.c b/gcc/testsuite/c-c++-common/Wno-attributes-2.c
new file mode 100644
index 00000000000..4307c74b048
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wno-attributes-2.c
@@ -0,0 +1,56 @@
+/* PR c++/101940 */
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c++11" { target c++ } } */
+
+#pragma GCC diagnostic ignored_attributes "company::,yoyodyne::attr"
+#pragma GCC diagnostic ignored_attributes "c1::attr,c1::attr,c1::__attr__"
+#pragma GCC diagnostic ignored_attributes "c2::,c2::attr"
+#pragma GCC diagnostic ignored_attributes "c3::attr,c3::"
+#pragma GCC diagnostic ignored_attributes "x::"
+#pragma GCC diagnostic ignored_attributes "yoyodyne::attr_new"
+#pragma GCC diagnostic ignored_attributes "c4::__attr__"
+#pragma GCC diagnostic ignored_attributes "c5::attr"
+#pragma GCC diagnostic ignored_attributes "__c6__::attr"
+
+[[company::attr]] void f1();
+[[company::attr2]] void f2();
+
+[[yoyodyne::attr]] void f3();
+[[yoyodyne::__attr__]] void f3__();
+[[yoyodyne::attrx]] void f4(); /* { dg-warning "ignored" } */
+[[yoyodyne::__attrx__]] void f4__(); /* { dg-warning "ignored" } */
+
+[[c1::attr]] void f5();
+
+[[c2::attr]] void f6();
+[[c2::attrx]] void f7();
+[[c2::__attr__]] void f6__();
+[[c2::__attrx__]] void f7__();
+
+[[c3::attr]] void f8();
+[[c3::attrx]] void f9();
+
+[[x::x]] void f10();
+
+[[yoyodyne::attr_new]] void f11();
+[[yoyodyne::__attr_new__]] void f11__();
+[[yoyodyne::attr_mew]] void f12(); /* { dg-warning "ignored" } */
+[[yoyodyne::__attr_mew__]] void f12__(); /* { dg-warning "ignored" } */
+
+[[c4::attr]] void f13();
+[[c4::__attr__]] void f13__();
+[[c4::attrx]] void f14(); /* { dg-warning "ignored" } */
+
+[[c5::attr]] void f15();
+[[c5::__attr__]] void f15__();
+[[__c5__::attr]] void __f15();
+[[__c5__::__attr__]] void __f15__();
+[[c5::attrx]] void f15x(); /* { dg-warning "ignored" } */
+[[__c5__::attrx]] void f15x(); /* { dg-warning "ignored" } */
+
+[[c6::attr]] void f16();
+[[c6::__attr__]] void f16__();
+[[__c6__::attr]] void __f16();
+[[__c6__::__attr__]] void __f16__();
+[[c6::attrx]] void f16x(); /* { dg-warning "ignored" } */
+[[__c6__::attrx]] void f16x(); /* { dg-warning "ignored" } */
diff --git a/gcc/testsuite/c-c++-common/Wno-attributes-3.c b/gcc/testsuite/c-c++-common/Wno-attributes-3.c
new file mode 100644
index 00000000000..64370f2ef6f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wno-attributes-3.c
@@ -0,0 +1,9 @@
+/* PR c++/101940 */
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-attributes=___::" } */
+/* { dg-additional-options "-Wno-attributes=c::____" } */
+/* { dg-additional-options "-Wno-attributes=____::____" } */
+/* { dg-additional-options "-Wno-attributes=c@::attr" } */
+/* { dg-additional-options "-Wno-attributes=c2::@tr" } */
+
+/* { dg-error "wrong argument to ignored attributes" "" { target *-*-* } 0 } */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index e91f083f8ff..99276bde87d 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -457,6 +457,8 @@ compile_file (void)
   if (flag_dump_locations)
     dump_location_info (stderr);
 
+  free_attr_data ();
+
   /* Compilation is now finished except for writing
      what's left of the symbol table output.  */


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-11-10 14:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-10 14:26 [gcc r12-5123] attribs: Implement -Wno-attributes=vendor::attr [PR101940] Marek Polacek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).