diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a4eb86a8b6b..e695ede3f2d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2009-03-20 Jason Merrill + 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. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9a6ab02e36e..a96e606ad4f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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; } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 60787b026f0..d3343aa6097 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 62a7b882015..1c408237c6f 100644 --- a/gcc/cp/pt.c +++ b/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); 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 16d50f4cee0..6d651dde37e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-03-21 Jason Merrill + + PR c++/28879 + * g++.dg/ext/vla6.C: New test. + 2009-03-20 Jason Merrill * g++.dg/cpp0x/initlist5.C: Add additional test. diff --git a/gcc/testsuite/g++.dg/ext/vla6.C b/gcc/testsuite/g++.dg/ext/vla6.C new file mode 100644 index 00000000000..83011f2f0ab --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla6.C @@ -0,0 +1,18 @@ +// PR c++/28879 +// { dg-options "" } + +struct A +{ + int i; + A(): i(1) {} +}; + +template void foo() +{ + int x[A().i]; +} + +void f() +{ + foo<1>(); +}