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> 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 C++ core issue 703
* typeck2.c (check_narrowing): Don't complain about loss of * typeck2.c (check_narrowing): Don't complain about loss of
precision when converting a floating-point constant. 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); 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 /* We cannot do any checking for a SIZE that isn't known to be
build the index type and mark that it requires structural constant. Just build the index type and mark that it requires
equality checks. */ structural equality checks. */
itype = build_index_type (build_min (MINUS_EXPR, sizetype, itype = build_index_type (build_min (MINUS_EXPR, sizetype,
size, integer_one_node)); 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); SET_TYPE_STRUCTURAL_EQUALITY (itype);
return itype; return itype;
} }

View File

@ -13267,6 +13267,13 @@ cp_parser_direct_declarator (cp_parser* parser,
&non_constant_p); &non_constant_p);
if (!non_constant_p) if (!non_constant_p)
bounds = fold_non_dependent_expr (bounds); 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 /* Normally, the array bound must be an integral constant
expression. However, as an extension, we allow VLAs expression. However, as an extension, we allow VLAs
in function scopes. */ 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); /*integral_constant_expression_p=*/false);
max = fold_decl_constant_value (max); 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 if (TREE_CODE (max) != INTEGER_CST
&& !at_function_scope_p () && !at_function_scope_p ()
&& !TREE_SIDE_EFFECTS (max)
&& !value_dependent_expression_p (max)) && !value_dependent_expression_p (max))
{ {
if (complain & tf_error) if (complain & tf_error)
@ -15972,9 +15983,9 @@ dependent_type_p_r (tree type)
&& !TREE_CONSTANT (TYPE_MAX_VALUE (type))) && !TREE_CONSTANT (TYPE_MAX_VALUE (type)))
{ {
/* If this is the TYPE_DOMAIN of an array type, consider it /* If this is the TYPE_DOMAIN of an array type, consider it
dependent. */ dependent. We already checked for value-dependence in
return (value_dependent_expression_p (TYPE_MAX_VALUE (type)) compute_array_index_type. */
|| type_dependent_expression_p (TYPE_MAX_VALUE (type))); return type_dependent_expression_p (TYPE_MAX_VALUE (type));
} }
/* -- a template-id in which either the template name is a template /* -- 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> 2009-03-20 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/initlist5.C: Add additional test. * 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>();
}