OSDN Git Service

PR c/39581
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 26 Apr 2009 17:00:04 +0000 (17:00 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 26 Apr 2009 17:00:04 +0000 (17:00 +0000)
* c-decl.c (global_bindings_p): Return negative value.
(c_variable_size): New.  Based on variable_size from
stor-layout.c.
(grokdeclarator): Call c_variable_size not variable_size.

testsuite:
* gcc.dg/c99-const-expr-14.c, gcc.dg/gnu99-const-expr-4.c,
gcc.dg/vla-21.c: New tests.

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

gcc/ChangeLog
gcc/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/c99-const-expr-14.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gnu99-const-expr-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vla-21.c [new file with mode: 0644]

index 01046ef..da92f2f 100644 (file)
@@ -1,3 +1,11 @@
+2009-04-26  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/39581
+       * c-decl.c (global_bindings_p): Return negative value.
+       (c_variable_size): New.  Based on variable_size from
+       stor-layout.c.
+       (grokdeclarator): Call c_variable_size not variable_size.
+
 2009-04-26  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.c (print_operand) ['z']: Fix typo.
index b87fee5..88bfa25 100644 (file)
@@ -663,7 +663,9 @@ objc_mark_locals_volatile (void *enclosing_blk)
 int
 global_bindings_p (void)
 {
-  return current_scope == file_scope && !c_override_global_bindings_to_false;
+  return (current_scope == file_scope && !c_override_global_bindings_to_false
+         ? -1
+         : 0);
 }
 
 void
@@ -4015,6 +4017,34 @@ warn_variable_length_array (const char *name, tree size)
     }
 }
 
+/* Given a size SIZE that may not be a constant, return a SAVE_EXPR to
+   serve as the actual size-expression for a type or decl.  This is
+   like variable_size in stor-layout.c, but we make global_bindings_p
+   return negative to avoid calls to that function from outside the
+   front end resulting in errors at file scope, then call this version
+   instead from front-end code.  */
+
+static tree
+c_variable_size (tree size)
+{
+  tree save;
+
+  if (TREE_CONSTANT (size))
+    return size;
+
+  size = save_expr (size);
+
+  save = skip_simple_arithmetic (size);
+
+  if (cfun && cfun->dont_save_pending_sizes_p)
+    return size;
+
+  if (!global_bindings_p ())
+    put_pending_size (save);
+
+  return size;
+}
+
 /* Given declspecs and a declarator,
    determine the name and type of the object declared
    and construct a ..._DECL node for it.
@@ -4479,7 +4509,7 @@ grokdeclarator (const struct c_declarator *declarator,
                       MINUS_EXPR, which allows the -1 to get folded
                       with the +1 that happens when building TYPE_SIZE.  */
                    if (size_varies)
-                     size = variable_size (size);
+                     size = c_variable_size (size);
                    if (this_size_varies && TREE_CODE (size) == INTEGER_CST)
                      size = build2 (COMPOUND_EXPR, TREE_TYPE (size),
                                     integer_zero_node, size);
index 79f0ff7..65d6cdf 100644 (file)
@@ -1,5 +1,11 @@
 2009-04-26  Joseph Myers  <joseph@codesourcery.com>
 
+       PR c/39581
+       * gcc.dg/c99-const-expr-14.c, gcc.dg/gnu99-const-expr-4.c,
+       gcc.dg/vla-21.c: New tests.
+
+2009-04-26  Joseph Myers  <joseph@codesourcery.com>
+
        PR c/39556
        * gcc.dg/inline-34.c: New test.
 
diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-14.c b/gcc/testsuite/gcc.dg/c99-const-expr-14.c
new file mode 100644 (file)
index 0000000..0c4f1b6
--- /dev/null
@@ -0,0 +1,35 @@
+/* Test for constant expressions: cases involving VLAs, at file scope.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+/* It appears address constants may contain casts to variably modified
+   types.  Whether they should be permitted was discussed in
+   <http://groups.google.com/group/comp.std.c/msg/923eee5ab690fd98>
+   <LV7g2Vy3ARF$Ew9Q@romana.davros.org>; since static pointers to VLAs
+   are definitely permitted within functions and may be initialized
+   and such initialization involves implicit conversion to a variably
+   modified type, allowing explicit casts seems appropriate.  Thus,
+   GCC allows them as long as the "evaluated" size expressions do not
+   contain the various operators not permitted to be evaluated in a
+   constant expression, and as long as the result is genuinely
+   constant (meaning that pointer arithmetic using the size of the VLA
+   is generally not permitted).  */
+
+static int sa[100];
+
+volatile int nv;
+int m;
+int n;
+int f (int, int);
+
+static int (*a2)[] = (int (*)[n])sa;
+static int (*a8)[] = (int (*)[(m=n)])sa; /* { dg-error "constant" } */
+static int (*a9)[] = (int (*)[(m+=n)])sa; /* { dg-error "constant" } */
+static int (*a10)[] = (int (*)[f(m,n)])sa; /* { dg-error "constant" } */
+static int (*a11)[] = (int (*)[(m,n)])sa; /* { dg-error "constant" } */
+static int (*a12)[] = (int (*)[sizeof(int[n])])sa;
+static int (*a13)[] = (int (*)[sizeof(int[m++])])sa; /* { dg-error "constant" } */
+static int (*a15)[] = (int (*)[sizeof(*(int (*)[n])sa)])sa;
+static int (*a16)[] = (int (*)[sizeof(*(int (*)[m++])sa)])sa; /* { dg-error "constant" } */
+static int (*a17)[] = (int (*)[nv])sa;
diff --git a/gcc/testsuite/gcc.dg/gnu99-const-expr-4.c b/gcc/testsuite/gcc.dg/gnu99-const-expr-4.c
new file mode 100644 (file)
index 0000000..baaa630
--- /dev/null
@@ -0,0 +1,29 @@
+/* Test for constant expressions: cases involving VLAs and typeof, at
+   file scope.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 -pedantic-errors" } */
+
+/* It appears address constants may contain casts to variably modified
+   types.  Whether they should be permitted was discussed in
+   <http://groups.google.com/group/comp.std.c/msg/923eee5ab690fd98>
+   <LV7g2Vy3ARF$Ew9Q@romana.davros.org>; since static pointers to VLAs
+   are definitely permitted within functions and may be initialized
+   and such initialization involves implicit conversion to a variably
+   modified type, allowing explicit casts seems appropriate.  Thus,
+   GCC allows them as long as the "evaluated" size expressions do not
+   contain the various operators not permitted to be evaluated in a
+   constant expression, and as long as the result is genuinely
+   constant (meaning that pointer arithmetic using the size of the VLA
+   is generally not permitted).  */
+
+static int sa[100];
+int m;
+int n;
+
+static int (*a1)[] = &sa;
+static int (*a2)[] = (__typeof__(int (*)[n]))sa;
+static int (*a4)[] = (__typeof__((int (*)[n])sa))sa;
+static int (*a5)[] = (__typeof__((int (*)[m++])sa))sa; /* { dg-error "constant" } */
+static int (*a6)[] = (__typeof__((int (*)[100])(int (*)[m++])sa))sa;
+static int (*a7)[] = (__typeof__((int (*)[n])sa + m++))sa; /* { dg-error "constant" } */
diff --git a/gcc/testsuite/gcc.dg/vla-21.c b/gcc/testsuite/gcc.dg/vla-21.c
new file mode 100644 (file)
index 0000000..a39ae0b
--- /dev/null
@@ -0,0 +1,7 @@
+/* Type names for VLAs should be allowed outside functions if the size
+   is not evaluated.  PR 39581.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic-errors" } */
+
+int a;
+int b = sizeof (int (*)[a]);