summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2005-09-27 16:04:25 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2005-09-27 16:04:25 +0000
commitbc2b76e0ab76f7e34071e916b32c08da70b283aa (patch)
tree3bb0430180145c4c46eccc4eb0371b0a2aeead17
parent20743c8aa7b65f7839c71bf4cb88959f739eb57a (diff)
downloadgcc-bc2b76e0ab76f7e34071e916b32c08da70b283aa.tar.gz
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
-rw-r--r--gcc/ChangeLog3
-rw-r--r--gcc/c-common.c2
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c27
-rw-r--r--gcc/cp/name-lookup.c5
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/block1.C11
7 files changed, 52 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index de070de522b..5b821c89f09 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,8 @@
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>
diff --git a/gcc/c-common.c b/gcc/c-common.c
index fe4bd8c4864..4b1f9e72858 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 44109ef82f5..bdc7237e4bf 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9e74d37dcac..ceaa425af57 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 e3dbc83cb35..bd77e06ddff 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 9afde87016f..f25a3342d70 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 00000000000..5573251cb1f
--- /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" } }