mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 08:20:32 +08:00
cp-tree.def (SCOPE_STMT): Take one operand.
* cp-tree.def (SCOPE_STMT): Take one operand. * cp-tree.h (SCOPE_STMT_BLOCK): New macro. (SCOPE_NULLIFIED_P): Redefine. (SCOPE_NO_CLEANUPS_P): New macro. (add_scope_stmt): Change prototype. * decl.c (poplevel): Tidy. Warn about unused variables here. Record SCOPE_STMT_BLOCKs. (finish_function): Keep DECL_INITIAL for functions that might be inlined. * ir.texi: Document SCOPE_NO_CLEANUPS_P. * semantics.c: Include rtl.h. (add_scope_stmt): Return the new scope statement and, for an end-of-scope statement, its matching begin statement. Don't set SCOPE_NULLIFIED_P. (do_pushlevel): Simplify, now that we are always function-at-a-time. (do_poplevel): Likewise. Record SCOPE_STMT_BLOCKs. (expand_stmt): Don't call expand_start_bindings or expand_end_bindings for a scope with SCOPE_NO_CLEANUPS_P set. * tree.c (copy_tree_r): Clear SCOPE_STMT_BLOCK rather than setting SCOPE_NULLIFIED_P. From-SVN: r30779
This commit is contained in:
parent
2c0f17dc4f
commit
d9b2d9da75
@ -1,5 +1,27 @@
|
||||
1999-12-04 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.def (SCOPE_STMT): Take one operand.
|
||||
* cp-tree.h (SCOPE_STMT_BLOCK): New macro.
|
||||
(SCOPE_NULLIFIED_P): Redefine.
|
||||
(SCOPE_NO_CLEANUPS_P): New macro.
|
||||
(add_scope_stmt): Change prototype.
|
||||
* decl.c (poplevel): Tidy. Warn about unused variables here.
|
||||
Record SCOPE_STMT_BLOCKs.
|
||||
(finish_function): Keep DECL_INITIAL for functions that might be
|
||||
inlined.
|
||||
* ir.texi: Document SCOPE_NO_CLEANUPS_P.
|
||||
* semantics.c: Include rtl.h.
|
||||
(add_scope_stmt): Return the new scope statement and, for an
|
||||
end-of-scope statement, its matching begin statement. Don't set
|
||||
SCOPE_NULLIFIED_P.
|
||||
(do_pushlevel): Simplify, now that we are always
|
||||
function-at-a-time.
|
||||
(do_poplevel): Likewise. Record SCOPE_STMT_BLOCKs.
|
||||
(expand_stmt): Don't call expand_start_bindings or
|
||||
expand_end_bindings for a scope with SCOPE_NO_CLEANUPS_P set.
|
||||
* tree.c (copy_tree_r): Clear SCOPE_STMT_BLOCK rather than setting
|
||||
SCOPE_NULLIFIED_P.
|
||||
|
||||
* decl2.c (pending_statics_used): Make it a macro.
|
||||
(saved_inlines_used): Likewise.
|
||||
(finish_static_data_member_decl): Use VARRAY_PUSH_TREE.
|
||||
|
@ -254,8 +254,9 @@ DEFTREECODE (START_CATCH_STMT, "start_catch_stmt", 'e', 0)
|
||||
SCOPE_BEGIN_P holds, then this is the start of a scope. If
|
||||
SCOPE_END_P holds, then this is the end of a scope. If
|
||||
SCOPE_NULLIFIED_P holds then there turned out to be no variables in
|
||||
this scope. */
|
||||
DEFTREECODE (SCOPE_STMT, "scope_stmt", 'e', 0)
|
||||
this scope. The SCOPE_STMT_BLOCK is the BLOCK containing the
|
||||
variables declared in this scope. */
|
||||
DEFTREECODE (SCOPE_STMT, "scope_stmt", 'e', 1)
|
||||
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2)
|
||||
DEFTREECODE (CASE_LABEL, "case_label", 'e', 2)
|
||||
DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
|
||||
|
@ -66,7 +66,7 @@ Boston, MA 02111-1307, USA. */
|
||||
(TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
|
||||
ICS_BAD_FLAG (in _CONV)
|
||||
FN_TRY_BLOCK_P (in TRY_BLOCK)
|
||||
SCOPE_NULLIFIED_P (in SCOPE_STMT)
|
||||
SCOPE_NO_CLEANUPS_P (in SCOPE_STMT)
|
||||
4: BINFO_NEW_VTABLE_MARKED.
|
||||
TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
|
||||
or FIELD_DECL).
|
||||
@ -2697,6 +2697,10 @@ extern int flag_new_for_scope;
|
||||
#define SCOPE_END_P(NODE) \
|
||||
(!SCOPE_BEGIN_P (SCOPE_STMT_CHECK (NODE)))
|
||||
|
||||
/* The BLOCK containing the declarations contained in this scope. */
|
||||
#define SCOPE_STMT_BLOCK(NODE) \
|
||||
(TREE_OPERAND (SCOPE_STMT_CHECK (NODE), 0))
|
||||
|
||||
/* Nonzero if this CTOR_STMT is for the beginning of a constructor. */
|
||||
#define CTOR_BEGIN_P(NODE) \
|
||||
(TREE_LANG_FLAG_0 (CTOR_STMT_CHECK (NODE)))
|
||||
@ -2707,6 +2711,12 @@ extern int flag_new_for_scope;
|
||||
|
||||
/* Nonzero for a SCOPE_STMT if there were no variables in this scope. */
|
||||
#define SCOPE_NULLIFIED_P(NODE) \
|
||||
(SCOPE_STMT_BLOCK ((NODE)) == NULL_TREE)
|
||||
|
||||
/* Nonzero for a SCOPE_STMT which represents a lexical scope, but
|
||||
which should be treated as non-existant from the point of view of
|
||||
running cleanup actions. */
|
||||
#define SCOPE_NO_CLEANUPS_P(NODE) \
|
||||
(TREE_LANG_FLAG_3 (SCOPE_STMT_CHECK (NODE)))
|
||||
|
||||
/* Nonzero for a SCOPE_STMT if this statement is for a partial scope.
|
||||
@ -3969,7 +3979,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 tree 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
|
||||
|
@ -1170,7 +1170,6 @@ poplevel (keep, reverse, functionbody)
|
||||
|
||||
/* Output any nested inline functions within this block
|
||||
if they weren't already output. */
|
||||
|
||||
for (decl = decls; decl; decl = TREE_CHAIN (decl))
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& ! TREE_ASM_WRITTEN (decl)
|
||||
@ -1191,10 +1190,17 @@ poplevel (keep, reverse, functionbody)
|
||||
}
|
||||
}
|
||||
|
||||
/* When not in function-at-a-time mode, expand_end_bindings will
|
||||
warn about unused variables. But, in function-at-a-time mode
|
||||
expand_end_bindings is not passed the list of variables in the
|
||||
current scope, and therefore no warning is emitted. So, we
|
||||
explicitly warn here. */
|
||||
if (!processing_template_decl)
|
||||
warn_about_unused_variables (getdecls ());
|
||||
|
||||
/* If there were any declarations or structure tags in that level,
|
||||
or if this level is a function body,
|
||||
create a BLOCK to record them for the life of this function. */
|
||||
|
||||
block = NULL_TREE;
|
||||
block_previously_created = (current_binding_level->this_block != NULL_TREE);
|
||||
if (block_previously_created)
|
||||
@ -1227,7 +1233,6 @@ poplevel (keep, reverse, functionbody)
|
||||
}
|
||||
|
||||
/* In each subblock, record that this is its superior. */
|
||||
|
||||
if (keep >= 0)
|
||||
for (link = subblocks; link; link = TREE_CHAIN (link))
|
||||
BLOCK_SUPERCONTEXT (link) = block;
|
||||
@ -1406,23 +1411,28 @@ poplevel (keep, reverse, functionbody)
|
||||
current_binding_level->blocks
|
||||
= chainon (current_binding_level->blocks, subblocks);
|
||||
|
||||
/* Take care of compiler's internal binding structures. */
|
||||
if (tmp == 2)
|
||||
{
|
||||
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, functionbody);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Take care of compiler's internal binding structures. */
|
||||
if (tmp == 2)
|
||||
{
|
||||
tree scope_stmts;
|
||||
|
||||
scope_stmts
|
||||
= add_scope_stmt (/*begin_p=*/0, /*partial_p=*/1);
|
||||
if (block)
|
||||
{
|
||||
SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
|
||||
SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
|
||||
}
|
||||
|
||||
block = poplevel (keep, reverse, functionbody);
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
@ -13777,7 +13787,8 @@ finish_function (lineno, flags)
|
||||
|
||||
--function_depth;
|
||||
|
||||
if (!DECL_SAVED_INSNS (fndecl) && !DECL_SAVED_FUNCTION_DATA (fndecl))
|
||||
if (!DECL_SAVED_INSNS (fndecl) && !DECL_SAVED_FUNCTION_DATA (fndecl)
|
||||
&& !(flag_inline_trees && DECL_INLINE (fndecl)))
|
||||
{
|
||||
tree t;
|
||||
|
||||
|
@ -1374,9 +1374,9 @@ A scope-statement represents the beginning or end of a scope. If
|
||||
scope; if @code{SCOPE_END_P} holds this statement represents the end of
|
||||
a scope. On exit from a scope, all cleanups from @code{CLEANUP_STMT}s
|
||||
occurring in the scope must be run, in reverse order to the order in
|
||||
which they were encountered. If @code{SCOPE_NULLIFIED_P} holds of the
|
||||
scope, back-ends should behave as if the @code{SCOPE_STMT} were not
|
||||
present at all.
|
||||
which they were encountered. If @code{SCOPE_NULLIFIED_P} or
|
||||
@code{SCOPE_NO_CLEANUPS_P} holds of the scope, back-ends should behave
|
||||
as if the @code{SCOPE_STMT} were not present at all.
|
||||
|
||||
@item START_CATCH_STMT
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "toplev.h"
|
||||
#include "flags.h"
|
||||
#include "ggc.h"
|
||||
#include "rtl.h"
|
||||
|
||||
/* There routines provide a modular interface to perform many parsing
|
||||
operations. They may therefore be used during actual parsing, or
|
||||
@ -1264,38 +1265,44 @@ setup_vtbl_ptr ()
|
||||
/* 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. */
|
||||
an object that needs a cleanup is created. If BEGIN_P is nonzero,
|
||||
returns a new TREE_LIST representing the top of the SCOPE_STMT
|
||||
stack. The TREE_PURPOSE is the new SCOPE_STMT. If BEGIN_P is
|
||||
zero, returns a TREE_LIST whose TREE_VALUE is the new SCOPE_STMT,
|
||||
and whose TREE_PURPOSE is the matching SCOPE_STMT iwth
|
||||
SCOPE_BEGIN_P set. */
|
||||
|
||||
void
|
||||
tree
|
||||
add_scope_stmt (begin_p, partial_p)
|
||||
int begin_p;
|
||||
int partial_p;
|
||||
{
|
||||
tree ss;
|
||||
tree top;
|
||||
|
||||
/* Build the statement. */
|
||||
ss = build_min_nt (SCOPE_STMT);
|
||||
ss = build_min_nt (SCOPE_STMT, NULL_TREE);
|
||||
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);
|
||||
{
|
||||
current_scope_stmt_stack
|
||||
= tree_cons (ss, NULL_TREE, current_scope_stmt_stack);
|
||||
top = current_scope_stmt_stack;
|
||||
}
|
||||
else
|
||||
current_scope_stmt_stack = TREE_CHAIN (current_scope_stmt_stack);
|
||||
{
|
||||
top = current_scope_stmt_stack;
|
||||
TREE_VALUE (top) = ss;
|
||||
current_scope_stmt_stack = TREE_CHAIN (top);
|
||||
}
|
||||
|
||||
/* Add the new statement to the statement-tree. */
|
||||
add_tree (ss);
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
/* Begin a new scope. */
|
||||
@ -1313,8 +1320,9 @@ do_pushlevel ()
|
||||
pushlevel (0);
|
||||
if (!building_stmt_tree ()
|
||||
&& !current_function->x_whole_function_mode_p)
|
||||
expand_start_bindings (0);
|
||||
else if (building_stmt_tree () && !processing_template_decl)
|
||||
my_friendly_abort (19991129);
|
||||
|
||||
if (building_stmt_tree () && !processing_template_decl)
|
||||
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
|
||||
}
|
||||
}
|
||||
@ -1324,28 +1332,27 @@ do_pushlevel ()
|
||||
tree
|
||||
do_poplevel ()
|
||||
{
|
||||
tree t = NULL_TREE;
|
||||
tree block = NULL_TREE;
|
||||
|
||||
if (stmts_are_full_exprs_p)
|
||||
{
|
||||
if (!building_stmt_tree ()
|
||||
&& !current_function->x_whole_function_mode_p)
|
||||
expand_end_bindings (getdecls (), kept_level_p (), 0);
|
||||
else if (building_stmt_tree () && !processing_template_decl)
|
||||
tree scope_stmts;
|
||||
int keep = kept_level_p ();
|
||||
|
||||
if (building_stmt_tree () && !processing_template_decl)
|
||||
scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
|
||||
else
|
||||
scope_stmts = NULL_TREE;
|
||||
|
||||
block = poplevel (kept_level_p (), 1, 0);
|
||||
if (block && !processing_template_decl)
|
||||
{
|
||||
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
|
||||
function-at-a-time mode expand_end_bindings is not passed
|
||||
the list of variables in the current scope, and therefore
|
||||
no warning is emitted. So, we explicitly warn here. */
|
||||
warn_about_unused_variables (getdecls ());
|
||||
SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
|
||||
SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
|
||||
}
|
||||
|
||||
t = poplevel (kept_level_p (), 1, 0);
|
||||
}
|
||||
return t;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
/* Finish a parenthesized expression EXPR. */
|
||||
@ -2473,11 +2480,19 @@ expand_stmt (t)
|
||||
break;
|
||||
|
||||
case SCOPE_STMT:
|
||||
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),
|
||||
SCOPE_PARTIAL_P (t));
|
||||
if (!SCOPE_NO_CLEANUPS_P (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),
|
||||
SCOPE_PARTIAL_P (t));
|
||||
}
|
||||
else if (!SCOPE_NULLIFIED_P (t))
|
||||
emit_note (NULL,
|
||||
(SCOPE_BEGIN_P (t)
|
||||
? NOTE_INSN_BLOCK_BEG
|
||||
: NOTE_INSN_BLOCK_END));
|
||||
break;
|
||||
|
||||
case RETURN_INIT:
|
||||
|
@ -1821,7 +1821,7 @@ copy_tree_r (tp, walk_subtrees, data)
|
||||
/* For now, we don't update BLOCKs when we make copies. So, we
|
||||
have to nullify all scope-statements. */
|
||||
if (TREE_CODE (*tp) == SCOPE_STMT)
|
||||
SCOPE_NULLIFIED_P (*tp) = 1;
|
||||
SCOPE_STMT_BLOCK (*tp) = NULL_TREE;
|
||||
}
|
||||
else if (code == TEMPLATE_TEMPLATE_PARM)
|
||||
/* These must be copied specially. */
|
||||
|
20
gcc/testsuite/g++.old-deja/g++.other/goto2.C
Normal file
20
gcc/testsuite/g++.old-deja/g++.other/goto2.C
Normal file
@ -0,0 +1,20 @@
|
||||
// Build don't link:
|
||||
// Origin: Mark Mitchell <mark@codesourcery.com>
|
||||
// Special g++ Options: -Wunused
|
||||
|
||||
struct S
|
||||
{
|
||||
S ();
|
||||
~S ();
|
||||
};
|
||||
|
||||
void f ()
|
||||
{
|
||||
{
|
||||
S s1;
|
||||
int j; // WARNING - unused
|
||||
|
||||
t: // WARNING - unused
|
||||
S s2;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user