Tested x86_64-pc-linux-gnu, OK for trunk?
gcc/ChangeLog:
PR c++/94492
* diagnostic.h (warning_enabled): Declare.
* diagnostic.c (diagnostic_enabled): Factor out from...
(diagnostic_report_diagnostic): ...here.
(warning_enabled): New.
gcc/cp/ChangeLog:
PR c++/94492
* decl2.c (cp_warn_deprecated_use): Check warning_enabled.
gcc/testsuite/ChangeLog:
PR c++/94492
* g++.dg/cpp0x/depr-copy4.C: New test.
---
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(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/depr-copy4.C
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 9a6eefcf918..caa97da2df9 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 (int, location_t = input_location);
+
#endif /* ! GCC_DIAGNOSTIC_H */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a82960fb39c..03b7a68aba2 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -5495,10 +5495,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 (OPT_Wdeprecated_copy,
+ DECL_SOURCE_LOCATION (decl)))
{
auto_diagnostic_group d;
tree ctx = DECL_CONTEXT (decl);
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 246d75256cf..278ec8b706f 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. */
+
+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 (int opt, location_t loc)
+{
+ 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;
+}
base-commit: f9d670128f6e6b3631a2db575ddf6f19fa43afdc