public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH for c++/58170 (ICE with alias template)
@ 2014-02-22  5:48 Jason Merrill
  2014-03-03  9:38 ` Jakub Jelinek
  0 siblings, 1 reply; 2+ messages in thread
From: Jason Merrill @ 2014-02-22  5:48 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 343 bytes --]

There's no reason why we wouldn't check for dependent scopes when 
parsing the target of an alias declaration, and indeed not doing so led 
to the ICE here.

The rest of the patch improves the diagnostic for this testcase (and 
some others).

Tested x86_64-pc-linux-gnu, applying to trunk.  Also applying the 
cp_parser_type_name hunk to 4.8.

[-- Attachment #2: 58170.patch --]
[-- Type: text/x-patch, Size: 5251 bytes --]

commit 21f4a8a5550498513e1235239b69aa5bc537687b
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Feb 21 16:58:21 2014 -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.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 47a67c4..1e98032 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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
index 0000000..f8bff78
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-40.C
@@ -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>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/error8.C b/gcc/testsuite/g++.dg/cpp0x/error8.C
index cc4f877..a992077 100644
--- a/gcc/testsuite/g++.dg/cpp0x/error8.C
+++ b/gcc/testsuite/g++.dg/cpp0x/error8.C
@@ -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" }
 };
diff --git a/gcc/testsuite/g++.dg/cpp0x/override4.C b/gcc/testsuite/g++.dg/cpp0x/override4.C
index aec5c2c..695f9a3 100644
--- a/gcc/testsuite/g++.dg/cpp0x/override4.C
+++ b/gcc/testsuite/g++.dg/cpp0x/override4.C
@@ -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" }
 };
diff --git a/gcc/testsuite/g++.dg/ext/underlying_type1.C b/gcc/testsuite/g++.dg/ext/underlying_type1.C
index a8f68d3..999cd9f 100644
--- a/gcc/testsuite/g++.dg/ext/underlying_type1.C
+++ b/gcc/testsuite/g++.dg/ext/underlying_type1.C
@@ -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" }
 
diff --git a/gcc/testsuite/g++.dg/parse/crash48.C b/gcc/testsuite/g++.dg/parse/crash48.C
index 4541548..020ddf0 100644
--- a/gcc/testsuite/g++.dg/parse/crash48.C
+++ b/gcc/testsuite/g++.dg/parse/crash48.C
@@ -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" }
 }
diff --git a/gcc/testsuite/g++.dg/parse/error49.C b/gcc/testsuite/g++.dg/parse/error49.C
index d5ec0c8..9d392af 100644
--- a/gcc/testsuite/g++.dg/parse/error49.C
+++ b/gcc/testsuite/g++.dg/parse/error49.C
@@ -2,5 +2,5 @@
 
 int main()
 {
-  int* p = new foo; // { dg-error "16:expected type-specifier" }
+  int* p = new foo; // { dg-error "16:type" }
 }

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: C++ PATCH for c++/58170 (ICE with alias template)
  2014-02-22  5:48 C++ PATCH for c++/58170 (ICE with alias template) Jason Merrill
@ 2014-03-03  9:38 ` Jakub Jelinek
  0 siblings, 0 replies; 2+ messages in thread
From: Jakub Jelinek @ 2014-03-03  9:38 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

On Sat, Feb 22, 2014 at 12:48:40AM -0500, Jason Merrill wrote:
> There's no reason why we wouldn't check for dependent scopes when
> parsing the target of an alias declaration, and indeed not doing so
> led to the ICE here.
> 
> The rest of the patch improves the diagnostic for this testcase (and
> some others).
> 
> Tested x86_64-pc-linux-gnu, applying to trunk.  Also applying the
> cp_parser_type_name hunk to 4.8.

This broke the obj-c++.dg/invalid-method-2.mm testcase, fixed thusly,
applied as obvious to the trunk:

2014-03-03  Jakub Jelinek  <jakub@redhat.com>

	PR objc++/60398
	* obj-c++.dg/invalid-method-2.mm: Adjust dg-error regexps.

--- gcc/testsuite/obj-c++.dg/invalid-method-2.mm.jj	2012-11-15 18:21:44.000000000 +0100
+++ gcc/testsuite/obj-c++.dg/invalid-method-2.mm	2014-03-03 10:26:50.333818063 +0100
@@ -7,11 +7,11 @@
 @end
 
 @implementation MyClass
-- (x) method /* { dg-error "expected" } */
+- (x) method /* { dg-error "expected|type" } */
 {
   return 0;
 }
-- (id) method2: (x)argument /* { dg-error "expected" } */
+- (id) method2: (x)argument /* { dg-error "expected|type" } */
 {
   return 0;
 }


	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-03-03  9:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-22  5:48 C++ PATCH for c++/58170 (ICE with alias template) Jason Merrill
2014-03-03  9:38 ` Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).