summaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2005-04-20 17:41:48 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2005-04-20 17:41:48 +0100
commit187230a795716fc0d98cb066402fe9d71639996c (patch)
treee2e44d98a3c2439eda0265c0bce9ef5990fc410d /gcc/c-decl.c
parent2a9254314b416c9d6e8eccf600a54ed829a48147 (diff)
downloadgcc-187230a795716fc0d98cb066402fe9d71639996c.tar.gz
re PR c/12913 (Jumps into variable length array scope not rejected)
PR c/12913 * c-tree.h (struct c_label_list): Update comment. (struct c_label_context): Rename to struct c_label_context_se. (label_context_stack): Rename to label_context_stack_se. (C_DECL_UNJUMPABLE_VM, C_DECL_UNDEFINABLE_VM, struct c_label_context_vm, label_context_stack_vm, c_begin_vm_scope, c_end_vm_scope): New. (C_DECL_DECLARED_BUILTIN, C_DECL_USED): Use FUNCTION_DECL_CHECK. * c-decl.c (pop_scope): Call c_end_vm_scope. (pushdecl): Call c_begin_vm_scope for variably modified declarations. (define_label): Check for jumping into scope of identifier with variably modified type. Push label on stack for those defined at current context of identifiers with variably modified type. (start_function): Create stack level for context of identifiers with variably modified type. (finish_function): Pop stack level for context of identifiers with variably modified type. * c-typeck.c (label_context_stack): Rename to label_context_stack_se. (label_context_stack_vm, c_begin_vm_scope, c_end_vm_scope): New. (c_finish_goto_label): Check for jumping into scope of identifier with variably modified type. Push label on stack for those jumped to from current context of identifiers with variably modified type. (struct c_switch): Add blocked_vm. (c_start_case): Initialize blocked_vm. (do_case): Check blocked_vm. (c_finish_case): Add comment. (c_begin_stmt_expr, c_finish_stmt_expr): Update for renamed variable label_context_stack. objc: * objc-act.c (objc_start_function): Create stack level for context of identifiers with variably modified type. testsuite: * gcc.dg/c99-vla-jump-1.c, gcc.dg/c99-vla-jump-2.c, gcc.dg/c99-vla-jump-3.c, gcc.dg/c99-vla-jump-4.c, gcc.dg/c99-vla-jump-5.c: New tests. From-SVN: r98464
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index d02d7429bad..5140a0fa5ed 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -673,6 +673,8 @@ pop_scope (void)
bool functionbody = scope->function_body;
bool keep = functionbody || scope->keep || scope->bindings;
+ c_end_vm_scope (scope->depth);
+
/* If appropriate, create a BLOCK to record the decls for the life
of this function. */
block = 0;
@@ -1983,6 +1985,12 @@ pushdecl (tree x)
|| DECL_INITIAL (x) || !DECL_EXTERNAL (x)))
DECL_CONTEXT (x) = current_function_decl;
+ /* If this is of variably modified type, prevent jumping into its
+ scope. */
+ if ((TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == TYPE_DECL)
+ && variably_modified_type_p (TREE_TYPE (x), NULL_TREE))
+ c_begin_vm_scope (scope->depth);
+
/* Anonymous decls are just inserted in the scope. */
if (!name)
{
@@ -2439,7 +2447,7 @@ define_label (location_t location, tree name)
if there is a containing function with a declared label with
the same name. */
tree label = I_LABEL_DECL (name);
- struct c_label_list *nlist;
+ struct c_label_list *nlist_se, *nlist_vm;
if (label
&& ((DECL_CONTEXT (label) == current_function_decl
@@ -2458,6 +2466,9 @@ define_label (location_t location, tree name)
definition. */
if (C_DECL_UNDEFINABLE_STMT_EXPR (label))
error ("%Jjump into statement expression", label);
+ if (C_DECL_UNDEFINABLE_VM (label))
+ error ("%Jjump into scope of identifier with variably modified type",
+ label);
DECL_SOURCE_LOCATION (label) = location;
}
else
@@ -2474,10 +2485,15 @@ define_label (location_t location, tree name)
warning ("%Htraditional C lacks a separate namespace for labels, "
"identifier %qE conflicts", &location, name);
- nlist = XOBNEW (&parser_obstack, struct c_label_list);
- nlist->next = label_context_stack->labels_def;
- nlist->label = label;
- label_context_stack->labels_def = nlist;
+ nlist_se = XOBNEW (&parser_obstack, struct c_label_list);
+ nlist_se->next = label_context_stack_se->labels_def;
+ nlist_se->label = label;
+ label_context_stack_se->labels_def = nlist_se;
+
+ nlist_vm = XOBNEW (&parser_obstack, struct c_label_list);
+ nlist_vm->next = label_context_stack_vm->labels_def;
+ nlist_vm->label = label;
+ label_context_stack_vm->labels_def = nlist_vm;
/* Mark label as having been defined. */
DECL_INITIAL (label) = error_mark_node;
@@ -5637,7 +5653,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
{
tree decl1, old_decl;
tree restype, resdecl;
- struct c_label_context *nstack;
+ struct c_label_context_se *nstack_se;
+ struct c_label_context_vm *nstack_vm;
current_function_returns_value = 0; /* Assume, until we see it does. */
current_function_returns_null = 0;
@@ -5646,11 +5663,18 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
current_extern_inline = 0;
c_switch_stack = NULL;
- nstack = XOBNEW (&parser_obstack, struct c_label_context);
- nstack->labels_def = NULL;
- nstack->labels_used = NULL;
- nstack->next = label_context_stack;
- label_context_stack = nstack;
+ nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
+ nstack_se->labels_def = NULL;
+ nstack_se->labels_used = NULL;
+ nstack_se->next = label_context_stack_se;
+ label_context_stack_se = nstack_se;
+
+ nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
+ nstack_vm->labels_def = NULL;
+ nstack_vm->labels_used = NULL;
+ nstack_vm->scope = 0;
+ nstack_vm->next = label_context_stack_vm;
+ label_context_stack_vm = nstack_vm;
/* Indicate no valid break/continue context by setting these variables
to some non-null, non-label value. We'll notice and emit the proper
@@ -6233,7 +6257,8 @@ finish_function (void)
{
tree fndecl = current_function_decl;
- label_context_stack = label_context_stack->next;
+ label_context_stack_se = label_context_stack_se->next;
+ label_context_stack_vm = label_context_stack_vm->next;
if (TREE_CODE (fndecl) == FUNCTION_DECL
&& targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))