re PR c++/49691 (ICE in cp_parser_late_return_type_opt, at cp/parser.c:15562)
authorJason Merrill <jason@redhat.com>
Sun, 10 Jul 2011 14:24:03 +0000 (10:24 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 10 Jul 2011 14:24:03 +0000 (10:24 -0400)
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
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/regress/regress6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/crash45.C
gcc/testsuite/g++.dg/template/crash38.C
gcc/testsuite/g++.dg/template/crash64.C

index c19e8b38762ce48137a2108f5e8b5713e63fd1fa..765c33bcaec30887415a62b3c0b05e95c5830b38 100644 (file)
@@ -1,3 +1,11 @@
+2011-07-10  Jason Merrill  <jason@redhat.com>
+
+       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  <jason@redhat.com>
 
        * tree.c (build_vec_init_elt): Strip TARGET_EXPR.
index 6bb15ed9508f5bbb55de35d01d7bd8871d1ec115..64be92335dad5e764db64986df200eaebcc51bf6 100644 (file)
@@ -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);
index fa71dde0df1c5bb7171d12dce064748bf679f014..cfc09f049a2e05b768e654636a45382f9227b099 100644 (file)
@@ -1,3 +1,10 @@
+2011-07-09  Jason Merrill  <jason@redhat.com>
+
+       * 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  <hongjiu.lu@intel.com>
 
        * 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 (file)
index 0000000..6de64c0
--- /dev/null
@@ -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);
+  }
+};
index 8696ab4bb3c722354c993370dee53f5319a2586b..d2fbc8ca97c2f29f46223172054773a642cdd67e 100644 (file)
@@ -3,5 +3,5 @@
 
 struct A
 {
-  template <class> int f (B);  // { dg-error "was not declared in this scope|cannot be a member template" }
+  template <class> int f (B);  // { dg-error "was not declared in this scope|cannot be a member template|has not been declared" }
 };
index c652cc86f6ef96d0fa91cc57c75dce14e4fbca27..f4cf299859cf7419fda5b63a8b1a81b2c48bdb42 100644 (file)
@@ -4,5 +4,5 @@ class A
 {
   template<class R>
   static void f(X&); // { dg-error "" }
-  inline void A::f<void>(X&); // { dg-error "f|expected" }
+  inline void A::f<void>(X&); // { dg-error "f|expected|not been declared" }
 };
index 750e3daf19e468859bd759cef3fb9d60d5ac6759..1d8fd009803a82faa93fa8008d378a30c1cda9e5 100644 (file)
@@ -2,5 +2,5 @@
 
 struct A
 {
-  template<int> void foo()(0); // { dg-error "initializer" } 
+  template<int> void foo()(0); // { dg-error "" }
 };