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
This commit is contained in:
parent
d0304854de
commit
6ee3ffe85e
5 changed files with 98 additions and 12 deletions
|
@ -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
|
||||
|
|
59
gcc/cp/pt.c
59
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;
|
||||
|
|
|
@ -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.
|
||||
|
|
24
gcc/testsuite/g++.dg/ext/vla3.C
Normal file
24
gcc/testsuite/g++.dg/ext/vla3.C
Normal file
|
@ -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;
|
||||
}
|
||||
|
9
gcc/testsuite/g++.dg/template/array16.C
Normal file
9
gcc/testsuite/g++.dg/template/array16.C
Normal file
|
@ -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;
|
Loading…
Add table
Reference in a new issue