diff options
author | Joseph Myers <joseph@codesourcery.com> | 2009-04-26 18:00:04 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2009-04-26 18:00:04 +0100 |
commit | e11187cc9473e1ad1d6a6df452187539fd248ed4 (patch) | |
tree | f5f749a398961d61350c6b4f85c26984ab3f9154 | |
parent | f6a51d3184cb8cd65a5b9a72312c4f4fb814a384 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/c-decl.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/c99-const-expr-14.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/gnu99-const-expr-4.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vla-21.c | 7 |
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]); |