From 53130f756045ccc520dc6ec8a6881dedfad8b46a Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sun, 10 Jul 2011 10:24:03 -0400 Subject: [PATCH] re PR c++/49691 (ICE in cp_parser_late_return_type_opt, at cp/parser.c:15562) PR c++/49691 * parser.c (cp_parser_late_return_type_opt): Check quals parameter rather than current_class_type to determine whether to set 'this'. (cp_parser_direct_declarator): Pass -1 to quals if member_p is false. (cp_parser_init_declarator): Pass down member_p. From-SVN: r176120 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/parser.c | 13 ++++++++----- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/g++.dg/cpp0x/regress/regress6.C | 11 +++++++++++ gcc/testsuite/g++.dg/parse/crash45.C | 2 +- gcc/testsuite/g++.dg/template/crash38.C | 2 +- gcc/testsuite/g++.dg/template/crash64.C | 2 +- 7 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/regress/regress6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c19e8b38762..765c33bcaec 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2011-07-10 Jason Merrill + + PR c++/49691 + * parser.c (cp_parser_late_return_type_opt): Check quals parameter + rather than current_class_type to determine whether to set 'this'. + (cp_parser_direct_declarator): Pass -1 to quals if member_p is false. + (cp_parser_init_declarator): Pass down member_p. + 2011-07-09 Jason Merrill * tree.c (build_vec_init_elt): Strip TARGET_EXPR. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 6bb15ed9508..64be92335da 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -14388,7 +14388,7 @@ cp_parser_init_declarator (cp_parser* parser, = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, &ctor_dtor_or_conv_p, /*parenthesized_p=*/NULL, - /*member_p=*/false); + member_p); /* Gather up the deferred checks. */ stop_deferring_access_checks (); @@ -14971,8 +14971,8 @@ cp_parser_direct_declarator (cp_parser* parser, /* Parse the virt-specifier-seq. */ virt_specifiers = cp_parser_virt_specifier_seq_opt (parser); - late_return - = cp_parser_late_return_type_opt (parser, cv_quals); + late_return = (cp_parser_late_return_type_opt + (parser, member_p ? cv_quals : -1)); /* Create the function-declarator. */ declarator = make_call_declarator (declarator, @@ -15538,7 +15538,10 @@ cp_parser_virt_specifier_seq_opt (cp_parser* parser) -> trailing-type-specifier-seq abstract-declarator(opt) - Returns the type indicated by the type-id. */ + Returns the type indicated by the type-id. + + QUALS is either a bitmask of cv_qualifiers or -1 for a non-member + function. */ static tree cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals) @@ -15555,7 +15558,7 @@ cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals) /* Consume the ->. */ cp_lexer_consume_token (parser->lexer); - if (current_class_type) + if (quals >= 0) { /* DR 1207: 'this' is in scope in the trailing return type. */ tree this_parm = build_this_parm (current_class_type, quals); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fa71dde0df1..cfc09f049a2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-07-09 Jason Merrill + + * g++.dg/cpp0x/regress/regress6.C: New. + * g++.dg/parse/crash45.C: Adjust message. + * g++.dg/template/crash38.C: Adjust message. + * g++.dg/template/crash64.C: Adjust message. + 2011-07-09 H.J. Lu * c-c++-common/dfp/func-vararg-alternate-d128-2.c: Support x32. diff --git a/gcc/testsuite/g++.dg/cpp0x/regress/regress6.C b/gcc/testsuite/g++.dg/cpp0x/regress/regress6.C new file mode 100644 index 00000000000..6de64c0b347 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/regress/regress6.C @@ -0,0 +1,11 @@ +// PR c++/49691 +// { dg-options -std=c++0x } + +struct A { int x; }; +A* f(); +struct B { + void g() + { + int(f()->x); + } +}; diff --git a/gcc/testsuite/g++.dg/parse/crash45.C b/gcc/testsuite/g++.dg/parse/crash45.C index 8696ab4bb3c..d2fbc8ca97c 100644 --- a/gcc/testsuite/g++.dg/parse/crash45.C +++ b/gcc/testsuite/g++.dg/parse/crash45.C @@ -3,5 +3,5 @@ struct A { - template int f (B); // { dg-error "was not declared in this scope|cannot be a member template" } + template int f (B); // { dg-error "was not declared in this scope|cannot be a member template|has not been declared" } }; diff --git a/gcc/testsuite/g++.dg/template/crash38.C b/gcc/testsuite/g++.dg/template/crash38.C index c652cc86f6e..f4cf299859c 100644 --- a/gcc/testsuite/g++.dg/template/crash38.C +++ b/gcc/testsuite/g++.dg/template/crash38.C @@ -4,5 +4,5 @@ class A { template static void f(X&); // { dg-error "" } - inline void A::f(X&); // { dg-error "f|expected" } + inline void A::f(X&); // { dg-error "f|expected|not been declared" } }; diff --git a/gcc/testsuite/g++.dg/template/crash64.C b/gcc/testsuite/g++.dg/template/crash64.C index 750e3daf19e..1d8fd009803 100644 --- a/gcc/testsuite/g++.dg/template/crash64.C +++ b/gcc/testsuite/g++.dg/template/crash64.C @@ -2,5 +2,5 @@ struct A { - template void foo()(0); // { dg-error "initializer" } + template void foo()(0); // { dg-error "" } }; -- 2.30.2