aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-06-19 11:11:43 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-06-19 11:11:43 +0000
commit0045e0bc3ceacdd3e52d8f0a9162e92f1a5570db (patch)
tree3f68877ca60ca264dadc0597d76ec96371959917
parent61571dfc4a69d6be22522fe8ee303946d516dd9f (diff)
downloadgcc-0045e0bc3ceacdd3e52d8f0a9162e92f1a5570db.zip
gcc-0045e0bc3ceacdd3e52d8f0a9162e92f1a5570db.tar.gz
gcc-0045e0bc3ceacdd3e52d8f0a9162e92f1a5570db.tar.bz2
decl.c (expand_static_init): When building an anonymous function for use with atexit...
* decl.c (expand_static_init): When building an anonymous function for use with atexit, compute its body before and after entering the function. * error.c (dump_expr): Handle BIND_EXPR, LOOP_EXPR, and EXIT_EXPR. From-SVN: r27612
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/decl.c24
-rw-r--r--gcc/cp/error.c18
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/cleanup3.C17
4 files changed, 66 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b671eb3..eca9572 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+1999-06-19 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (expand_static_init): When building an anonymous function
+ for use with atexit, compute its body before and after entering
+ the function.
+
+ * error.c (dump_expr): Handle BIND_EXPR, LOOP_EXPR, and
+ EXIT_EXPR.
+
1999-06-18 Mark Mitchell <mark@codesourcery.com>
* init.c (expand_aggr_vbase_init): Add flag parameter.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 1fc4525..0a4d539 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8509,6 +8509,8 @@ expand_static_init (decl, init)
{
tree cleanup, fcall;
static tree Atexit = 0;
+ int saved_flag_access_control;
+
if (Atexit == 0)
{
tree atexit_fndecl, PFV, pfvlist;
@@ -8540,13 +8542,31 @@ expand_static_init (decl, init)
so that any access checks will be done relative to the
current scope, rather than the scope of the anonymous
function. */
- fcall = build_cleanup (decl);
+ build_cleanup (decl);
+
+ /* Now start the function. */
cleanup = start_anon_func ();
+
+ /* Now, recompute the cleanup. It may contain SAVE_EXPRs
+ that refer to the original function, rather than the
+ anonymous one. That will make the back-end think that
+ nested functions are in use, which causes confusion. */
+ saved_flag_access_control = flag_access_control;
+ flag_access_control = 0;
+ fcall = build_cleanup (decl);
+ flag_access_control = saved_flag_access_control;
+
+ /* Finish off the function. */
expand_expr_stmt (fcall);
end_anon_func ();
+
+ /* Call atexit with the cleanup function. */
mark_addressable (cleanup);
cleanup = build_unary_op (ADDR_EXPR, cleanup, 0);
- fcall = build_function_call (Atexit, expr_tree_cons (NULL_TREE, cleanup, NULL_TREE));
+ fcall = build_function_call (Atexit,
+ expr_tree_cons (NULL_TREE,
+ cleanup,
+ NULL_TREE));
expand_expr_stmt (fcall);
}
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index ed316e1..a79420e 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1779,6 +1779,24 @@ dump_expr (t, nop)
dump_decl (t, 0);
break;
+ case BIND_EXPR:
+ OB_PUTS ("{ ");
+ dump_expr (TREE_OPERAND (t, 1), nop);
+ OB_PUTS ("} ");
+ break;
+
+ case LOOP_EXPR:
+ OB_PUTS ("while (1) { ");
+ dump_expr (TREE_OPERAND (t, 0), nop);
+ OB_PUTS ("} ");
+ break;
+
+ case EXIT_EXPR:
+ OB_PUTS ("if (");
+ dump_expr (TREE_OPERAND (t, 0), nop);
+ OB_PUTS (") break; ");
+ break;
+
case TREE_LIST:
if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
{
diff --git a/gcc/testsuite/g++.old-deja/g++.other/cleanup3.C b/gcc/testsuite/g++.old-deja/g++.other/cleanup3.C
new file mode 100644
index 0000000..33d2c4d
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/cleanup3.C
@@ -0,0 +1,17 @@
+// Build don't link:
+// Special g++ Options: -fno-vtable-thunks
+// Origin: Marc Espie <espie@tetto.liafa.jussieu.fr>
+
+struct A {
+ virtual ~A();
+ A();
+};
+
+struct B: public A {
+ B();
+};
+
+void f()
+{
+ static B t[2];
+}