public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-6355] c++: Don't diagnose ignoring of attributes if all ignored attributes are attribute_ignored_p
@ 2023-12-09  9:28 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2023-12-09  9:28 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:388ab03975c5c6b3c434ebb95c56c07ea8932486

commit r14-6355-g388ab03975c5c6b3c434ebb95c56c07ea8932486
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Dec 9 10:20:05 2023 +0100

    c++: Don't diagnose ignoring of attributes if all ignored attributes are attribute_ignored_p
    
    There is another thing I wonder about: with -Wno-attributes= we are
    supposed to ignore the attributes altogether, but we are actually still
    warning about them when we emit these generic warnings about ignoring
    all attributes which appertain to this and that (perhaps with some
    exceptions we first remove from the attribute chain), like:
    void foo () { [[foo::bar]]; }
    with -Wattributes -Wno-attributes=foo::bar
    Shouldn't we call some helper function in cases like this and warn
    not when std_attrs (or how the attribute chain var is called) is non-NULL,
    but if it is non-NULL and contains at least one non-attribute_ignored_p
    attribute?
    
    I've kept warnings for cases where the C++ standard says explicitly any
    attributes aren't ok -
    "If an attribute-specifier-seq appertains to a friend declaration, that
    declaration shall be a definition."
    or
    https://eel.is/c++draft/dcl.type.elab#3
    or
    https://eel.is/c++draft/temp.spec#temp.explicit-3
    
    For some changes I haven't figured out how could I cover it in the
    testsuite.
    
    Note, C uses a different strategy, it has c_warn_unused_attributes
    function which warns about all the attributes one by one unless they
    are ignored (or allowed in certain position).
    Though that is just a single diagnostic wording, while C++ FE just warns
    that there are some ignored attributes and doesn't name them individually
    (except for namespace and using namespace) and uses different wordings in
    different spots.
    
    2023-12-09  Jakub Jelinek  <jakub@redhat.com>
    
    gcc/
            * attribs.h (any_nonignored_attribute_p): Declare.
            * attribs.cc (any_nonignored_attribute_p): New function.
    gcc/cp/
            * parser.cc (cp_parser_statement, cp_parser_expression_statement,
            cp_parser_declaration, cp_parser_asm_definition): Don't diagnose
            ignored attributes if !any_nonignored_attribute_p.
            * decl.cc (grokdeclarator): Likewise.
            * name-lookup.cc (handle_namespace_attrs, finish_using_directive):
            Don't diagnose ignoring of attr_ignored_p attributes.
    gcc/testsuite/
            * g++.dg/warn/Wno-attributes-1.C: New test.

Diff:
---
 gcc/attribs.cc                               | 13 +++++++
 gcc/attribs.h                                |  1 +
 gcc/cp/decl.cc                               |  3 +-
 gcc/cp/name-lookup.cc                        |  4 +--
 gcc/cp/parser.cc                             | 11 +++---
 gcc/testsuite/g++.dg/warn/Wno-attributes-1.C | 52 ++++++++++++++++++++++++++++
 6 files changed, 75 insertions(+), 9 deletions(-)

diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index ff4b638c25c..776655dde00 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -584,6 +584,19 @@ attribute_ignored_p (const attribute_spec *const as)
   return as->max_length == -2;
 }
 
+/* Return true if the ATTRS chain contains at least one attribute which
+   is not ignored.  */
+
+bool
+any_nonignored_attribute_p (tree attrs)
+{
+  for (tree attr = attrs; attr; attr = TREE_CHAIN (attr))
+    if (!attribute_ignored_p (attr))
+      return true;
+
+  return false;
+}
+
 /* See whether LIST contains at least one instance of attribute ATTR
    (possibly with different arguments).  Return the first such attribute
    if so, otherwise return null.  */
diff --git a/gcc/attribs.h b/gcc/attribs.h
index fdeebff1cd9..2c615a45663 100644
--- a/gcc/attribs.h
+++ b/gcc/attribs.h
@@ -48,6 +48,7 @@ extern void apply_tm_attr (tree, tree);
 extern tree make_attribute (const char *, const char *, tree);
 extern bool attribute_ignored_p (tree);
 extern bool attribute_ignored_p (const attribute_spec *const);
+extern bool any_nonignored_attribute_p (tree);
 
 extern struct scoped_attributes *
   register_scoped_attributes (const scoped_attribute_specs &, bool = false);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 4b685270097..b1ada1d5215 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -13058,7 +13058,8 @@ grokdeclarator (const cp_declarator *declarator,
       && !diagnose_misapplied_contracts (declspecs->std_attributes))
     {
       location_t attr_loc = declspecs->locations[ds_std_attribute];
-      if (warning_at (attr_loc, OPT_Wattributes, "attribute ignored"))
+      if (any_nonignored_attribute_p (declspecs->std_attributes)
+	  && warning_at (attr_loc, OPT_Wattributes, "attribute ignored"))
 	inform (attr_loc, "an attribute that appertains to a type-specifier "
 		"is ignored");
     }
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 76f1d44610a..09dc6ef3e5a 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -6356,7 +6356,7 @@ handle_namespace_attrs (tree ns, tree attributes)
 	    DECL_ATTRIBUTES (ns) = tree_cons (name, args,
 					      DECL_ATTRIBUTES (ns));
 	}
-      else
+      else if (!attribute_ignored_p (d))
 	{
 	  warning (OPT_Wattributes, "%qD attribute directive ignored",
 		   name);
@@ -8703,7 +8703,7 @@ finish_using_directive (tree target, tree attribs)
 		diagnosed = true;
 	      }
 	  }
-	else
+	else if (!attribute_ignored_p (a))
 	  warning (OPT_Wattributes, "%qD attribute directive ignored", name);
       }
 }
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index ca91a50f059..de7af150781 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -12778,9 +12778,8 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
     SET_EXPR_LOCATION (statement, statement_location);
 
   /* Allow "[[fallthrough]];" or "[[assume(cond)]];", but warn otherwise.  */
-  if (std_attrs != NULL_TREE)
-    warning_at (attrs_loc,
-		OPT_Wattributes,
+  if (std_attrs != NULL_TREE && any_nonignored_attribute_p (std_attrs))
+    warning_at (attrs_loc, OPT_Wattributes,
 		"attributes at the beginning of statement are ignored");
 }
 
@@ -12989,7 +12988,7 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
     }
 
   /* Allow "[[fallthrough]];", but warn otherwise.  */
-  if (attr != NULL_TREE)
+  if (attr != NULL_TREE && any_nonignored_attribute_p (attr))
     warning_at (loc, OPT_Wattributes,
 		"attributes at the beginning of statement are ignored");
 
@@ -15194,7 +15193,7 @@ cp_parser_declaration (cp_parser* parser, tree prefix_attrs)
 	    }
 	}
 
-      if (std_attrs != NULL_TREE && !attribute_ignored_p (std_attrs))
+      if (std_attrs != NULL_TREE && any_nonignored_attribute_p (std_attrs))
 	warning_at (make_location (attrs_loc, attrs_loc, parser->lexer),
 		    OPT_Wattributes, "attribute ignored");
       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
@@ -22675,7 +22674,7 @@ cp_parser_asm_definition (cp_parser* parser)
 	symtab->finalize_toplevel_asm (string);
     }
 
-  if (std_attrs)
+  if (std_attrs && any_nonignored_attribute_p (std_attrs))
     warning_at (asm_loc, OPT_Wattributes,
 		"attributes ignored on %<asm%> declaration");
 }
diff --git a/gcc/testsuite/g++.dg/warn/Wno-attributes-1.C b/gcc/testsuite/g++.dg/warn/Wno-attributes-1.C
new file mode 100644
index 00000000000..863ca5c4892
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wno-attributes-1.C
@@ -0,0 +1,52 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-attributes=bar:: -Wno-attributes=baz::qux" }
+
+[[foo::bar]];				// { dg-warning "attribute ignored" }
+[[bar::foo, foo::bar, baz::qux]];	// { dg-warning "attribute ignored" }
+[[bar::foo, bar::bar, baz::qux]];	// { dg-bogus "attribute ignored" }
+
+namespace [[foo::bar]] N {		// { dg-warning "'bar' attribute directive ignored" }
+  int n;
+}
+namespace [[bar::foo, foo::bar, baz::qux]] O { // { dg-warning "'bar' attribute directive ignored" }
+  int o;
+}
+namespace [[bar::foo, bar::bar, baz::qux]] P { // { dg-bogus "attribute directive ignored" }
+  int p;
+}
+
+void
+foo ()
+{
+  int i = 0;
+  [[foo::bar]];				// { dg-warning "attributes at the beginning of statement are ignored" }
+  [[bar::foo, foo::bar, baz::qux]];	// { dg-warning "attributes at the beginning of statement are ignored" }
+  [[bar::foo, bar::bar, baz::qux]];	// { dg-bogus "attributes at the beginning of statement are ignored" }
+  [[foo::bar]] ++i;			// { dg-warning "attributes at the beginning of statement are ignored" }
+  [[bar::foo, foo::bar, baz::qux]] ++i;	// { dg-warning "attributes at the beginning of statement are ignored" }
+  [[bar::foo, bar::bar, baz::qux]] ++i;	// { dg-bogus "attributes at the beginning of statement are ignored" }
+  [[foo::bar]] asm ("");		// { dg-warning "attributes ignored on 'asm' declaration" }
+  [[bar::foo, foo::bar, baz::qux]] asm (""); // { dg-warning "attributes ignored on 'asm' declaration" }
+  [[bar::foo, bar::bar, baz::qux]] asm (""); // { dg-bogus "attributes ignored on 'asm' declaration" }
+  [[foo::bar]] using namespace N;	// { dg-warning "'bar' attribute directive ignored" }
+  [[bar::foo, foo::bar, baz::qux]] using namespace O; // { dg-warning "'bar' attribute directive ignored" }
+  [[bar::foo, bar::bar, baz::qux]] using namespace P; // { dg-bogus "attribute directive ignored" }
+}
+
+class S
+{
+  [[foo::bar]] friend int bar (S &);	// { dg-warning "attribute ignored" }
+					// { dsg-message "an attribute that appertains to a friend declaration that is not a definition is ignored" "" { target *-*-* } .-1 }
+  [[bar::foo, foo::bar, baz::qux]] friend int baz (S &); // { dg-warning "attribute ignored" }
+					// { dsg-message "an attribute that appertains to a friend declaration that is not a definition is ignored" "" { target *-*-* } .-1 }
+  [[bar::foo, bar::bar, baz::qux]] friend int qux (S &); // { dg-warning "attribute ignored" }
+					// { dsg-message "an attribute that appertains to a friend declaration that is not a definition is ignored" "" { target *-*-* } .-1 }
+public:
+  int s;
+};
+
+int [[foo::bar]] i;			// { dg-warning "attribute ignored" }
+					// { dg-message "an attribute that appertains to a type-specifier is ignored" "" { target *-*-* } .-1 }
+int [[bar::foo, foo::bar, baz::qux]] j;	// { dg-warning "attribute ignored" }
+					// { dg-message "an attribute that appertains to a type-specifier is ignored" "" { target *-*-* } .-1 }
+int [[bar::foo, bar::bar, baz::qux]] k;	// { dg-bogus "attribute ignored" }

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

only message in thread, other threads:[~2023-12-09  9:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-09  9:28 [gcc r14-6355] c++: Don't diagnose ignoring of attributes if all ignored attributes are attribute_ignored_p Jakub Jelinek

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).