aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2009-04-26 18:00:04 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2009-04-26 18:00:04 +0100
commite11187cc9473e1ad1d6a6df452187539fd248ed4 (patch)
treef5f749a398961d61350c6b4f85c26984ab3f9154
parentf6a51d3184cb8cd65a5b9a72312c4f4fb814a384 (diff)
downloadgcc-e11187cc9473e1ad1d6a6df452187539fd248ed4.zip
gcc-e11187cc9473e1ad1d6a6df452187539fd248ed4.tar.gz
gcc-e11187cc9473e1ad1d6a6df452187539fd248ed4.tar.bz2
re PR c/39581 (VLA types at file scope wrongly rejected)
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. testsuite: * gcc.dg/c99-const-expr-14.c, gcc.dg/gnu99-const-expr-4.c, gcc.dg/vla-21.c: New tests. From-SVN: r146806
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/c-decl.c34
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/c99-const-expr-14.c35
-rw-r--r--gcc/testsuite/gcc.dg/gnu99-const-expr-4.c29
-rw-r--r--gcc/testsuite/gcc.dg/vla-21.c7
6 files changed, 117 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 01046ef..da92f2f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index b87fee5..88bfa25 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 79f0ff7..65d6cdf8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..0c4f1b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-const-expr-14.c
@@ -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
index 0000000..baaa630
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu99-const-expr-4.c
@@ -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
index 0000000..a39ae0b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vla-21.c
@@ -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]);