]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/58170 ([c++11] Crash when aliasing a template class that is a member of...
authorJason Merrill <jason@redhat.com>
Sat, 22 Feb 2014 05:50:12 +0000 (00:50 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 22 Feb 2014 05:50:12 +0000 (00:50 -0500)
PR c++/58170
* parser.c (cp_parser_type_name): Always check dependency.
(cp_parser_type_specifier_seq): Call
cp_parser_parse_and_diagnose_invalid_type_name.

From-SVN: r208040

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/g++.dg/cpp0x/alias-decl-40.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/error8.C
gcc/testsuite/g++.dg/cpp0x/override4.C
gcc/testsuite/g++.dg/ext/underlying_type1.C
gcc/testsuite/g++.dg/parse/crash48.C
gcc/testsuite/g++.dg/parse/error49.C

index 53f6c2101e06ff541226d9f42368d3fab39436f2..1b204dcf4be8f9aa24e0a8460da03b19c000b7f0 100644 (file)
@@ -1,5 +1,10 @@
 2014-02-21  Jason Merrill  <jason@redhat.com>
 
+       PR c++/58170
+       * parser.c (cp_parser_type_name): Always check dependency.
+       (cp_parser_type_specifier_seq): Call
+       cp_parser_parse_and_diagnose_invalid_type_name.
+
        PR c++/60108
        * semantics.c (expand_or_defer_fn_1): Check DECL_DEFAULTED_FN.
 
index 47a67c4932021cdfbf9b3cdacc356d235b58b9f4..1e9803263067e1950de88e2ea975182a68dab8a7 100644 (file)
@@ -14763,7 +14763,7 @@ cp_parser_type_name (cp_parser* parser)
         instantiation of an alias template...  */
       type_decl = cp_parser_template_id (parser,
                                         /*template_keyword_p=*/false,
-                                        /*check_dependency_p=*/false,
+                                        /*check_dependency_p=*/true,
                                         none_type,
                                         /*is_declaration=*/false);
       /* Note that this must be an instantiation of an alias template
@@ -18083,7 +18083,16 @@ cp_parser_type_specifier_seq (cp_parser* parser,
             type-specifier-seq at all.  */
          if (!seen_type_specifier)
            {
-             cp_parser_error (parser, "expected type-specifier");
+             /* Set in_declarator_p to avoid skipping to the semicolon.  */
+             int in_decl = parser->in_declarator_p;
+             parser->in_declarator_p = true;
+
+             if (cp_parser_uncommitted_to_tentative_parse_p (parser)
+                 || !cp_parser_parse_and_diagnose_invalid_type_name (parser))
+               cp_parser_error (parser, "expected type-specifier");
+
+             parser->in_declarator_p = in_decl;
+
              type_specifier_seq->type = error_mark_node;
              return;
            }
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-40.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-40.C
new file mode 100644 (file)
index 0000000..f8bff78
--- /dev/null
@@ -0,0 +1,33 @@
+// PR c++/58170
+// { dg-require-effective-target c++11 }
+// { dg-prune-output "not declared" }
+// { dg-prune-output "expected" }
+
+template <typename T, typename U>
+struct base {
+  template <typename V>
+  struct derived;
+};
+
+template <typename T, typename U>
+template <typename V>
+struct base<T, U>::derived : public base<T, V> {
+};
+
+// This (wrong?) alias declaration provokes the crash.
+template <typename T, typename U, typename V>
+using alias = base<T, U>::derived<V>; // { dg-error "template|typename" }
+
+// This one works:
+// template <typename T, typename U, typename V>
+// using alias = typename base<T, U>::template derived<V>;
+
+template <typename T>
+void f() {
+  alias<T, bool, char> m{};
+  (void) m;
+}
+
+int main() {
+  f<int>();
+}
index cc4f87791a956f6350ea3dfa36d5ccdda90e42f1..a99207792ae073001b98f4ef0e45ad52c5f31c54 100644 (file)
@@ -3,5 +3,5 @@
 
 struct A
 {
-  int* p = new foo; // { dg-error "16:expected type-specifier" }
+  int* p = new foo; // { dg-error "16:foo. does not name a type" }
 };
index aec5c2cdf359dfb61309abc7b54aa82f34a5bf9a..695f9a3810965c1e0ce506ab5d732bfd128d0975 100644 (file)
@@ -16,12 +16,12 @@ struct B2
 
 struct B3
 {
-  virtual auto f() -> final void; // { dg-error "expected type-specifier" }
+  virtual auto f() -> final void; // { dg-error "type" }
 };
 
 struct B4
 {
-  virtual auto f() -> final void {} // { dg-error "expected type-specifier" }
+  virtual auto f() -> final void {} // { dg-error "type" }
 };
 
 struct D : B
@@ -36,10 +36,10 @@ struct D2 : B
 
 struct D3 : B
 {
-  virtual auto g() -> override void; // { dg-error "expected type-specifier" }
+  virtual auto g() -> override void; // { dg-error "type" }
 };
 
 struct D4 : B
 {
-  virtual auto g() -> override void {} // { dg-error "expected type-specifier" }
+  virtual auto g() -> override void {} // { dg-error "type" }
 };
index a8f68d3d60a8d3df0f7f15fbc2475bebd8fd4897..999cd9f35bd97df18fd6b311905a38561c859b95 100644 (file)
@@ -8,7 +8,7 @@ template<typename T>
   { typedef __underlying_type(T) type; }; // { dg-error "not an enumeration" }
 
 __underlying_type(int) i1; // { dg-error "not an enumeration|invalid" }
-__underlying_type(A)   i2; // { dg-error "expected" }
+__underlying_type(A)   i2; // { dg-error "expected|type" }
 __underlying_type(B)   i3; // { dg-error "not an enumeration|invalid" }
 __underlying_type(U)   i4; // { dg-error "not an enumeration|invalid" }
 
index 45415484b4ad2acb21a29e6488198281a33382df..020ddf079acb33f947e15253d4a32f00a0590553 100644 (file)
@@ -5,5 +5,5 @@ void
 foo (bool b)
 {
   if (b)
-    try { throw 0; } catch (X) { }     // { dg-error "expected type-specifier before" }
+    try { throw 0; } catch (X) { }     // { dg-error "type" }
 }
index d5ec0c87ef67e98e4efa58c4fd70f16eced4ca8e..9d392afa84f13592a8b5eaf315d6fe2cf76af643 100644 (file)
@@ -2,5 +2,5 @@
 
 int main()
 {
-  int* p = new foo; // { dg-error "16:expected type-specifier" }
+  int* p = new foo; // { dg-error "16:type" }
 }