public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jason Merrill <jason@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r12-1144] c++: -Wdeprecated-copy and #pragma diagnostic [PR94492]
Date: Tue,  1 Jun 2021 15:38:21 +0000 (GMT)	[thread overview]
Message-ID: <20210601153821.6461B3855036@sourceware.org> (raw)

https://gcc.gnu.org/g:620cd7861e1266991c9c2a82e1e2d5f4d723ec88

commit r12-1144-g620cd7861e1266991c9c2a82e1e2d5f4d723ec88
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Apr 27 17:13:39 2021 -0400

    c++: -Wdeprecated-copy and #pragma diagnostic [PR94492]
    
    -Wdeprecated-copy was depending only on the state of the warning at the
    point where we call the function, making it hard to use #pragma diagnostic
    to suppress the warning for a particular implicitly declared function.
    
    But checking whether the warning is enabled at the location of the implicit
    declaration turned out to be a bit complicated; option_enabled only tests
    whether it was enabled at the start of compilation, the actual test only
    existed in the middle of diagnostic_report_diagnostic.  So this patch
    factors it out and adds a new warning_enabled function to diagnostic.h.
    
    gcc/ChangeLog:
    
            PR c++/94492
            * diagnostic.h (warning_enabled_at): Declare.
            * diagnostic.c (diagnostic_enabled): Factor out from...
            (diagnostic_report_diagnostic): ...here.
            (warning_enabled_at): New.
    
    gcc/cp/ChangeLog:
    
            PR c++/94492
            * decl2.c (cp_warn_deprecated_use): Check warning_enabled_at.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/94492
            * g++.dg/cpp0x/depr-copy4.C: New test.

Diff:
---
 gcc/diagnostic.h                        |  2 +
 gcc/cp/decl2.c                          |  8 ++--
 gcc/diagnostic.c                        | 85 ++++++++++++++++++++++-----------
 gcc/testsuite/g++.dg/cpp0x/depr-copy4.C | 16 +++++++
 4 files changed, 80 insertions(+), 31 deletions(-)

diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 9a6eefcf918..1b9d6b1f64d 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -515,4 +515,6 @@ extern int num_digits (int);
 extern json::value *json_from_expanded_location (diagnostic_context *context,
 						 location_t loc);
 
+extern bool warning_enabled_at (location_t, int);
+
 #endif /* ! GCC_DIAGNOSTIC_H */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 89f874a32cc..e46fded908a 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -5499,10 +5499,10 @@ cp_warn_deprecated_use (tree decl, tsubst_flags_t complain)
       && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
       && copy_fn_p (decl))
     {
-      if (warn_deprecated_copy
-	  /* Don't warn about system library classes (c++/86342).  */
-	  && (!DECL_IN_SYSTEM_HEADER (decl)
-	      || global_dc->dc_warn_system_headers))
+      /* Don't warn if the flag was disabled around the class definition
+	 (c++/94492).  */
+      if (warning_enabled_at (DECL_SOURCE_LOCATION (decl),
+			      OPT_Wdeprecated_copy))
 	{
 	  auto_diagnostic_group d;
 	  tree ctx = DECL_CONTEXT (decl);
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 246d75256cf..d58586f2526 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -1122,6 +1122,62 @@ print_option_information (diagnostic_context *context,
     }
 }
 
+/* Returns whether a DIAGNOSTIC should be printed, and adjusts diagnostic->kind
+   as appropriate for #pragma GCC diagnostic and -Werror=foo.  */
+
+static bool
+diagnostic_enabled (diagnostic_context *context,
+		    diagnostic_info *diagnostic)
+{
+  /* Diagnostics with no option or -fpermissive are always enabled.  */
+  if (!diagnostic->option_index
+      || diagnostic->option_index == permissive_error_option (context))
+    return true;
+
+  /* This tests if the user provided the appropriate -Wfoo or
+     -Wno-foo option.  */
+  if (! context->option_enabled (diagnostic->option_index,
+				 context->lang_mask,
+				 context->option_state))
+    return false;
+
+  /* This tests for #pragma diagnostic changes.  */
+  diagnostic_t diag_class
+    = update_effective_level_from_pragmas (context, diagnostic);
+
+  /* This tests if the user provided the appropriate -Werror=foo
+     option.  */
+  if (diag_class == DK_UNSPECIFIED
+      && (context->classify_diagnostic[diagnostic->option_index]
+	  != DK_UNSPECIFIED))
+    diagnostic->kind
+      = context->classify_diagnostic[diagnostic->option_index];
+
+  /* This allows for future extensions, like temporarily disabling
+     warnings for ranges of source code.  */
+  if (diagnostic->kind == DK_IGNORED)
+    return false;
+
+  return true;
+}
+
+/* Returns whether warning OPT is enabled at LOC.  */
+
+bool
+warning_enabled_at (location_t loc, int opt)
+{
+  if (!diagnostic_report_warnings_p (global_dc, loc))
+    return false;
+
+  rich_location richloc (line_table, loc);
+  diagnostic_info diagnostic = {};
+  diagnostic.option_index = opt;
+  diagnostic.richloc = &richloc;
+  diagnostic.message.m_richloc = &richloc;
+  diagnostic.kind = DK_WARNING;
+  return diagnostic_enabled (global_dc, &diagnostic);
+}
+
 /* Report a diagnostic message (an error or a warning) as specified by
    DC.  This function is *the* subroutine in terms of which front-ends
    should implement their specific diagnostic handling modules.  The
@@ -1172,33 +1228,8 @@ diagnostic_report_diagnostic (diagnostic_context *context,
       && diagnostic->kind == DK_WARNING)
     diagnostic->kind = DK_ERROR;
 
-  if (diagnostic->option_index
-      && diagnostic->option_index != permissive_error_option (context))
-    {
-      /* This tests if the user provided the appropriate -Wfoo or
-	 -Wno-foo option.  */
-      if (! context->option_enabled (diagnostic->option_index,
-				     context->lang_mask,
-				     context->option_state))
-	return false;
-
-      /* This tests for #pragma diagnostic changes.  */
-      diagnostic_t diag_class
-	= update_effective_level_from_pragmas (context, diagnostic);
-
-      /* This tests if the user provided the appropriate -Werror=foo
-	 option.  */
-      if (diag_class == DK_UNSPECIFIED
-	  && (context->classify_diagnostic[diagnostic->option_index]
-	      != DK_UNSPECIFIED))
-	diagnostic->kind
-	  = context->classify_diagnostic[diagnostic->option_index];
-
-      /* This allows for future extensions, like temporarily disabling
-	 warnings for ranges of source code.  */
-      if (diagnostic->kind == DK_IGNORED)
-	return false;
-    }
+  if (!diagnostic_enabled (context, diagnostic))
+    return false;
 
   if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE)
     diagnostic_check_max_errors (context);
diff --git a/gcc/testsuite/g++.dg/cpp0x/depr-copy4.C b/gcc/testsuite/g++.dg/cpp0x/depr-copy4.C
new file mode 100644
index 00000000000..42852a70558
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/depr-copy4.C
@@ -0,0 +1,16 @@
+// PR c++/94492
+// { dg-additional-options -Wdeprecated-copy }
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+struct expr
+{
+    int a, b;
+    expr& operator=(const expr&) { return *this; }
+};
+#pragma GCC diagnostic pop
+
+expr foo(expr e)
+{
+    return e;
+}


                 reply	other threads:[~2021-06-01 15:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210601153821.6461B3855036@sourceware.org \
    --to=jason@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).