OSDN Git Service

* gimplify.c (gimplify_type_sizes) [POINTER_TYPE, REFERENCE_TYPE]:
authorhainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 6 Oct 2006 09:12:09 +0000 (09:12 +0000)
committerhainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 6 Oct 2006 09:12:09 +0000 (09:12 +0000)
Don't recurse on the pointed-to type.
* c-decl.c (grokdeclarator) [cdk_pointer]: If we are in a NORMAL or
DECL context, attach an artificial TYPE_DECL to anonymous pointed-to
types with components of variable size.

* testsuite/gcc.dg/typename-vla-1.c: New case.
* testsuite/gnat.dg/forward_vla.adb: New case.

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

gcc/ChangeLog
gcc/c-decl.c
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/typename-vla-1.c [new file with mode: 0644]
gcc/testsuite/gnat.dg/forward_vla.adb [new file with mode: 0644]

index 3292139..f9596e8 100644 (file)
@@ -1,3 +1,11 @@
+2006-10-06  Olivier Hainque  <hainque@adacore.com>
+       
+       * gimplify.c (gimplify_type_sizes) [POINTER_TYPE, REFERENCE_TYPE]:
+       Don't recurse on the pointed-to type.
+       * c-decl.c (grokdeclarator) [cdk_pointer]: If we are in a NORMAL or
+       DECL context, attach an artificial TYPE_DECL to anonymous pointed-to
+       types with components of variable size.
+
 2006-10-06  Danny Smith  <dannysmith@users.sourceforge.net>
 
        config/i386/mingw32.h (GOMP_SELF_SPECS): Add -mthreads for openmp.
index fd20078..6379a1e 100644 (file)
@@ -4471,6 +4471,40 @@ grokdeclarator (const struct c_declarator *declarator,
              type = c_build_qualified_type (type, type_quals);
            size_varies = 0;
 
+           /* 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 attaching an
+              artificial TYPE_DECL to such pointed-to type.  This forces the
+              sizes evaluation at a safe point and ensures it is not deferred
+              until e.g. within a deeper conditional context.
+
+              We expect nothing to be needed here for PARM or TYPENAME.
+              Pushing a TYPE_DECL 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 fake TYPE_DECL in the
+              enclosing context would force the size evaluation prior to the
+              side effects.  */
+
+           if (!TYPE_NAME (type)
+               && (decl_context == NORMAL || decl_context == FIELD)
+               && variably_modified_type_p (type, NULL_TREE))
+             {
+               tree decl = build_decl (TYPE_DECL, NULL_TREE, type);
+               DECL_ARTIFICIAL (decl) = 1;
+               pushdecl (decl);
+               finish_decl (decl, NULL_TREE, NULL_TREE);
+               TYPE_NAME (type) = decl;
+             }
+
            type = build_pointer_type (type);
 
            /* Process type qualifiers (such as const or volatile)
index 84c7219..faa5b48 100644 (file)
@@ -6043,7 +6043,18 @@ gimplify_type_sizes (tree type, tree *list_p)
 
     case POINTER_TYPE:
     case REFERENCE_TYPE:
-      gimplify_type_sizes (TREE_TYPE (type), list_p);
+       /* We used to recurse on the pointed-to type here, which turned out to
+          be incorrect because its definition might refer to variables not
+          yet initialized at this point if a forward declaration is involved.
+
+          It was actually useful for anonymous pointed-to types to ensure
+          that the sizes evaluation dominates every possible later use of the
+          values.  Restricting to such types here would be safe since there
+          is no possible forward declaration around, but would introduce a
+          undesireable middle-end semantic to anonymity.  We then defer to
+          front-ends the responsibilty of ensuring that the sizes are
+          evaluated both early and late enough, e.g. by attaching artifical
+          type declarations to the tree.  */
       break;
 
     default:
index 4754970..43988d7 100644 (file)
@@ -1,3 +1,8 @@
+2006-10-06  Olivier Hainque  <hainque@adacore.com>
+       
+       * gcc.dg/typename-vla-1.c: New case.
+       * gnat.dg/forward_vla.adb: New case.
+
 2006-10-06  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/29290
diff --git a/gcc/testsuite/gcc.dg/typename-vla-1.c b/gcc/testsuite/gcc.dg/typename-vla-1.c
new file mode 100644 (file)
index 0000000..1616513
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR c/21536 */
+/* { dg-do run } */
+/* { dg-options "-O2 -Wuninitialized" } */
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+  int a = 1;
+  if (sizeof (*(++a, (char (*)[a])0)) != 2)
+    abort ();
+  exit (0);
+}
+
+
diff --git a/gcc/testsuite/gnat.dg/forward_vla.adb b/gcc/testsuite/gnat.dg/forward_vla.adb
new file mode 100644 (file)
index 0000000..515112b
--- /dev/null
@@ -0,0 +1,20 @@
+-- { dg-do compile }
+-- { dg-options "-O2 -gnatp -Wuninitialized" }
+
+procedure Forward_Vla is
+
+   function N return Natural is begin return 1; end;
+
+   type Sequence;
+   type Sequence_Access is access all Sequence;
+
+   Ptr : Sequence_Access := null;  -- freeze access type
+
+   Sequence_Length : Natural := N;
+   type Sequence is array (1 .. Sequence_Length) of Natural;
+
+   Seq : Sequence;
+begin
+   Seq (1) := 0;
+end;
+