diff options
author | Joseph Myers <joseph@codesourcery.com> | 2005-04-20 17:41:48 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2005-04-20 17:41:48 +0100 |
commit | 187230a795716fc0d98cb066402fe9d71639996c (patch) | |
tree | e2e44d98a3c2439eda0265c0bce9ef5990fc410d /gcc/c-decl.c | |
parent | 2a9254314b416c9d6e8eccf600a54ed829a48147 (diff) | |
download | gcc-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.c | 49 |
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))) |