Commit 86ad3aa9 by Jason Merrill Committed by Jason Merrill

re PR c++/13764 (c++ front-end creates extra blocks)

        PR c++/13764
        * c-common.c (finish_fname_decls): Use append_to_statement_list_force.
        * cp/cp-tree.h (FUNCTION_NEEDS_BODY_BLOCK): New macro.
        * cp/name-lookup.c (pushdecl_maybe_friend): Check it.
        * cp/decl.c (begin_function_body): Do nothing if it's false.
        (finish_function_body): Ditto.
        (outer_curly_brace_block): New fn.
        (finish_function): Use it.

From-SVN: r104698
parent 8ec88e19
2005-09-26 Jason Merrill <jason@redhat.com>
PR c++/13764
* c-common.c (finish_fname_decls): Use append_to_statement_list_force.
* doc/invoke.texi: Clarify documentation of -fno-enforce-eh-specs.
2005-09-26 James E Wilson <wilson@specifix.com>
......
......@@ -695,7 +695,7 @@ finish_fname_decls (void)
if (TREE_CODE (*bodyp) == BIND_EXPR)
bodyp = &BIND_EXPR_BODY (*bodyp);
append_to_statement_list (*bodyp, &stmts);
append_to_statement_list_force (*bodyp, &stmts);
*bodyp = stmts;
}
......
2005-09-26 Jason Merrill <jason@redhat.com>
PR c++/13764
* cp-tree.h (FUNCTION_NEEDS_BODY_BLOCK): New macro.
* name-lookup.c (pushdecl_maybe_friend): Check it.
* decl.c (begin_function_body): Do nothing if it's false.
(finish_function_body): Ditto.
(outer_curly_brace_block): New fn.
(finish_function): Use it.
2005-09-26 Richard Guenther <rguenther@suse.de>
PR middle-end/15855
......
......@@ -255,6 +255,8 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
/* Used to mark the block around the member initializers and cleanups. */
#define BIND_EXPR_BODY_BLOCK(NODE) \
TREE_LANG_FLAG_3 (BIND_EXPR_CHECK (NODE))
#define FUNCTION_NEEDS_BODY_BLOCK(NODE) \
(DECL_CONSTRUCTOR_P (NODE) || DECL_DESTRUCTOR_P (NODE))
#define STATEMENT_LIST_NO_SCOPE(NODE) \
TREE_LANG_FLAG_0 (STATEMENT_LIST_CHECK (NODE))
......
......@@ -10656,14 +10656,16 @@ finish_destructor_body (void)
/* Do the necessary processing for the beginning of a function body, which
in this case includes member-initializers, but not the catch clauses of
a function-try-block. Currently, this means opening a binding level
for the member-initializers (in a ctor) and member cleanups (in a dtor).
In other functions, this isn't necessary, but it doesn't hurt. */
for the member-initializers (in a ctor) and member cleanups (in a dtor). */
tree
begin_function_body (void)
{
tree stmt;
if (! FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
return NULL_TREE;
if (processing_template_decl)
/* Do nothing now. */;
else
......@@ -10694,6 +10696,9 @@ begin_function_body (void)
void
finish_function_body (tree compstmt)
{
if (compstmt == NULL_TREE)
return;
/* Close the block. */
finish_compound_stmt (compstmt);
......@@ -10705,6 +10710,20 @@ finish_function_body (tree compstmt)
finish_destructor_body ();
}
/* Given a function, returns the BLOCK corresponding to the outermost level
of curly braces, skipping the artificial block created for constructor
initializers. */
static tree
outer_curly_brace_block (tree fndecl)
{
tree block = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl));
if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
/* Skip the artificial function body block. */
block = BLOCK_SUBBLOCKS (block);
return block;
}
/* Finish up a function declaration and compile that function
all the way to assembler language output. The free the storage
for the function definition.
......@@ -10836,9 +10855,7 @@ finish_function (int flags)
the function so we know that their lifetime always ends with a
return; see g++.dg/opt/nrv6.C. We could be more flexible if
we were to do this optimization in tree-ssa. */
&& (outer = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl)))
/* Skip the artificial function body block. */
&& (outer = BLOCK_SUBBLOCKS (outer))
&& (outer = outer_curly_brace_block (fndecl))
&& chain_member (r, BLOCK_VARS (outer)))
finalize_nrv (&DECL_SAVED_TREE (fndecl), r, DECL_RESULT (fndecl));
......
......@@ -935,8 +935,9 @@ pushdecl_maybe_friend (tree x, bool is_friend)
them there. */
struct cp_binding_level *b = current_binding_level->level_chain;
/* Skip the ctor/dtor cleanup level. */
b = b->level_chain;
if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
/* Skip the ctor/dtor cleanup level. */
b = b->level_chain;
/* ARM $8.3 */
if (b->kind == sk_function_parms)
......
// PR 13764: We were inserting an extra body block in all functions, but
// it's only really necessary for [cd]tors.
// { dg-options "-fdump-tree-gimple" }
void bar (void)
{
int a;
}
// { dg-final { scan-tree-dump-times "\{" 1 "gimple" } }
// { dg-final { cleanup-tree-dump "gimple" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment