re PR c++/28879 (ICE with VLA in template function)

PR c++/28879
        * parser.c (cp_parser_direct_declarator): In a template, wrap
        non-constant expression in NOP_EXPR with TREE_SIDE_EFFECTS set.
        * pt.c (tsubst): Preserve it in a partial instantiation.
        (dependent_type_p_r): Don't check value_dependent_expression_p.
        * decl.c (compute_array_index_type): Don't check
        value_dependent_expression_p if TREE_SIDE_EFFECTS.

From-SVN: r144988
This commit is contained in:
Jason Merrill 2009-03-21 16:15:41 -04:00 committed by Jason Merrill
parent b39f88bd05
commit c11655358b
6 changed files with 65 additions and 7 deletions

View File

@ -1,5 +1,13 @@
2009-03-20 Jason Merrill <jason@redhat.com>
PR c++/28879
* parser.c (cp_parser_direct_declarator): In a template, wrap
non-constant expression in NOP_EXPR with TREE_SIDE_EFFECTS set.
* pt.c (tsubst): Preserve it in a partial instantiation.
(dependent_type_p_r): Don't check value_dependent_expression_p.
* decl.c (compute_array_index_type): Don't check
value_dependent_expression_p if TREE_SIDE_EFFECTS.
C++ core issue 703
* typeck2.c (check_narrowing): Don't complain about loss of
precision when converting a floating-point constant.

View File

@ -7179,13 +7179,22 @@ compute_array_index_type (tree name, tree size)
type = TREE_TYPE (size);
}
if (value_dependent_expression_p (size))
/* We can only call value_dependent_expression_p on integral constant
expressions; the parser adds a dummy NOP_EXPR with TREE_SIDE_EFFECTS
set if this isn't one. */
if (processing_template_decl
&& (TREE_SIDE_EFFECTS (size) || value_dependent_expression_p (size)))
{
/* We cannot do any checking for a value-dependent SIZE. Just
build the index type and mark that it requires structural
equality checks. */
/* We cannot do any checking for a SIZE that isn't known to be
constant. Just build the index type and mark that it requires
structural equality checks. */
itype = build_index_type (build_min (MINUS_EXPR, sizetype,
size, integer_one_node));
if (!TREE_SIDE_EFFECTS (size))
{
TYPE_DEPENDENT_P (itype) = 1;
TYPE_DEPENDENT_P_VALID (itype) = 1;
}
SET_TYPE_STRUCTURAL_EQUALITY (itype);
return itype;
}

View File

@ -13267,6 +13267,13 @@ cp_parser_direct_declarator (cp_parser* parser,
&non_constant_p);
if (!non_constant_p)
bounds = fold_non_dependent_expr (bounds);
else if (processing_template_decl)
{
/* Remember this wasn't a constant-expression. */
bounds = build_nop (TREE_TYPE (bounds), bounds);
TREE_SIDE_EFFECTS (bounds) = 1;
}
/* Normally, the array bound must be an integral constant
expression. However, as an extension, we allow VLAs
in function scopes. */

View File

@ -9084,8 +9084,19 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
/*integral_constant_expression_p=*/false);
max = fold_decl_constant_value (max);
/* If we're in a partial instantiation, preserve the magic NOP_EXPR
with TREE_SIDE_EFFECTS that indicates this is not an integral
constant expression. */
if (processing_template_decl
&& TREE_SIDE_EFFECTS (omax) && TREE_CODE (omax) == NOP_EXPR)
{
gcc_assert (TREE_CODE (max) == NOP_EXPR);
TREE_SIDE_EFFECTS (max) = 1;
}
if (TREE_CODE (max) != INTEGER_CST
&& !at_function_scope_p ()
&& !TREE_SIDE_EFFECTS (max)
&& !value_dependent_expression_p (max))
{
if (complain & tf_error)
@ -15972,9 +15983,9 @@ dependent_type_p_r (tree type)
&& !TREE_CONSTANT (TYPE_MAX_VALUE (type)))
{
/* If this is the TYPE_DOMAIN of an array type, consider it
dependent. */
return (value_dependent_expression_p (TYPE_MAX_VALUE (type))
|| type_dependent_expression_p (TYPE_MAX_VALUE (type)));
dependent. We already checked for value-dependence in
compute_array_index_type. */
return type_dependent_expression_p (TYPE_MAX_VALUE (type));
}
/* -- a template-id in which either the template name is a template

View File

@ -1,3 +1,8 @@
2009-03-21 Jason Merrill <jason@redhat.com>
PR c++/28879
* g++.dg/ext/vla6.C: New test.
2009-03-20 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/initlist5.C: Add additional test.

View File

@ -0,0 +1,18 @@
// PR c++/28879
// { dg-options "" }
struct A
{
int i;
A(): i(1) {}
};
template<int> void foo()
{
int x[A().i];
}
void f()
{
foo<1>();
}