aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
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 /gcc/c-decl.c
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
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c34
1 files changed, 32 insertions, 2 deletions
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);