aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
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 d02d742..5140a0f 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)))