PR c++/28879
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Mar 2009 20:15:41 +0000 (20:15 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Mar 2009 20:15:41 +0000 (20:15 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@144988 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/vla6.C [new file with mode: 0644]

index a4eb86a..e695ede 100644 (file)
@@ -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.
index 9a6ab02..a96e606 100644 (file)
@@ -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;
     }
index 60787b0..d3343aa 100644 (file)
@@ -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.  */
index 62a7b88..1c40823 100644 (file)
@@ -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
index 16d50f4..6d651dd 100644 (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>
 
        * 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 (file)
index 0000000..83011f2
--- /dev/null
@@ -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>();
+}