re PR c++/48446 (internal compiler error: in gimplify_var_or_parm_decl, at gimplify...
authorJason Merrill <jason@redhat.com>
Thu, 14 Apr 2011 14:59:58 +0000 (10:59 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 14 Apr 2011 14:59:58 +0000 (10:59 -0400)
PR c++/48446
* decl.c (compute_array_index_type): Use get_temp_regvar instead
of variable_size.
* init.c (get_temp_regvar): No longer static.
* cp-tree.h: Declare it.

From-SVN: r172432

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/vla10.C [new file with mode: 0644]

index 37b107191d5fc8223738e1a72433ef6e35912a1e..0833125b4700b769952d243eeea47d71c542207a 100644 (file)
@@ -1,3 +1,11 @@
+2011-04-14  Jason Merrill  <jason@redhat.com>
+
+       PR c++/48446
+       * decl.c (compute_array_index_type): Use get_temp_regvar instead
+       of variable_size.
+       * init.c (get_temp_regvar): No longer static.
+       * cp-tree.h: Declare it.
+
 2011-04-14  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * parser.c (cp_parser_objc_class_declaration): Updated for change
index 15c197452339de6e94f6adb50d4e4605d00205bf..3ca44c2681ece8a8bfff1aa2261a0c48959cd9de 100644 (file)
@@ -4964,6 +4964,7 @@ extern tree build_offset_ref                      (tree, tree, bool);
 extern tree build_new                          (VEC(tree,gc) **, tree, tree,
                                                 VEC(tree,gc) **, int,
                                                  tsubst_flags_t);
+extern tree get_temp_regvar                    (tree, tree);
 extern tree build_vec_init                     (tree, tree, tree, bool, int,
                                                  tsubst_flags_t);
 extern tree build_delete                       (tree, tree,
index 75538866a71de4bd44deb5482f0d2de6973b38d0..794832b2e0a766e8c82d72e8e1285ffc3d3b3f90 100644 (file)
@@ -7710,8 +7710,16 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
       processing_template_decl = saved_processing_template_decl;
 
       if (!TREE_CONSTANT (itype))
-       /* A variable sized array.  */
-       itype = variable_size (itype);
+       {
+         /* A variable sized array.  */
+         if (TREE_SIDE_EFFECTS (itype))
+           /* Use get_temp_regvar rather than variable_size here so that
+              people walking expressions that use a variable of this type
+              don't walk into this expression.  */
+           itype = get_temp_regvar (TREE_TYPE (itype), itype);
+         else
+           itype = variable_size (itype);
+       }
       /* Make sure that there was no overflow when creating to a signed
         index type.  (For example, on a 32-bit machine, an array with
         size 2^32 - 1 is too big.)  */
index 313169072b4ab969322163330a683cffc4228927..32afa03f53885a6adb3720fe4a0d9b161ecd6b70 100644 (file)
@@ -45,7 +45,6 @@ static void expand_virtual_init (tree, tree);
 static tree sort_mem_initializers (tree, tree);
 static tree initializing_context (tree);
 static void expand_cleanup_for_base (tree, tree);
-static tree get_temp_regvar (tree, tree);
 static tree dfs_initialize_vtbl_ptrs (tree, void *);
 static tree build_dtor_call (tree, special_function_kind, int);
 static tree build_field_list (tree, tree, int *);
@@ -2875,7 +2874,7 @@ create_temporary_var (tree type)
    things when it comes time to do final cleanups (which take place
    "outside" the binding contour of the function).  */
 
-static tree
+tree
 get_temp_regvar (tree type, tree init)
 {
   tree decl;
index ffca004140f85b0c25bbe6223677c74d4eb30291..080d29bc40f677c94fc708388a86c72cd1433eb3 100644 (file)
@@ -1,3 +1,7 @@
+2011-04-14  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/ext/vla10.C: New.
+
 2011-04-14  Richard Guenther  <rguenther@suse.de>
 
        * gcc.dg/tree-ssa/ssa-dse-14.c: New testcase.
diff --git a/gcc/testsuite/g++.dg/ext/vla10.C b/gcc/testsuite/g++.dg/ext/vla10.C
new file mode 100644 (file)
index 0000000..17cdb2f
--- /dev/null
@@ -0,0 +1,32 @@
+// PR c++/48446
+// { dg-options "" }
+
+template<typename T>
+struct A
+{
+  ~A ();
+  T *operator-> () const;
+};
+
+struct B
+{
+  typedef A <B> P;
+  static P foo (int);
+};
+
+struct C
+{
+  typedef A<C> P;
+  static const int c = 80;
+};
+
+C::P bar ();
+
+void
+baz ()
+{
+  char z[bar ()->c];
+  {
+    B::P m = B::foo (sizeof (z));
+  }
+}