From 7fc1e5fb14010db60715fda1fdd30a3d975614fc Mon Sep 17 00:00:00 2001 From: jsm28 Date: Sun, 26 Apr 2009 17:00:04 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146806 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++ gcc/c-decl.c | 34 ++++++++++++++++++++-- gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/gcc.dg/c99-const-expr-14.c | 35 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/gnu99-const-expr-4.c | 29 +++++++++++++++++++ gcc/testsuite/gcc.dg/vla-21.c | 7 +++++ 6 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/c99-const-expr-14.c create mode 100644 gcc/testsuite/gcc.dg/gnu99-const-expr-4.c create mode 100644 gcc/testsuite/gcc.dg/vla-21.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 01046ef4ba28..da92f2f9686a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-04-26 Joseph Myers + + 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 * config/i386/i386.c (print_operand) ['z']: Fix typo. diff --git a/gcc/c-decl.c b/gcc/c-decl.c index b87fee543425..88bfa25008e2 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 79f0ff7d212a..65d6cdf8feb8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-04-26 Joseph Myers + + 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 PR c/39556 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 000000000000..0c4f1b69bd4a --- /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 */ +/* { 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 + + ; 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 000000000000..baaa63031a50 --- /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 */ +/* { 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 + + ; 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 000000000000..a39ae0b42666 --- /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]); -- 2.47.2