aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-09-27 16:07:40 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2024-09-27 16:07:40 +0200
commit64072e60b1599ae7d347c2cdee46c3b0e37fc338 (patch)
tree4ab233a209c4ce21a2d155b33e1634d997888f63
parentddc72ba6c6c2c84a1a95340840bd5fde1f2bde44 (diff)
downloadgcc-64072e60b1599ae7d347c2cdee46c3b0e37fc338.zip
gcc-64072e60b1599ae7d347c2cdee46c3b0e37fc338.tar.gz
gcc-64072e60b1599ae7d347c2cdee46c3b0e37fc338.tar.bz2
diagnostic: Save/restore diagnostic context history and push/pop state for PCH [PR116847]
The following patch on top of the just posted cleanup patch saves/restores the m_classification_history and m_push_list vectors for PCH. Without that as the testcase shows during parsing of the templates we don't report ignored diagnostics, but after loading PCH header when instantiating those templates those warnings can be emitted. This doesn't show up on x86_64-linux build because configure injects there -fcf-protection -mshstk flags during library build (and so also during PCH header creation), but make check doesn't use those flags and so the PCH header is ignored. 2024-09-26 Jakub Jelinek <jakub@redhat.com> PR libstdc++/116847 gcc/ * diagnostic.h (diagnostic_option_classifier): Add pch_save and pch_restore method declarations. (diagnostic_context): Add pch_save and pch_restore inline method definitions. * diagnostic.cc (diagnostic_option_classifier::pch_save): New method. (diagnostic_option_classifier::pch_restore): Likewise. gcc/c-family/ * c-pch.cc: Include diagnostic.h. (c_common_write_pch): Call global_dc->pch_save. (c_common_read_pch): Call global_dc->pch_restore. gcc/testsuite/ * g++.dg/pch/pr116847.C: New test. * g++.dg/pch/pr116847.Hs: New test.
-rw-r--r--gcc/c-family/c-pch.cc8
-rw-r--r--gcc/diagnostic.cc40
-rw-r--r--gcc/diagnostic.h15
-rw-r--r--gcc/testsuite/g++.dg/pch/pr116847.C10
-rw-r--r--gcc/testsuite/g++.dg/pch/pr116847.Hs8
5 files changed, 80 insertions, 1 deletions
diff --git a/gcc/c-family/c-pch.cc b/gcc/c-family/c-pch.cc
index 9bcfdc8..f104575 100644
--- a/gcc/c-family/c-pch.cc
+++ b/gcc/c-family/c-pch.cc
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-pragma.h"
#include "langhooks.h"
#include "hosthooks.h"
+#include "diagnostic.h"
/* This is a list of flag variables that must match exactly, and their
names for the error message. The possible values for *flag_var must
@@ -178,7 +179,8 @@ c_common_write_pch (void)
cpp_write_pch_state (parse_in, pch_outfile);
timevar_pop (TV_PCH_CPP_SAVE);
- if (fseek (pch_outfile, 0, SEEK_SET) != 0
+ if (global_dc->pch_save (pch_outfile) < 0
+ || fseek (pch_outfile, 0, SEEK_SET) != 0
|| fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
fatal_error (input_location, "cannot write %s: %m", pch_file);
@@ -359,6 +361,10 @@ c_common_read_pch (cpp_reader *pfile, const char *name,
linemap_line_start (line_table, saved_loc.line, 0);
timevar_pop (TV_PCH_CPP_RESTORE);
+
+ if (global_dc->pch_restore (f) < 0)
+ fatal_error (input_location, "cannot read %s: %m", name);
+
fclose (f);
if (cpp_result != 0)
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index ffe61f7..9462fe6 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -156,6 +156,46 @@ diagnostic_option_classifier::fini ()
m_push_list.release ();
}
+/* Save the diagnostic_option_classifier state to F for PCH
+ output. Returns 0 on success, -1 on error. */
+
+int
+diagnostic_option_classifier::pch_save (FILE *f)
+{
+ unsigned int lengths[2] = { m_classification_history.length (),
+ m_push_list.length () };
+ if (fwrite (lengths, sizeof (lengths), 1, f) != 1
+ || fwrite (m_classification_history.address (),
+ sizeof (diagnostic_classification_change_t),
+ lengths[0], f) != lengths[0]
+ || fwrite (m_push_list.address (), sizeof (int),
+ lengths[1], f) != lengths[1])
+ return -1;
+ return 0;
+}
+
+/* Read the diagnostic_option_classifier state from F for PCH
+ read. Returns 0 on success, -1 on error. */
+
+int
+diagnostic_option_classifier::pch_restore (FILE *f)
+{
+ unsigned int lengths[2];
+ if (fread (lengths, sizeof (lengths), 1, f) != 1)
+ return -1;
+ gcc_checking_assert (m_classification_history.is_empty ());
+ gcc_checking_assert (m_push_list.is_empty ());
+ m_classification_history.safe_grow (lengths[0]);
+ m_push_list.safe_grow (lengths[1]);
+ if (fread (m_classification_history.address (),
+ sizeof (diagnostic_classification_change_t),
+ lengths[0], f) != lengths[0]
+ || fread (m_push_list.address (), sizeof (int),
+ lengths[1], f) != lengths[1])
+ return -1;
+ return 0;
+}
+
/* Save all diagnostic classifications in a stack. */
void
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index c3300fc..3087b19 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -256,6 +256,9 @@ public:
diagnostic_t
update_effective_level_from_pragmas (diagnostic_info *diagnostic) const;
+ int pch_save (FILE *);
+ int pch_restore (FILE *);
+
private:
/* Each time a diagnostic's classification is changed with a pragma,
we record the change and the location of the change in an array of
@@ -551,6 +554,18 @@ public:
const char *, const char *, va_list *,
diagnostic_t) ATTRIBUTE_GCC_DIAG(7,0);
+ int
+ pch_save (FILE *f)
+ {
+ return m_option_classifier.pch_save (f);
+ }
+
+ int
+ pch_restore (FILE *f)
+ {
+ return m_option_classifier.pch_restore (f);
+ }
+
private:
void error_recursion () ATTRIBUTE_NORETURN;
diff --git a/gcc/testsuite/g++.dg/pch/pr116847.C b/gcc/testsuite/g++.dg/pch/pr116847.C
new file mode 100644
index 0000000..e1e4344
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pch/pr116847.C
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++11 } }
+
+#include "pr116847.H"
+
+int a = S<0>::bar ();
+
+int
+main ()
+{
+}
diff --git a/gcc/testsuite/g++.dg/pch/pr116847.Hs b/gcc/testsuite/g++.dg/pch/pr116847.Hs
new file mode 100644
index 0000000..89bbb2d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pch/pr116847.Hs
@@ -0,0 +1,8 @@
+[[deprecated]] int foo () { return 42; }
+template <int N>
+struct S {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+static int bar () { return foo (); }
+#pragma GCC diagnostic pop
+};