diff options
author | Jason Merrill <jason@redhat.com> | 2009-03-21 16:15:41 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-03-21 16:15:41 -0400 |
commit | c11655358bd4a0f3dba75e77dc531a9399f37684 (patch) | |
tree | 632fbc5aeb17457459bfa8833e865a8f2f37a7fd /gcc | |
parent | b39f88bd05693c200851c934fca5ee8d0121173e (diff) | |
download | gcc-c11655358bd4a0f3dba75e77dc531a9399f37684.zip gcc-c11655358bd4a0f3dba75e77dc531a9399f37684.tar.gz gcc-c11655358bd4a0f3dba75e77dc531a9399f37684.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/decl.c | 19 | ||||
-rw-r--r-- | gcc/cp/parser.c | 7 | ||||
-rw-r--r-- | gcc/cp/pt.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/vla6.C | 18 |
6 files changed, 66 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a4eb86a..e695ede 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9a6ab02..a96e606 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 cannot do any checking for a value-dependent SIZE. Just - build the index type and mark that it requires structural - equality checks. */ + /* 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 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 60787b0..d3343aa 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 62a7b88..1c408237 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 16d50f4..6d651dd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/g++.dg/ext/vla6.C b/gcc/testsuite/g++.dg/ext/vla6.C new file mode 100644 index 0000000..83011f2 --- /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<int> void foo() +{ + int x[A().i]; +} + +void f() +{ + foo<1>(); +} |