From bc2b76e0ab76f7e34071e916b32c08da70b283aa Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 27 Sep 2005 16:04:25 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104698 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 3 +++ gcc/c-common.c | 2 +- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/cp-tree.h | 2 ++ gcc/cp/decl.c | 27 ++++++++++++++++++++++----- gcc/cp/name-lookup.c | 5 +++-- gcc/testsuite/g++.dg/tree-ssa/block1.C | 11 +++++++++++ 7 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/block1.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index de070de..5b821c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,8 @@ 2005-09-26 Jason Merrill + 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 diff --git a/gcc/c-common.c b/gcc/c-common.c index fe4bd8c..4b1f9e7 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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; } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 44109ef..bdc7237 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2005-09-26 Jason Merrill + + 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 PR middle-end/15855 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9e74d37..ceaa425 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e3dbc83..bd77e06 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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)); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 9afde87..f25a334 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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) diff --git a/gcc/testsuite/g++.dg/tree-ssa/block1.C b/gcc/testsuite/g++.dg/tree-ssa/block1.C new file mode 100644 index 0000000..5573251 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/block1.C @@ -0,0 +1,11 @@ +// 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" } } -- 2.7.4