aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp0x
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-03-06 18:26:37 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2025-03-06 18:26:37 +0100
commit179e01085b0aed111ef1f7908c4b87c800f880e9 (patch)
treed3ca396d5628fd1ed79880a8ca9c6d619e915da4 /gcc/testsuite/g++.dg/cpp0x
parent0ba3e5ff14a48f1fb7ca53cb86194e08d5b5da66 (diff)
downloadgcc-179e01085b0aed111ef1f7908c4b87c800f880e9.zip
gcc-179e01085b0aed111ef1f7908c4b87c800f880e9.tar.gz
gcc-179e01085b0aed111ef1f7908c4b87c800f880e9.tar.bz2
c++: Update TYPE_FIELDS of variant types if cp_parser_late_parsing_default_args etc. modify it [PR98533]
The following testcases ICE during type verification, because TYPE_FIELDS of e.g. S RECORD_TYPE in pr119123.C is different from TYPE_FIELDS of const S. Various decls are added to S's TYPE_FIELDS first, then finish_struct indirectly calls fixup_type_variants to sync the variant copies. But later on cp_parser_class_specifier calls cp_parser_late_parsing_default_args and that apparently adds a lambda type (from default argument) to TYPE_FIELDS of S. Dunno if that is right or not, assuming it is right, the following patch fixes it by updating TYPE_FIELDS of variant types if there were any changes in the various functions cp_parser_class_specifier defers and calls on the outermost enclosing class. There was quite a lot of code repetition already before, so the patch uses a lambda to avoid the repetitions. To my surprise, in some of the contract testcases ( g++.dg/contracts/contracts-friend1.C g++.dg/contracts/contracts-nested-class1.C g++.dg/contracts/contracts-nested-class2.C g++.dg/contracts/contracts-redecl7.C g++.dg/contracts/contracts-redecl8.C ) it is actually setting class_type and pushing TRANSLATION_UNIT_DECL rather than some class types in some cases. Or should the lambda pushing into the containing class be somehow avoided? 2025-03-06 Jakub Jelinek <jakub@redhat.com> PR c++/98533 PR c++/119123 * parser.cc (cp_parser_class_specifier): Update TYPE_FIELDS of variant types in case cp_parser_late_parsing_default_args etc. change TYPE_FIELDS on the main variant. Add switch_to_class lambda and use it to simplify repeated class switching code. * g++.dg/cpp0x/pr98533.C: New test. * g++.dg/cpp0x/pr119123.C: New test.
Diffstat (limited to 'gcc/testsuite/g++.dg/cpp0x')
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr119123.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr98533.C25
2 files changed, 35 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr119123.C b/gcc/testsuite/g++.dg/cpp0x/pr119123.C
new file mode 100644
index 0000000..bbc1ca0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr119123.C
@@ -0,0 +1,10 @@
+// PR c++/119123
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -g" }
+
+struct S {
+ template <typename> void foo (int = [] {}) const;
+};
+struct T {
+ static void bar (const S &);
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr98533.C b/gcc/testsuite/g++.dg/cpp0x/pr98533.C
new file mode 100644
index 0000000..c279d02
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr98533.C
@@ -0,0 +1,25 @@
+// PR c++/98533
+// { dg-do compile { target c++11 } }
+// { dg-options "-g" }
+
+class IR;
+struct Pass {
+ explicit Pass(IR *ir) : ir_(ir) {}
+ virtual ~Pass() = default;
+ IR *ir_ {nullptr};
+};
+struct PassManager {
+ template <typename T> void RunPass() { T pass(ir_); }
+ IR *ir_ {nullptr};
+};
+struct IR final {
+ template <typename T> void RunPass() { pass_manager_.RunPass<T>(); }
+ PassManager pass_manager_;
+};
+struct ThePass : Pass {
+ explicit ThePass(IR *ir) : Pass(ir) {}
+ ThePass(const ThePass &) = delete;
+ template <typename Func = bool (*)(void *)> void Bar(void *inst, Func func = [](void *) {});
+};
+
+void foo(IR *ir) { ir->RunPass<ThePass>(); }