This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix 3 ICEs on invalid with variadic templates (PR c++/33496)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>, Mark Mitchell <mark at codesourcery dot com>, Doug Gregor <doug dot gregor at gmail dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 20 Sep 2007 08:20:27 -0400
- Subject: [C++ PATCH] Fix 3 ICEs on invalid with variadic templates (PR c++/33496)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following patch cures 3 different places where we can
die with tree checking ICE. tsubst_pack_expansion can return
error_mark_node for multiple reasons, so assuming it returned
TREE_VEC is a wrong assumption.
Tested on x86_64-linux, ok for trunk?
Other calls to tsubst_pack_expansion which don't handle
error_mark_node still IMHO need investigation:
1) tsubst_exception_specification
template<int M, int N> struct pair
{
int i, j;
pair() : i(M), j(N) {}
};
template<int... M> struct S
{
template<int... N> static int foo() throw (pair <M, N>...)
{
return 1;
}
};
int bar ()
{
return S<0, 1, 2>::foo<0, 1> ();
}
ICEs, but I'm not 100% sure what to do there, tsubst_pack_expansion
doesn't return there a TREE_VEC, but TYPE_PACK_EXPANSION (guess I'll
file a new PR to track this)
2) regenerate_decl_from_template
Not sure how to create a testcase for it.
3) tsubst_initializer_list
Second call to tsubst_pack_expansion. No testcase either.
Additionally, how should [] arrays be sized in presence of
packs? Following compiles only without -DSIZE_FROM_CTOR
template<int M, int N> struct pair
{
int i, j;
pair () : i (M), j (N) {}
};
template<int... M> struct S
{
template<int... N> static int *foo ()
{
#ifdef SIZE_FROM_CTOR
static int x[] = { (M + N)..., -1 };
#else
static int x[1 + sizeof... N] = { (M + N)..., -1 };
#endif
return x;
}
};
int *bar ()
{
return S<0, 1, 2>::foo<0, 1, 2> ();
}
Should I file a PR? Is the upcoming C++ standard going to have
something similar as ISO C99 designated initializers? If yes, how
would that play together with variadic templates?
2007-09-20 Jakub Jelinek <jakub@redhat.com>
PR c++/33496
* pt.c (tsubst_copy) <case SIZEOF_EXPR>: Handle error_mark_node
returned from tsubst_pack_expansion.
(tsubst_copy_and_build) <case SIZEOF_EXPR>: Likewise.
(tsubst_copy_and_build) <case CONSTRUCTOR>: Likewise.
* g++.dg/cpp0x/variadic76.C: New test.
* g++.dg/cpp0x/variadic77.C: New test.
* g++.dg/cpp0x/variadic78.C: New test.
--- gcc/cp/pt.c.jj 2007-09-19 12:23:29.000000000 +0200
+++ gcc/cp/pt.c 2007-09-20 13:37:32.000000000 +0200
@@ -9586,6 +9586,8 @@ tsubst_copy (tree t, tree args, tsubst_f
/* We only want to compute the number of arguments. */
tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args,
complain, in_decl);
+ if (expanded == error_mark_node)
+ return error_mark_node;
return build_int_cst (size_type_node, TREE_VEC_LENGTH (expanded));
}
/* Fall through */
@@ -10586,6 +10588,8 @@ tsubst_copy_and_build (tree t,
/* We only want to compute the number of arguments. */
tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args,
complain, in_decl);
+ if (expanded == error_mark_node)
+ return error_mark_node;
return build_int_cst (size_type_node, TREE_VEC_LENGTH (expanded));
}
/* Fall through */
@@ -10978,7 +10982,9 @@ tsubst_copy_and_build (tree t,
ce->value = tsubst_pack_expansion (ce->value, args, complain,
in_decl);
- if (TREE_VEC_LENGTH (ce->value) == 1)
+ if (ce->value == error_mark_node)
+ ;
+ else if (TREE_VEC_LENGTH (ce->value) == 1)
/* Just move the argument into place. */
ce->value = TREE_VEC_ELT (ce->value, 0);
else
--- gcc/testsuite/g++.dg/cpp0x/variadic76.C.jj 2007-09-20 13:48:44.000000000 +0200
+++ gcc/testsuite/g++.dg/cpp0x/variadic76.C 2007-09-20 13:44:17.000000000 +0200
@@ -0,0 +1,13 @@
+// PR c++/33496
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+template<int... N> int foo ()
+{
+ return sizeof... N (); // { dg-error "cannot be used as a function" }
+}
+
+int bar ()
+{
+ return foo<0> ();
+}
--- gcc/testsuite/g++.dg/cpp0x/variadic77.C.jj 2007-09-20 13:48:49.000000000 +0200
+++ gcc/testsuite/g++.dg/cpp0x/variadic77.C 2007-09-20 13:44:32.000000000 +0200
@@ -0,0 +1,22 @@
+// PR c++/33496
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+template<int M, int N> struct pair
+{
+ int i, j;
+ pair () : i (M), j (N) {}
+};
+
+template<int... M> struct S
+{
+ template<int... N> static int foo ()
+ {
+ return sizeof... (pair<M, N>); // { dg-error "mismatched argument pack lengths" }
+ }
+};
+
+int bar ()
+{
+ return S<0, 1, 2>::foo<0, 1> ();
+}
--- gcc/testsuite/g++.dg/cpp0x/variadic78.C.jj 2007-09-20 13:48:53.000000000 +0200
+++ gcc/testsuite/g++.dg/cpp0x/variadic78.C 2007-09-20 13:44:48.000000000 +0200
@@ -0,0 +1,23 @@
+// PR c++/33496
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+template<int M, int N> struct pair
+{
+ int i, j;
+ pair () : i (M), j (N) {}
+};
+
+template<int... M> struct S
+{
+ template<int... N> static int *foo ()
+ {
+ static int x[] = { (M + N)... }; // { dg-error "mismatched argument pack lengths" }
+ return x;
+ }
+};
+
+int *bar ()
+{
+ return S<0, 1, 2>::foo<0, 1> ();
+}
Jakub