Skip to content

Commit

Permalink
* cp-tree.h (SCOPE_PARTIAL_P): New macro.
Browse files Browse the repository at this point in the history
	(pushlevel_temporary): Remove.
	(add_scope_stmt): New function.
	* decl.c (pushlevel_temporary): Remove.
	(poplevel): Use add_scope_stmt.
	(start_decl_1): Likewise.
	* semantics.c (add_scope_stmt): New function.
	(do_pushlevel): Use it.
	(do_poplevel): Use it.
	(expand_stmt): Check SCOPE_PARTIAL_P.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30118 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
mmitchel committed Oct 21, 1999
1 parent f4e94e2 commit 4f39667
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 36 deletions.
11 changes: 11 additions & 0 deletions gcc/cp/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
1999-10-21 Mark Mitchell <mark@codesourcery.com>

* cp-tree.h (SCOPE_PARTIAL_P): New macro.
(pushlevel_temporary): Remove.
(add_scope_stmt): New function.
* decl.c (pushlevel_temporary): Remove.
(poplevel): Use add_scope_stmt.
(start_decl_1): Likewise.
* semantics.c (add_scope_stmt): New function.
(do_pushlevel): Use it.
(do_poplevel): Use it.
(expand_stmt): Check SCOPE_PARTIAL_P.

* cp-tree.def (EMPTY_CLASS_EXPR): New tree node.
* call.c (build_call): Use EMPTY_CLASS_EXPR instead of RTL_EXPR.
* expr.c (cplus_expand_expr): Expand it.
Expand Down
18 changes: 17 additions & 1 deletion gcc/cp/cp-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Boston, MA 02111-1307, USA. */
TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
or FIELD_DECL).
NEED_TEMPORARY_P (in REF_BIND, BASE_CONV)
SCOPE_PARTIAL_P (in SCOPE_STMT)
5: Not used.
6: Not used.
Expand Down Expand Up @@ -2651,6 +2652,21 @@ extern int flag_new_for_scope;
#define SCOPE_NULLIFIED_P(NODE) \
(TREE_LANG_FLAG_3 (SCOPE_STMT_CHECK (NODE)))

/* Nonzero for a SCOPE_STMT if this statement is for a partial scope.
For example, in:
S s;
l:
S s2;
goto l;
there is (implicitly) a new scope after `l', even though there are
no curly braces. In particular, when we hit the goto, we must
destroy s2 and then re-construct it. For the implicit scope,
SCOPE_PARTIAL_P will be set. */
#define SCOPE_PARTIAL_P(NODE) \
(TREE_LANG_FLAG_4 (SCOPE_STMT_CHECK (NODE)))

/* Nonzero for an ASM_STMT if the assembly statement is volatile. */
#define ASM_VOLATILE_P(NODE) \
(ASM_CV_QUAL (ASM_STMT_CHECK (NODE)) != NULL_TREE)
Expand Down Expand Up @@ -3336,7 +3352,6 @@ extern int pseudo_global_level_p PROTO((void));
extern void set_class_shadows PROTO((tree));
extern void pushlevel PROTO((int));
extern void note_level_for_for PROTO((void));
extern void pushlevel_temporary PROTO((int));
extern void resume_level PROTO((struct binding_level *));
extern void delete_block PROTO((tree));
extern void insert_block PROTO((tree));
Expand Down Expand Up @@ -3886,6 +3901,7 @@ extern void expand_body PROTO((tree));
extern void begin_stmt_tree PROTO((tree *));
extern void finish_stmt_tree PROTO((tree *));
extern void prep_stmt PROTO((tree));
extern void add_scope_stmt PROTO((int, int));
extern void do_pushlevel PROTO((void));
extern tree do_poplevel PROTO((void));
/* Non-zero if we are presently building a statement tree, rather
Expand Down
32 changes: 11 additions & 21 deletions gcc/cp/decl.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,21 +825,6 @@ note_level_for_for ()
current_binding_level->is_for_scope = 1;
}

void
pushlevel_temporary (tag_transparent)
int tag_transparent;
{
pushlevel (tag_transparent);
current_binding_level->keep = 2;
clear_last_expr ();

/* Note we don't call push_momentary() here. Otherwise, it would cause
cleanups to be allocated on the momentary obstack, and they will be
overwritten by the next statement. */

expand_start_bindings (0);
}

/* For a binding between a name and an entity at a block scope,
this is the `struct binding_level' for the block. */
#define BINDING_LEVEL(NODE) \
Expand Down Expand Up @@ -1458,13 +1443,13 @@ poplevel (keep, reverse, functionbody)
/* Take care of compiler's internal binding structures. */
if (tmp == 2)
{
expand_end_bindings (getdecls (), keep, 1);
add_scope_stmt (/*begin_p=*/0, /*partial_p=*/1);
/* Each and every BLOCK node created here in `poplevel' is important
(e.g. for proper debugging information) so if we created one
earlier, mark it as "used". */
if (block)
TREE_USED (block) = 1;
block = poplevel (keep, reverse, real_functionbody);
block = poplevel (keep, reverse, functionbody);
}

/* Each and every BLOCK node created here in `poplevel' is important
Expand Down Expand Up @@ -6874,12 +6859,17 @@ start_decl_1 (decl)
if (type == error_mark_node)
return;

/* If this type of object needs a cleanup, and control may
jump past it, make a new binding level so that it is cleaned
up only when it is initialized first. */
/* If this type of object needs a cleanup, but we're not allowed to
add any more objects with cleanups to the current scope, create a
new binding level. */
if (TYPE_NEEDS_DESTRUCTOR (type)
&& current_binding_level->more_cleanups_ok == 0)
pushlevel_temporary (1);
{
keep_next_level (2);
pushlevel (1);
clear_last_expr ();
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
}

if (initialized)
/* Is it valid for this decl to have an initializer at all?
Expand Down
55 changes: 41 additions & 14 deletions gcc/cp/semantics.c
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,43 @@ setup_vtbl_ptr ()
vtbls_set_up_p = 1;
}

/* Add a scope-statement to the statement-tree. BEGIN_P indicates
whether this statements opens or closes a scope. PARTIAL_P is true
for a partial scope, i.e, the scope that begins after a label when
an object that needs a cleanup is created. */

void
add_scope_stmt (begin_p, partial_p)
int begin_p;
int partial_p;
{
tree ss;

/* Build the statement. */
ss = build_min_nt (SCOPE_STMT);
SCOPE_BEGIN_P (ss) = begin_p;
SCOPE_PARTIAL_P (ss) = partial_p;

/* If we're finishing a scope, figure out whether the scope was
really necessary. */
if (!begin_p)
{
SCOPE_NULLIFIED_P (ss) = !kept_level_p ();
SCOPE_NULLIFIED_P (TREE_VALUE (current_scope_stmt_stack))
= SCOPE_NULLIFIED_P (ss);
}

/* Keep the scope stack up to date. */
if (begin_p)
current_scope_stmt_stack
= tree_cons (NULL_TREE, ss, current_scope_stmt_stack);
else
current_scope_stmt_stack = TREE_CHAIN (current_scope_stmt_stack);

/* Add the new statement to the statement-tree. */
add_tree (ss);
}

/* Begin a new scope. */

void
Expand All @@ -1266,13 +1303,7 @@ do_pushlevel ()
&& !current_function->x_whole_function_mode_p)
expand_start_bindings (0);
else if (building_stmt_tree () && !processing_template_decl)
{
tree ss = build_min_nt (SCOPE_STMT);
SCOPE_BEGIN_P (ss) = 1;
add_tree (ss);
current_scope_stmt_stack
= tree_cons (NULL_TREE, ss, current_scope_stmt_stack);
}
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
}
}

Expand All @@ -1290,12 +1321,7 @@ do_poplevel ()
expand_end_bindings (getdecls (), kept_level_p (), 0);
else if (building_stmt_tree () && !processing_template_decl)
{
tree ss = build_min_nt (SCOPE_STMT);
SCOPE_NULLIFIED_P (ss) = !kept_level_p ();
SCOPE_NULLIFIED_P (TREE_VALUE (current_scope_stmt_stack))
= SCOPE_NULLIFIED_P (ss);
add_tree (ss);
current_scope_stmt_stack = TREE_CHAIN (current_scope_stmt_stack);
add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);

/* When not in function-at-a-time mode, expand_end_bindings
will warn about unused variables. But, in
Expand Down Expand Up @@ -2455,7 +2481,8 @@ expand_stmt (t)
if (SCOPE_BEGIN_P (t))
expand_start_bindings (2 * SCOPE_NULLIFIED_P (t));
else if (SCOPE_END_P (t))
expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 0);
expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t),
SCOPE_PARTIAL_P (t));
break;

case RETURN_INIT:
Expand Down
15 changes: 15 additions & 0 deletions gcc/testsuite/g++.old-deja/g++.other/debug5.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Build don't link:
// Special g++ Options: -g
// Origin: Mark Mitchell <mark@codesourcery.com>

struct S
{
~S ();
};

void f ()
{
t:
S s3;
}

21 changes: 21 additions & 0 deletions gcc/testsuite/g++.old-deja/g++.other/goto1.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Build don't link:
// Origin: Mark Mitchell <mark@codesourcery.com>

struct S
{
S ();
~S ();
};

void f ()
{
{
S s1;

t:
S s2;
;
}

goto t; // ERROR - jump avoids initialization of `s1'
}

0 comments on commit 4f39667

Please sign in to comment.