diff mbox

PR c++/51194 - ICE with invalid alias template

Message ID m37h2wnr6t.fsf@redhat.com
State New
Headers show

Commit Message

Dodji Seketeli Nov. 19, 2011, 2:05 p.m. UTC
Hello,

Here we crash while looking up an instantiation of an erroneous member
template.

In the example of the patch below, when we look at the expression in
#3, an error is (rightfully) triggered.  As a result of 'bar<foo>'
TT's argument (in #2) is foo, which takes 2 parameters.  Then the
partial instantiation of the member template 'mem' is ill-formed, as
it is equivalent to:

    template<> template<class... Args> bar<foo>::P<foo<Arg...> >

In that expression foo<Arg...> is ill-formed as the declaration of foo
in #1 doesn't for instance have a default argument for one of its
parameters and so the number of template parameters and arguments
don't match.

An error_mark_node is thus inserted in the AST for foo<Arg...> in the
expression bar<foo>::P<foo<Arg...> >, and the type of the template
bar<foo>::mem is error_mark_node.

The problem is, when we go further to lookup bar<foo>::mem<int, char>
with the type of the 'mem' template being error_mark_node, we just
crash.

Now lookup_template_class_1 returns early when the type of the
template is error_mark_node.

Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.

From: Dodji Seketeli <dodji@redhat.com>
Date: Fri, 18 Nov 2011 19:35:04 +0100
Subject: [PATCH] PR c++/51194 - ICE with invalid alias template

gcc/cp/

	PR c++/51194
	* pt.c (lookup_template_class_1): Go out early if the type of the
	template is error_mark_node.

gcc/testsuite/

	* g++.dg/cpp0x/alias-decl-15.C: New test.
---
 gcc/cp/pt.c                                |    6 ++++++
 gcc/testsuite/g++.dg/cpp0x/alias-decl-15.C |   17 +++++++++++++++++
 2 files changed, 23 insertions(+), 0 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-15.C

Comments

Jason Merrill Nov. 19, 2011, 7:11 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 78e263f..049e3b2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7270,6 +7270,12 @@  lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
       int is_dependent_type;
       int use_partial_inst_tmpl = false;
 
+      if (template_type == error_mark_node)
+	/* An error occured while building the template TEMPL, and a
+	   diagnostic has most certainly been emitted for that
+	   already.  Let's propagate that error.  */
+	return error_mark_node;
+
       gen_tmpl = most_general_template (templ);
       parmlist = DECL_TEMPLATE_PARMS (gen_tmpl);
       parm_depth = TMPL_PARMS_DEPTH (parmlist);
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-15.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-15.C
new file mode 100644
index 0000000..2bc9b11
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-15.C
@@ -0,0 +1,17 @@ 
+// Origin PR c++/51194
+// { dg-options "-std=c++0x" }
+
+template<class U, class V> //#1
+struct foo {}; // { dg-error "provided for|foo" }
+
+template<class U, class V=char>
+struct P {};
+
+template<template<class... U> class... TT>
+struct bar {
+    template<class... Args>
+    using mem = P<TT<Args...>...>;//#2 { dg-error "wrong number of|arguments" }
+};
+
+bar<foo>::mem<int, char> b;//#3 { dg-error "invalid type" }
+