This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix ICE in tsubst with VLA in template (PR c++/40013)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 4 May 2009 13:24:58 +0200
- Subject: [C++ PATCH] Fix ICE in tsubst with VLA in template (PR c++/40013)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
Since PR28879 the parser adds a magic NOP_EXPR with side-effects flag set on
non-constant array bounds to avoid calling value_dependent_expr_p on it.
Unfortunately the bounds at that point could very well have NULL type
(build_nt_call* etc.).
The following patch fixes it up during tsubst (tsubst already has code
to recognize these magic NOP_EXPRs just a few lines below it, though just
during processing of template decls), ok for 4.4/trunk if bootstrap/regtest
passes?
2009-05-04 Jakub Jelinek <jakub@redhat.com>
PR c++/40013
* pt.c (tsubst): If magic NOP_EXPR with side-effects has no type,
set it from its operand's type after tsubst_expr.
* g++.dg/ext/vla7.C: New test.
--- gcc/cp/pt.c.jj 2009-05-04 12:54:19.000000000 +0200
+++ gcc/cp/pt.c 2009-05-04 13:10:16.000000000 +0200
@@ -9182,6 +9182,14 @@ tsubst (tree t, tree args, tsubst_flags_
max = tsubst_expr (omax, args, complain, in_decl,
/*integral_constant_expression_p=*/false);
+
+ /* Fix up type of the magic NOP_EXPR with TREE_SIDE_EFFECTS if
+ needed. */
+ if (TREE_CODE (max) == NOP_EXPR
+ && TREE_SIDE_EFFECTS (max)
+ && !TREE_TYPE (max))
+ TREE_TYPE (max) = TREE_TYPE (TREE_OPERAND (max, 0));
+
max = fold_decl_constant_value (max);
/* If we're in a partial instantiation, preserve the magic NOP_EXPR
--- gcc/testsuite/g++.dg/ext/vla7.C.jj 2009-05-04 12:56:31.000000000 +0200
+++ gcc/testsuite/g++.dg/ext/vla7.C 2009-05-04 12:56:26.000000000 +0200
@@ -0,0 +1,30 @@
+// PR c++/40013
+// { dg-options "" }
+
+template <class T>
+struct A
+{
+ struct B
+ {
+ struct
+ {
+ int fn () { return 0; }
+ } b;
+ };
+ void test ();
+};
+
+template <class T>
+void
+A <T>::test ()
+{
+ B a;
+ int vla[a.b.fn ()];
+}
+
+int
+main ()
+{
+ A <char> a;
+ a.test ();
+}
Jakub