public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-1144] c++: -Wdeprecated-copy and #pragma diagnostic [PR94492]
@ 2021-06-01 15:38 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2021-06-01 15:38 UTC (permalink / raw)
  To: gcc-cvs

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;
+}


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

only message in thread, other threads:[~2021-06-01 15:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-01 15:38 [gcc r12-1144] c++: -Wdeprecated-copy and #pragma diagnostic [PR94492] Jason Merrill

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