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:
parent
b39f88bd05
commit
c11655358b
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
17
gcc/cp/pt.c
17
gcc/cp/pt.c
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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>();
|
||||||
|
}
|
Loading…
Reference in New Issue