aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-03-21 16:15:41 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-03-21 16:15:41 -0400
commitc11655358bd4a0f3dba75e77dc531a9399f37684 (patch)
tree632fbc5aeb17457459bfa8833e865a8f2f37a7fd /gcc
parentb39f88bd05693c200851c934fca5ee8d0121173e (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/cp/decl.c19
-rw-r--r--gcc/cp/parser.c7
-rw-r--r--gcc/cp/pt.c17
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/vla6.C18
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>();
+}