summaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-30 19:56:39 +0000
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-30 19:56:39 +0000
commitf08c7a57f79b981e68df4f7d1cfa244297849c4a (patch)
tree975e92e4bf871faf584ef0740e176cafc5997392 /gcc/c-decl.c
parent494fc9d0f43f28049e7334c2f16183a700da3882 (diff)
downloadgcc-f08c7a57f79b981e68df4f7d1cfa244297849c4a.tar.gz
PR c/772
PR c/17913 * c-tree.h (C_DECL_UNJUMPABLE_STMT_EXPR, C_DECL_UNDEFINABLE_STMT_EXPR, struct c_label_list, struct c_label_context, label_context_stack): New. * c-decl.c (define_label): Check for jumps into statement expressions. Add label to list of defined labels. (start_function): Push context on label_context_stack. (finish_function): Pop context from label_context_stack. * c-typeck.c (label_context_stack): New. (c_finish_goto_label): Check for jumps into statement expressions. Add label to list of jumped to labels. (struct c_switch): Add blocked_stmt_expr. (c_start_case): Initialize it. (do_case): Check it. (c_finish_case): Verify !blocked_stmt_expr. (c_begin_stmt_expr): Push context on label_context_stack. Increment blocked_stmt_expr. Mark labels jumped to from outside as undefinable. (c_finish_stmt_expr): December blocked_stmt_expr. Mark labels defined in the statement expression and no longer jumpable to. Mark labels jumped to from just outside the statement expression as again definable. Pop context from label_context_stack. * doc/extend.texi (Statement Exprs): Update. objc: * objc-act.c (objc_start_function): Push context on label_context_stack. testsuite: * gcc.dg/stmt-expr-label-1.c, gcc.dg/stmt-expr-label-2.c, gcc.dg/stmt-expr-label-3.c : New tests. * gcc.c-torture/execute/medce-2.c: Remove. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97273 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index f333dade0b8..cb8fd9dfa2f 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -2440,6 +2440,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;
if (label
&& ((DECL_CONTEXT (label) == current_function_decl
@@ -2456,6 +2457,8 @@ define_label (location_t location, tree name)
/* The label has been used or declared already in this function,
but not defined. Update its location to point to this
definition. */
+ if (C_DECL_UNDEFINABLE_STMT_EXPR (label))
+ error ("%Jjump into statement expression", label);
DECL_SOURCE_LOCATION (label) = location;
}
else
@@ -2472,6 +2475,11 @@ 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;
+
/* Mark label as having been defined. */
DECL_INITIAL (label) = error_mark_node;
return label;
@@ -5631,6 +5639,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
{
tree decl1, old_decl;
tree restype, resdecl;
+ struct c_label_context *nstack;
current_function_returns_value = 0; /* Assume, until we see it does. */
current_function_returns_null = 0;
@@ -5639,6 +5648,12 @@ 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;
+
/* Indicate no valid break/continue context by setting these variables
to some non-null, non-label value. We'll notice and emit the proper
error message in c_finish_bc_stmt. */
@@ -6220,6 +6235,8 @@ finish_function (void)
{
tree fndecl = current_function_decl;
+ label_context_stack = label_context_stack->next;
+
if (TREE_CODE (fndecl) == FUNCTION_DECL
&& targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
{