]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
decl.c (expand_static_init): When building an anonymous function for use with atexit...
authorMark Mitchell <mark@codesourcery.com>
Sat, 19 Jun 1999 11:11:43 +0000 (11:11 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sat, 19 Jun 1999 11:11:43 +0000 (11:11 +0000)
* 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

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/error.c
gcc/testsuite/g++.old-deja/g++.other/cleanup3.C [new file with mode: 0644]

index b671eb324adbf923ffc514d5ec16e287a4895c96..eca957246c27fe2dd7226f450b8d1a2e16e15eff 100644 (file)
@@ -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.
index 1fc452551dce4e2287b761f1203931bce8e789c3..0a4d5396bda59eb0d92c1a8f354f8fc0ddbb0788 100644 (file)
@@ -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);
        }
 
index ed316e1dafcdbc24b18bb1bc64b76ccdc33c8c2f..a79420ec77882c76bdf32803a99ce78bab83007e 100644 (file)
@@ -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 (file)
index 0000000..33d2c4d
--- /dev/null
@@ -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];
+}