This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH for c++/54359 ('this' in trailing-return-type with out-of-class method defn)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 17 Mar 2013 23:45:42 -0400
- Subject: Re: C++ PATCH for c++/54359 ('this' in trailing-return-type with out-of-class method defn)
- References: <51451F3C.1050709@redhat.com>
This patch caused c++/56639: when within a function we were trying to
parse something that could be either a declaration or an expression, we
went to set current_class_ptr and failed the assertion that it wasn't
already set. We could save and restore the value, but instead with this
patch I take advantage of the fact that there can never be a declaration
with a qualified-id at function scope.
Tested x86_64-pc-linux-gnu, applied to trunk.
commit 1d92c03f05ea76a2c10b491f4b31852c8a6b04d5
Author: Jason Merrill <jason@redhat.com>
Date: Sun Mar 17 21:48:31 2013 -0400
PR c++/54359
PR c++/56639
* parser.c (cp_parser_direct_declarator): Bail if we see a
qualified-id not at namespace scope.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 0222e90..23fe3f3 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -16707,9 +16707,18 @@ cp_parser_direct_declarator (cp_parser* parser,
handle_declarator:;
scope = get_scope_of_declarator (declarator);
if (scope)
- /* Any names that appear after the declarator-id for a
- member are looked up in the containing scope. */
- pushed_scope = push_scope (scope);
+ {
+ /* Any names that appear after the declarator-id for a
+ member are looked up in the containing scope. */
+ if (at_function_scope_p ())
+ {
+ /* But declarations with qualified-ids can't appear in a
+ function. */
+ cp_parser_error (parser, "qualified-id in declaration");
+ break;
+ }
+ pushed_scope = push_scope (scope);
+ }
parser->in_declarator_p = true;
if ((ctor_dtor_or_conv_p && *ctor_dtor_or_conv_p)
|| (declarator && declarator->kind == cdk_id))
diff --git a/gcc/testsuite/g++.dg/parse/typename7.C b/gcc/testsuite/g++.dg/parse/typename7.C
index 2d823f8..6ec7696 100644
--- a/gcc/testsuite/g++.dg/parse/typename7.C
+++ b/gcc/testsuite/g++.dg/parse/typename7.C
@@ -22,7 +22,7 @@ struct B
A().bar<typename T>(t); } // { dg-error "expected|parse error|no matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 22 }
void bad(T t) {
- B<typename T>::bar(t); } // { dg-error "invalid|not a template" }
+ B<typename T>::bar(t); } // { dg-error "invalid|qualified-id|not a template" }
};
void baz()
diff --git a/gcc/testsuite/g++.dg/template/arrow2.C b/gcc/testsuite/g++.dg/template/arrow2.C
new file mode 100644
index 0000000..8ec9e01
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/arrow2.C
@@ -0,0 +1,12 @@
+// PR c++/56639
+
+struct A {
+ int i;
+ static A* f();
+};
+
+struct B {
+ void g() {
+ int (A::f()->i);
+ }
+};