diff options
author | Mark Mitchell <mark@codesourcery.com> | 2006-09-07 01:04:07 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2006-09-07 01:04:07 +0000 |
commit | 6ee3ffe85ea599b1d977615ee31b8421563312c0 (patch) | |
tree | ad868713c74b728318412e4f976f6e9e9eced7ed /gcc | |
parent | d0304854de398cc3979df4976047c2dcd5de0723 (diff) | |
download | gcc-6ee3ffe85ea599b1d977615ee31b8421563312c0.zip gcc-6ee3ffe85ea599b1d977615ee31b8421563312c0.tar.gz gcc-6ee3ffe85ea599b1d977615ee31b8421563312c0.tar.bz2 |
re PR c++/28903 (Rejects VLA in template class's member with using)
PR c++/28903
* pt.c (tsubst): Use fold_non_dependent_expr to fold array
dimensions.
PR c++/28886
* pt.c (unify): Avoid unnecessary calls to fold_build2 for array
dimensions.
From-SVN: r116736
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/pt.c | 59 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/vla3.C | 24 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/array16.C | 9 |
5 files changed, 98 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cd1af6f..60d2fb2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2006-09-06 Mark Mitchell <mark@codesourcery.com> + + PR c++/28903 + * pt.c (tsubst): Use fold_non_dependent_expr to fold array + dimensions. + + PR c++/28886 + * pt.c (unify): Avoid unnecessary calls to fold_build2 for array + dimensions. + 2006-09-06 Jason Merrill <jason@redhat.com> PR c++/26696 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d278b00..715b946 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7216,9 +7216,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0); - /* The array dimension behaves like a non-type template arg, - in that we want to fold it as much as possible. */ - max = tsubst_template_arg (omax, args, complain, in_decl); + max = tsubst_expr (omax, args, complain, in_decl, + /*integral_constant_expression_p=*/false); + max = fold_non_dependent_expr (max); max = fold_decl_constant_value (max); if (TREE_CODE (max) != INTEGER_CST @@ -10618,21 +10618,56 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) { tree parm_max; tree arg_max; - - parm_max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm)); - arg_max = TYPE_MAX_VALUE (TYPE_DOMAIN (arg)); + bool parm_cst; + bool arg_cst; /* Our representation of array types uses "N - 1" as the TYPE_MAX_VALUE for an array with "N" elements, if "N" is - not an integer constant. */ - if (TREE_CODE (parm_max) == MINUS_EXPR) + not an integer constant. We cannot unify arbitrarily + complex expressions, so we eliminate the MINUS_EXPRs + here. */ + parm_max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm)); + parm_cst = TREE_CODE (parm_max) == INTEGER_CST; + if (!parm_cst) { - arg_max = fold_build2 (PLUS_EXPR, - integer_type_node, - arg_max, - TREE_OPERAND (parm_max, 1)); + gcc_assert (TREE_CODE (parm_max) == MINUS_EXPR); parm_max = TREE_OPERAND (parm_max, 0); } + arg_max = TYPE_MAX_VALUE (TYPE_DOMAIN (arg)); + arg_cst = TREE_CODE (arg_max) == INTEGER_CST; + if (!arg_cst) + { + /* The ARG_MAX may not be a simple MINUS_EXPR, if we are + trying to unify the type of a variable with the type + of a template parameter. For example: + + template <unsigned int N> + void f (char (&) [N]); + int g(); + void h(int i) { + char a[g(i)]; + f(a); + } + + Here, the type of the ARG will be "int [g(i)]", and + may be a SAVE_EXPR, etc. */ + if (TREE_CODE (arg_max) != MINUS_EXPR) + return 1; + arg_max = TREE_OPERAND (arg_max, 0); + } + + /* If only one of the bounds used a MINUS_EXPR, compensate + by adding one to the other bound. */ + if (parm_cst && !arg_cst) + parm_max = fold_build2 (PLUS_EXPR, + integer_type_node, + parm_max, + integer_one_node); + else if (arg_cst && !parm_cst) + arg_max = fold_build2 (PLUS_EXPR, + integer_type_node, + arg_max, + integer_one_node); if (unify (tparms, targs, parm_max, arg_max, UNIFY_ALLOW_INTEGER)) return 1; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c15dda4..6e7bd99 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2006-09-06 Mark Mitchell <mark@codesourcery.com> + + PR c++/28903 + * g++.dg/ext/vla3.C: New test. + + PR c++/28886 + * g++.dg/template/array16.C: New test. + 2006-09-06 Richard Guenther <rguenther@suse.de> * gcc.dg/pr27226.c: Remove testcase again. diff --git a/gcc/testsuite/g++.dg/ext/vla3.C b/gcc/testsuite/g++.dg/ext/vla3.C new file mode 100644 index 0000000..329cc7d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla3.C @@ -0,0 +1,24 @@ +// PR c++/28903 +// { dg-options "" } + +template <class> +struct View +{ + int n; +}; +template <class ViewA> +struct ViewDom : View<ViewA> +{ + using View<ViewA>::n; + ViewDom(); +}; +template <class ViewA> +ViewDom<ViewA>::ViewDom() +{ + char a[n]; +} +void element( ) +{ + ViewDom<int> a; +} + diff --git a/gcc/testsuite/g++.dg/template/array16.C b/gcc/testsuite/g++.dg/template/array16.C new file mode 100644 index 0000000..c514410 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array16.C @@ -0,0 +1,9 @@ +// PR c++/28886 + +template<typename> struct A; + +template<typename T, int N> struct A<T[N]> {}; + +template<typename T, int N> struct A<const T[N]> {}; + +A<const int[1]> a; |