This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix up cp_parser_class_specifier_1 error recovery (PR c++/88180, take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 20 Dec 2018 00:12:29 +0100
- Subject: [C++ PATCH] Fix up cp_parser_class_specifier_1 error recovery (PR c++/88180, take 2)
- References: <20181218204930.GT23305@tucnak> <e5f50b21-f12f-a56e-821b-38a6744d47fc@redhat.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
On Tue, Dec 18, 2018 at 05:29:41PM -0500, Jason Merrill wrote:
> So, we end up calling ggc_collect because we're processing a member function
> in a context where defining a type is not allowed. One solution would be to
> not do late parsing of members in such a context.
>
> We don't have this problem with lambdas because cp_parser_lambda_body
> already increments function_depth to avoid GC in the middle of an
> expression.
So like this? We already have similar treatment for error-recovery
if template arguments are erroneous.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2018-12-19 Jakub Jelinek <jakub@redhat.com>
PR c++/88180
* parser.c (cp_parser_class_specifier_1): If
cp_parser_check_type_definition fails, skip default arguments, NSDMIs,
etc. like for erroneous template args.
* g++.dg/parse/pr88180.C: New test.
* g++.dg/pr85039-1.C: Don't expect diagnostics inside of the type
definition's NSDMIs.
--- gcc/cp/parser.c.jj 2018-12-18 22:44:59.229131699 +0100
+++ gcc/cp/parser.c 2018-12-19 11:35:17.250161052 +0100
@@ -23106,7 +23106,7 @@ cp_parser_class_specifier_1 (cp_parser*
cp_ensure_no_oacc_routine (parser);
/* Issue an error message if type-definitions are forbidden here. */
- cp_parser_check_type_definition (parser);
+ bool type_definition_ok_p = cp_parser_check_type_definition (parser);
/* Remember that we are defining one more class. */
++parser->num_classes_being_defined;
/* Inside the class, surrounding template-parameter-lists do not
@@ -23301,7 +23301,7 @@ cp_parser_class_specifier_1 (cp_parser*
cp_default_arg_entry *e;
tree save_ccp, save_ccr;
- if (any_erroneous_template_args_p (type))
+ if (!type_definition_ok_p || any_erroneous_template_args_p (type))
{
/* Skip default arguments, NSDMIs, etc, in order to improve
error recovery (c++/71169, c++/71832). */
--- gcc/testsuite/g++.dg/parse/pr88180.C.jj 2018-12-19 11:25:39.565627093 +0100
+++ gcc/testsuite/g++.dg/parse/pr88180.C 2018-12-19 11:25:39.565627093 +0100
@@ -0,0 +1,12 @@
+// PR c++/88180
+// { dg-do compile }
+// { dg-options "--param ggc-min-heapsize=1024" }
+
+struct d {
+ static d *b;
+} * d::b(__builtin_offsetof(struct { // { dg-error "types may not be defined" }
+ int i;
+ struct a { // { dg-error "types may not be defined" }
+ int c() { return .1f; }
+ };
+}, i));
--- gcc/testsuite/g++.dg/pr85039-1.C.jj 2018-04-17 09:01:04.023044471 +0200
+++ gcc/testsuite/g++.dg/pr85039-1.C 2018-12-20 00:09:32.348914862 +0100
@@ -5,9 +5,9 @@ constexpr int a() {
__builtin_offsetof(struct { // { dg-error "types may not be defined" }
int i;
short b {
- __builtin_offsetof(struct { // { dg-error "types may not be defined" }
+ __builtin_offsetof(struct {
int j;
- struct c { // { dg-error "types may not be defined" }
+ struct c {
void d() {
}
};
Jakub