mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-26 07:40:26 +08:00
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
This commit is contained in:
parent
f6a51d3184
commit
e11187cc94
@ -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.
|
||||
|
34
gcc/c-decl.c
34
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);
|
||||
|
@ -1,3 +1,9 @@
|
||||
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
|
||||
|
35
gcc/testsuite/gcc.dg/c99-const-expr-14.c
Normal file
35
gcc/testsuite/gcc.dg/c99-const-expr-14.c
Normal file
@ -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;
|
29
gcc/testsuite/gcc.dg/gnu99-const-expr-4.c
Normal file
29
gcc/testsuite/gcc.dg/gnu99-const-expr-4.c
Normal file
@ -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" } */
|
7
gcc/testsuite/gcc.dg/vla-21.c
Normal file
7
gcc/testsuite/gcc.dg/vla-21.c
Normal file
@ -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]);
|
Loading…
x
Reference in New Issue
Block a user