OSDN Git Service

* cp-tree.def (SCOPE_STMT): Take one operand.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 5 Dec 1999 00:49:26 +0000 (00:49 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 5 Dec 1999 00:49:26 +0000 (00:49 +0000)
* cp-tree.h (SCOPE_STMT_BLOCK): New macro.
(SCOPE_NULLIFIED_P): Redefine.
(SCOPE_NO_CLEANUPS_P): New macro.
(add_scope_stmt): Change prototype.
* decl.c (poplevel): Tidy.  Warn about unused variables here.
Record SCOPE_STMT_BLOCKs.
(finish_function): Keep DECL_INITIAL for functions that might be
inlined.
* ir.texi: Document SCOPE_NO_CLEANUPS_P.
* semantics.c: Include rtl.h.
(add_scope_stmt): Return the new scope statement and, for an
end-of-scope statement, its matching begin statement.  Don't set
SCOPE_NULLIFIED_P.
(do_pushlevel): Simplify, now that we are always
function-at-a-time.
(do_poplevel): Likewise.  Record SCOPE_STMT_BLOCKs.
(expand_stmt): Don't call expand_start_bindings or
expand_end_bindings for a scope with SCOPE_NO_CLEANUPS_P set.
* tree.c (copy_tree_r): Clear SCOPE_STMT_BLOCK rather than setting
SCOPE_NULLIFIED_P.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30779 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/ir.texi
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/testsuite/g++.old-deja/g++.other/goto2.C [new file with mode: 0644]

index fa7e6c8..d67e30d 100644 (file)
@@ -1,5 +1,27 @@
 1999-12-04  Mark Mitchell  <mark@codesourcery.com>
 
+       * cp-tree.def (SCOPE_STMT): Take one operand.
+       * cp-tree.h (SCOPE_STMT_BLOCK): New macro.
+       (SCOPE_NULLIFIED_P): Redefine.
+       (SCOPE_NO_CLEANUPS_P): New macro.
+       (add_scope_stmt): Change prototype.
+       * decl.c (poplevel): Tidy.  Warn about unused variables here.
+       Record SCOPE_STMT_BLOCKs.
+       (finish_function): Keep DECL_INITIAL for functions that might be
+       inlined.
+       * ir.texi: Document SCOPE_NO_CLEANUPS_P.
+       * semantics.c: Include rtl.h.
+       (add_scope_stmt): Return the new scope statement and, for an
+       end-of-scope statement, its matching begin statement.  Don't set
+       SCOPE_NULLIFIED_P.
+       (do_pushlevel): Simplify, now that we are always
+       function-at-a-time.
+       (do_poplevel): Likewise.  Record SCOPE_STMT_BLOCKs.
+       (expand_stmt): Don't call expand_start_bindings or
+       expand_end_bindings for a scope with SCOPE_NO_CLEANUPS_P set.
+       * tree.c (copy_tree_r): Clear SCOPE_STMT_BLOCK rather than setting
+       SCOPE_NULLIFIED_P.
+       
        * decl2.c (pending_statics_used): Make it a macro.
        (saved_inlines_used): Likewise.
        (finish_static_data_member_decl): Use VARRAY_PUSH_TREE.
index 6ccc874..71c1d8d 100644 (file)
@@ -254,8 +254,9 @@ DEFTREECODE (START_CATCH_STMT, "start_catch_stmt", 'e', 0)
    SCOPE_BEGIN_P holds, then this is the start of a scope.  If
    SCOPE_END_P holds, then this is the end of a scope.  If
    SCOPE_NULLIFIED_P holds then there turned out to be no variables in
-   this scope.  */
-DEFTREECODE (SCOPE_STMT, "scope_stmt", 'e', 0)
+   this scope.  The SCOPE_STMT_BLOCK is the BLOCK containing the
+   variables declared in this scope.  */
+DEFTREECODE (SCOPE_STMT, "scope_stmt", 'e', 1)
 DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2)
 DEFTREECODE (CASE_LABEL, "case_label", 'e', 2)
 DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
index f2dc09e..d31a6ce 100644 (file)
@@ -66,7 +66,7 @@ Boston, MA 02111-1307, USA.  */
       (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
       ICS_BAD_FLAG (in _CONV)
       FN_TRY_BLOCK_P (in TRY_BLOCK)
-      SCOPE_NULLIFIED_P (in SCOPE_STMT)
+      SCOPE_NO_CLEANUPS_P (in SCOPE_STMT)
    4: BINFO_NEW_VTABLE_MARKED.
       TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
           or FIELD_DECL).
@@ -2697,6 +2697,10 @@ extern int flag_new_for_scope;
 #define SCOPE_END_P(NODE) \
   (!SCOPE_BEGIN_P (SCOPE_STMT_CHECK (NODE)))
 
+/* The BLOCK containing the declarations contained in this scope.  */
+#define SCOPE_STMT_BLOCK(NODE) \
+  (TREE_OPERAND (SCOPE_STMT_CHECK (NODE), 0))
+
 /* Nonzero if this CTOR_STMT is for the beginning of a constructor.  */
 #define CTOR_BEGIN_P(NODE) \
   (TREE_LANG_FLAG_0 (CTOR_STMT_CHECK (NODE)))
@@ -2707,6 +2711,12 @@ extern int flag_new_for_scope;
 
 /* Nonzero for a SCOPE_STMT if there were no variables in this scope.  */
 #define SCOPE_NULLIFIED_P(NODE) \
+  (SCOPE_STMT_BLOCK ((NODE)) == NULL_TREE)
+
+/* Nonzero for a SCOPE_STMT which represents a lexical scope, but
+   which should be treated as non-existant from the point of view of
+   running cleanup actions.  */
+#define SCOPE_NO_CLEANUPS_P(NODE) \
   (TREE_LANG_FLAG_3 (SCOPE_STMT_CHECK (NODE)))
 
 /* Nonzero for a SCOPE_STMT if this statement is for a partial scope.
@@ -3969,7 +3979,7 @@ extern void expand_body                         PROTO((tree));
 extern void begin_stmt_tree                     PROTO((tree *));
 extern void finish_stmt_tree                    PROTO((tree *));
 extern void prep_stmt                           PROTO((tree));
-extern void add_scope_stmt                      PROTO((int, int));
+extern tree add_scope_stmt                      PROTO((int, int));
 extern void do_pushlevel                        PROTO((void));
 extern tree do_poplevel                         PROTO((void));
 /* Non-zero if we are presently building a statement tree, rather
index deea199..2091557 100644 (file)
@@ -1170,7 +1170,6 @@ poplevel (keep, reverse, functionbody)
 
   /* Output any nested inline functions within this block
      if they weren't already output.  */
-
   for (decl = decls; decl; decl = TREE_CHAIN (decl))
     if (TREE_CODE (decl) == FUNCTION_DECL
        && ! TREE_ASM_WRITTEN (decl)
@@ -1191,10 +1190,17 @@ poplevel (keep, reverse, functionbody)
          }
       }
 
+  /* When not in function-at-a-time mode, expand_end_bindings will
+     warn about unused variables.  But, in function-at-a-time mode
+     expand_end_bindings is not passed the list of variables in the
+     current scope, and therefore no warning is emitted.  So, we
+     explicitly warn here.  */
+  if (!processing_template_decl)
+    warn_about_unused_variables (getdecls ());
+
   /* If there were any declarations or structure tags in that level,
      or if this level is a function body,
      create a BLOCK to record them for the life of this function.  */
-
   block = NULL_TREE;
   block_previously_created = (current_binding_level->this_block != NULL_TREE);
   if (block_previously_created)
@@ -1227,7 +1233,6 @@ poplevel (keep, reverse, functionbody)
     }
 
   /* In each subblock, record that this is its superior.  */
-
   if (keep >= 0)
     for (link = subblocks; link; link = TREE_CHAIN (link))
       BLOCK_SUPERCONTEXT (link) = block;
@@ -1406,23 +1411,28 @@ poplevel (keep, reverse, functionbody)
     current_binding_level->blocks
       = chainon (current_binding_level->blocks, subblocks);
 
+  /* Each and every BLOCK node created here in `poplevel' is important
+     (e.g. for proper debugging information) so if we created one
+     earlier, mark it as "used".  */
+  if (block)
+    TREE_USED (block) = 1;
+
   /* Take care of compiler's internal binding structures.  */
   if (tmp == 2)
     {
-      add_scope_stmt (/*begin_p=*/0, /*partial_p=*/1);
-      /* Each and every BLOCK node created here in `poplevel' is important
-        (e.g. for proper debugging information) so if we created one
-        earlier, mark it as "used".  */
+      tree scope_stmts;
+
+      scope_stmts 
+       = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/1);
       if (block)
-       TREE_USED (block) = 1;
+       {
+         SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
+         SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
+       }
+
       block = poplevel (keep, reverse, functionbody);
     }
 
-  /* Each and every BLOCK node created here in `poplevel' is important
-     (e.g. for proper debugging information) so if we created one
-     earlier, mark it as "used".  */
-  if (block)
-    TREE_USED (block) = 1;
   return block;
 }
 
@@ -13777,7 +13787,8 @@ finish_function (lineno, flags)
 
   --function_depth;
 
-  if (!DECL_SAVED_INSNS (fndecl) && !DECL_SAVED_FUNCTION_DATA (fndecl))
+  if (!DECL_SAVED_INSNS (fndecl) && !DECL_SAVED_FUNCTION_DATA (fndecl)
+      && !(flag_inline_trees && DECL_INLINE (fndecl)))
     {
       tree t;
 
index b2e6a49..cb6e138 100644 (file)
@@ -1374,9 +1374,9 @@ A scope-statement represents the beginning or end of a scope.  If
 scope; if @code{SCOPE_END_P} holds this statement represents the end of
 a scope.  On exit from a scope, all cleanups from @code{CLEANUP_STMT}s
 occurring in the scope must be run, in reverse order to the order in
-which they were encountered.  If @code{SCOPE_NULLIFIED_P} holds of the
-scope, back-ends should behave as if the @code{SCOPE_STMT} were not
-present at all.
+which they were encountered.  If @code{SCOPE_NULLIFIED_P} or
+@code{SCOPE_NO_CLEANUPS_P} holds of the scope, back-ends should behave
+as if the @code{SCOPE_STMT} were not present at all.
 
 @item START_CATCH_STMT
 
index fa69540..028279f 100644 (file)
@@ -33,6 +33,7 @@
 #include "toplev.h"
 #include "flags.h"
 #include "ggc.h"
+#include "rtl.h"
 
 /* There routines provide a modular interface to perform many parsing
    operations.  They may therefore be used during actual parsing, or
@@ -1264,38 +1265,44 @@ setup_vtbl_ptr ()
 /* Add a scope-statement to the statement-tree.  BEGIN_P indicates
    whether this statements opens or closes a scope.  PARTIAL_P is true
    for a partial scope, i.e, the scope that begins after a label when
-   an object that needs a cleanup is created.  */
+   an object that needs a cleanup is created.  If BEGIN_P is nonzero,
+   returns a new TREE_LIST representing the top of the SCOPE_STMT
+   stack.  The TREE_PURPOSE is the new SCOPE_STMT.  If BEGIN_P is
+   zero, returns a TREE_LIST whose TREE_VALUE is the new SCOPE_STMT,
+   and whose TREE_PURPOSE is the matching SCOPE_STMT iwth
+   SCOPE_BEGIN_P set.  */
 
-void
+tree
 add_scope_stmt (begin_p, partial_p)
      int begin_p;
      int partial_p;
 {
   tree ss;
+  tree top;
 
   /* Build the statement.  */
-  ss = build_min_nt (SCOPE_STMT);
+  ss = build_min_nt (SCOPE_STMT, NULL_TREE);
   SCOPE_BEGIN_P (ss) = begin_p;
   SCOPE_PARTIAL_P (ss) = partial_p;
 
-  /* If we're finishing a scope, figure out whether the scope was
-     really necessary.  */
-  if (!begin_p)
-    {
-      SCOPE_NULLIFIED_P (ss) = !kept_level_p ();
-      SCOPE_NULLIFIED_P (TREE_VALUE (current_scope_stmt_stack))
-       = SCOPE_NULLIFIED_P (ss);
-    }
-
   /* Keep the scope stack up to date.  */
   if (begin_p)
-    current_scope_stmt_stack 
-      = tree_cons (NULL_TREE, ss, current_scope_stmt_stack);
+    {
+      current_scope_stmt_stack 
+       = tree_cons (ss, NULL_TREE, current_scope_stmt_stack);
+      top = current_scope_stmt_stack;
+    }
   else
-    current_scope_stmt_stack = TREE_CHAIN (current_scope_stmt_stack);
+    {
+      top = current_scope_stmt_stack;
+      TREE_VALUE (top) = ss;
+      current_scope_stmt_stack = TREE_CHAIN (top);
+    }
 
   /* Add the new statement to the statement-tree.  */
   add_tree (ss);
+
+  return top;
 }
 
 /* Begin a new scope.  */
@@ -1313,8 +1320,9 @@ do_pushlevel ()
       pushlevel (0);
       if (!building_stmt_tree ()
          && !current_function->x_whole_function_mode_p)
-       expand_start_bindings (0);
-      else if (building_stmt_tree () && !processing_template_decl)
+       my_friendly_abort (19991129);
+
+      if (building_stmt_tree () && !processing_template_decl)
        add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
     }
 }
@@ -1324,28 +1332,27 @@ do_pushlevel ()
 tree
 do_poplevel ()
 {
-  tree t = NULL_TREE;
+  tree block = NULL_TREE;
 
   if (stmts_are_full_exprs_p)
     {
-      if (!building_stmt_tree ()
-         && !current_function->x_whole_function_mode_p)
-       expand_end_bindings (getdecls (), kept_level_p (), 0);
-      else if (building_stmt_tree () && !processing_template_decl)
+      tree scope_stmts;
+      int keep = kept_level_p ();
+
+      if (building_stmt_tree () && !processing_template_decl)
+       scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
+      else
+       scope_stmts = NULL_TREE;
+
+      block = poplevel (kept_level_p (), 1, 0);
+      if (block && !processing_template_decl)
        {
-         add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
-
-         /* When not in function-at-a-time mode, expand_end_bindings
-            will warn about unused variables.  But, in
-            function-at-a-time mode expand_end_bindings is not passed
-            the list of variables in the current scope, and therefore
-            no warning is emitted.  So, we explicitly warn here.  */
-         warn_about_unused_variables (getdecls ());
+         SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
+         SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
        }
-
-      t = poplevel (kept_level_p (), 1, 0);
     }
-  return t;
+
+  return block;
 }
 
 /* Finish a parenthesized expression EXPR.  */
@@ -2473,11 +2480,19 @@ expand_stmt (t)
          break;
 
        case SCOPE_STMT:
-         if (SCOPE_BEGIN_P (t))
-           expand_start_bindings (2 * SCOPE_NULLIFIED_P (t));
-         else if (SCOPE_END_P (t))
-           expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 
-                                SCOPE_PARTIAL_P (t));
+         if (!SCOPE_NO_CLEANUPS_P (t))
+           {
+             if (SCOPE_BEGIN_P (t))
+               expand_start_bindings (2 * SCOPE_NULLIFIED_P (t));
+             else if (SCOPE_END_P (t))
+               expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 
+                                    SCOPE_PARTIAL_P (t));
+           }
+         else if (!SCOPE_NULLIFIED_P (t))
+           emit_note (NULL,
+                      (SCOPE_BEGIN_P (t) 
+                       ? NOTE_INSN_BLOCK_BEG
+                       : NOTE_INSN_BLOCK_END));
          break;
 
        case RETURN_INIT:
index 9796c8f..da15a28 100644 (file)
@@ -1821,7 +1821,7 @@ copy_tree_r (tp, walk_subtrees, data)
       /* For now, we don't update BLOCKs when we make copies.  So, we
         have to nullify all scope-statements.  */
       if (TREE_CODE (*tp) == SCOPE_STMT)
-       SCOPE_NULLIFIED_P (*tp) = 1;
+       SCOPE_STMT_BLOCK (*tp) = NULL_TREE;
     }
   else if (code == TEMPLATE_TEMPLATE_PARM)
     /* These must be copied specially.  */
diff --git a/gcc/testsuite/g++.old-deja/g++.other/goto2.C b/gcc/testsuite/g++.old-deja/g++.other/goto2.C
new file mode 100644 (file)
index 0000000..2b95273
--- /dev/null
@@ -0,0 +1,20 @@
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+// Special g++ Options: -Wunused
+
+struct S
+{
+  S ();
+  ~S ();
+};
+
+void f ()
+{
+  {
+    S s1;
+    int j; // WARNING - unused
+    
+  t:       // WARNING - unused
+    S s2;
+  }
+}