re PR c++/54359 ([C++0x] decltype in member function's trailing return type when...
authorJason Merrill <jason@redhat.com>
Mon, 18 Mar 2013 03:41:10 +0000 (23:41 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 18 Mar 2013 03:41:10 +0000 (23:41 -0400)
PR c++/54359
PR c++/56639
* parser.c (cp_parser_direct_declarator): Bail if we see a
qualified-id not at namespace scope.

From-SVN: r196765

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/g++.dg/parse/typename7.C
gcc/testsuite/g++.dg/template/arrow2.C [new file with mode: 0644]

index b341e92..b2796b6 100644 (file)
@@ -1,5 +1,10 @@
 2013-03-17  Jason Merrill  <jason@redhat.com>
 
+       PR c++/54359
+       PR c++/56639
+       * parser.c (cp_parser_direct_declarator): Bail if we see a
+       qualified-id not at namespace scope.
+
        PR c++/17232
        PR c++/56642
        * typeck2.c (abstract_virtuals_error_sfinae): Revert complete_type
index 0222e90..23fe3f3 100644 (file)
@@ -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))
index 2d823f8..6ec7696 100644 (file)
@@ -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 (file)
index 0000000..8ec9e01
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/56639
+
+struct A {
+  int i;
+  static A* f();
+};
+
+struct B {
+  void g() {
+    int (A::f()->i);
+  }
+};