]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/43555
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 May 2010 18:39:28 +0000 (18:39 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 May 2010 18:39:28 +0000 (18:39 +0000)
* decl.c (grokdeclarator) [cdk_pointer et al]: Force evaluation of
anonymous VLA size.

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

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

index 5c094b7df98b5aa9b0e47f1ef3e75bbd5b48f159..f63703ead046f5a975cb9be245836cee5749de0f 100644 (file)
@@ -1,3 +1,9 @@
+2010-05-27  Jason Merrill  <jason@redhat.com>
+
+       PR c++/43555
+       * decl.c (grokdeclarator) [cdk_pointer et al]: Force evaluation of
+       anonymous VLA size.
+
 2010-05-27  Kai Tietz  <kai.tietz@onevision.com>
 
        PR bootstrap/44287
index e560cb47b1d326b42723185e7a05d28bc4ab291e..0d30340358867d08c275b35c5d5462afadb35b2c 100644 (file)
@@ -8705,6 +8705,34 @@ grokdeclarator (const cp_declarator *declarator,
                    : G_("cannot declare pointer to qualified function type %qT"),
                   type);
 
+         /* When the pointed-to type involves components of variable size,
+            care must be taken to ensure that the size evaluation code is
+            emitted early enough to dominate all the possible later uses
+            and late enough for the variables on which it depends to have
+            been assigned.
+
+            This is expected to happen automatically when the pointed-to
+            type has a name/declaration of it's own, but special attention
+            is required if the type is anonymous.
+
+            We handle the NORMAL and FIELD contexts here by inserting a
+            dummy statement that just evaluates the size at a safe point
+            and ensures it is not deferred until e.g. within a deeper
+            conditional context (c++/43555).
+
+            We expect nothing to be needed here for PARM or TYPENAME.
+            Evaluating the size at this point for TYPENAME would
+            actually be incorrect, as we might be in the middle of an
+            expression with side effects on the pointed-to type size
+            "arguments" prior to the pointer declaration point and the
+            size evaluation could end up prior to the side effects.  */
+
+         if (!TYPE_NAME (type)
+             && (decl_context == NORMAL || decl_context == FIELD)
+             && at_function_scope_p ()
+             && variably_modified_type_p (type, NULL_TREE))
+           finish_expr_stmt (TYPE_SIZE (type));
+
          if (declarator->kind == cdk_reference)
            {
              /* In C++0x, the type we are creating a reference to might be
index 63e32a39510cd30eac3090b591ad1432bae01976..5501c8dd93ee627644fc3c33d5b5826689232058 100644 (file)
@@ -1,3 +1,8 @@
+2010-05-27  Jason Merrill  <jason@redhat.com>
+
+       PR c++/43555
+       * g++.dg/ext/vla9.C: New.
+
 2010-05-27  Iain Sandoe  <iains@gcc.gnu.org>
 
        PR ObjC/44140
diff --git a/gcc/testsuite/g++.dg/ext/vla9.C b/gcc/testsuite/g++.dg/ext/vla9.C
new file mode 100644 (file)
index 0000000..c58edbc
--- /dev/null
@@ -0,0 +1,38 @@
+// PR c++/43555
+// { dg-options "" }
+// { dg-do run }
+
+extern "C" void * malloc (__SIZE_TYPE__);
+extern "C" int printf (const char *, ...);
+extern "C" void abort(void);
+
+int nx,ny;
+
+void f(double *x1d,int choice)
+{
+  double (*x2d)[nx][ny]=(double(*)[nx][ny])x1d;
+  unsigned long delta;
+//  (*x2d)[0][0]=123; // <- this line affects the result
+  if (choice!=0)
+  {
+    delta=&(*x2d)[1][0]-x1d;
+  }
+  else
+  {
+    delta=&(*x2d)[1][0]-x1d;
+  }
+  printf("Choice: %d, Delta: %ld\n",choice,delta);
+  if (delta != ny)
+    abort ();
+}
+
+int main()
+{
+  double *data;
+  nx=100;
+  ny=100;
+  data=(double*)malloc(nx*ny*sizeof(double));
+  f(data,0);
+  f(data,1);
+  return 0;
+}