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> 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. * doc/invoke.texi: Clarify documentation of -fno-enforce-eh-specs.
2005-09-26 James E Wilson <wilson@specifix.com> 2005-09-26 James E Wilson <wilson@specifix.com>
......
...@@ -695,7 +695,7 @@ finish_fname_decls (void) ...@@ -695,7 +695,7 @@ finish_fname_decls (void)
if (TREE_CODE (*bodyp) == BIND_EXPR) if (TREE_CODE (*bodyp) == BIND_EXPR)
bodyp = &BIND_EXPR_BODY (*bodyp); bodyp = &BIND_EXPR_BODY (*bodyp);
append_to_statement_list (*bodyp, &stmts); append_to_statement_list_force (*bodyp, &stmts);
*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> 2005-09-26 Richard Guenther <rguenther@suse.de>
PR middle-end/15855 PR middle-end/15855
......
...@@ -255,6 +255,8 @@ typedef struct ptrmem_cst * ptrmem_cst_t; ...@@ -255,6 +255,8 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
/* Used to mark the block around the member initializers and cleanups. */ /* Used to mark the block around the member initializers and cleanups. */
#define BIND_EXPR_BODY_BLOCK(NODE) \ #define BIND_EXPR_BODY_BLOCK(NODE) \
TREE_LANG_FLAG_3 (BIND_EXPR_CHECK (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) \ #define STATEMENT_LIST_NO_SCOPE(NODE) \
TREE_LANG_FLAG_0 (STATEMENT_LIST_CHECK (NODE)) TREE_LANG_FLAG_0 (STATEMENT_LIST_CHECK (NODE))
......
...@@ -10656,14 +10656,16 @@ finish_destructor_body (void) ...@@ -10656,14 +10656,16 @@ finish_destructor_body (void)
/* Do the necessary processing for the beginning of a function body, which /* Do the necessary processing for the beginning of a function body, which
in this case includes member-initializers, but not the catch clauses of in this case includes member-initializers, but not the catch clauses of
a function-try-block. Currently, this means opening a binding level a function-try-block. Currently, this means opening a binding level
for the member-initializers (in a ctor) and member cleanups (in a dtor). 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. */
tree tree
begin_function_body (void) begin_function_body (void)
{ {
tree stmt; tree stmt;
if (! FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
return NULL_TREE;
if (processing_template_decl) if (processing_template_decl)
/* Do nothing now. */; /* Do nothing now. */;
else else
...@@ -10694,6 +10696,9 @@ begin_function_body (void) ...@@ -10694,6 +10696,9 @@ begin_function_body (void)
void void
finish_function_body (tree compstmt) finish_function_body (tree compstmt)
{ {
if (compstmt == NULL_TREE)
return;
/* Close the block. */ /* Close the block. */
finish_compound_stmt (compstmt); finish_compound_stmt (compstmt);
...@@ -10705,6 +10710,20 @@ finish_function_body (tree compstmt) ...@@ -10705,6 +10710,20 @@ finish_function_body (tree compstmt)
finish_destructor_body (); 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 /* Finish up a function declaration and compile that function
all the way to assembler language output. The free the storage all the way to assembler language output. The free the storage
for the function definition. for the function definition.
...@@ -10836,9 +10855,7 @@ finish_function (int flags) ...@@ -10836,9 +10855,7 @@ finish_function (int flags)
the function so we know that their lifetime always ends with a 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 return; see g++.dg/opt/nrv6.C. We could be more flexible if
we were to do this optimization in tree-ssa. */ we were to do this optimization in tree-ssa. */
&& (outer = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl))) && (outer = outer_curly_brace_block (fndecl))
/* Skip the artificial function body block. */
&& (outer = BLOCK_SUBBLOCKS (outer))
&& chain_member (r, BLOCK_VARS (outer))) && chain_member (r, BLOCK_VARS (outer)))
finalize_nrv (&DECL_SAVED_TREE (fndecl), r, DECL_RESULT (fndecl)); finalize_nrv (&DECL_SAVED_TREE (fndecl), r, DECL_RESULT (fndecl));
......
...@@ -935,8 +935,9 @@ pushdecl_maybe_friend (tree x, bool is_friend) ...@@ -935,8 +935,9 @@ pushdecl_maybe_friend (tree x, bool is_friend)
them there. */ them there. */
struct cp_binding_level *b = current_binding_level->level_chain; struct cp_binding_level *b = current_binding_level->level_chain;
/* Skip the ctor/dtor cleanup level. */ if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
b = b->level_chain; /* Skip the ctor/dtor cleanup level. */
b = b->level_chain;
/* ARM $8.3 */ /* ARM $8.3 */
if (b->kind == sk_function_parms) 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