OSDN Git Service

91th Cygnus<->FSF quick merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 2 May 1997 01:42:58 +0000 (01:42 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 2 May 1997 01:42:58 +0000 (01:42 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14007 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/except.c
gcc/cp/expr.c
gcc/cp/init.c
gcc/cp/lang-options.h
gcc/cp/method.c
gcc/cp/typeck.c

index 2f9b6e2..d4231c1 100644 (file)
@@ -1,3 +1,46 @@
+Thu May  1 18:26:37 1997  Mike Stump  <mrs@cygnus.com>
+
+       * except.c (expand_exception_blocks): Ensure that we flow through
+       the end of the exception region for the exception specification.
+       Move exception region for the exception specification in, so that
+       it doesn't protect the parm cleanup.  Remove some obsolete code.
+       * decl.c (store_parm_decls): Likewise.
+       (finish_function): Likewise.
+
+Tue Apr 29 15:38:54 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * init.c (build_new): Fix nothrow handling.
+
+Tue Apr 29 14:29:50 1997  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * init.c (emit_base_init): Don't warn about the initialization
+       list for an artificial member.
+
+Fri Apr 25 17:47:59 1997  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * expr.c (do_case): Handle !START case for the error msg.
+
+Fri Apr 25 11:55:23 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl2.c, lang-options.h: New option -Weffc++.
+       * class.c, decl.c, init.c, typeck.c: Move Effective C++ warnings
+       to -Weffc++.
+
+       * decl2.c (finish_prevtable_vardecl): Change NO_LINKAGE_HEURISTICS
+       to MULTIPLE_SYMBOL_SPACES.
+
+Wed Apr 23 18:06:50 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * method.c (emit_thunk, generic case): Set current_function_is_thunk.
+
+       * method.c (emit_thunk, macro case): Set up DECL_RESULT.
+
+       * typeck.c (c_expand_return): Don't complain about returning void
+       to void in an artificial function.
+       * method.c (make_thunk): Change settings of READONLY/VOLATILE, 
+       don't set DECL_RESULT, set DECL_ARTIFICIAL.
+       (emit_thunk, generic code): Also set up DECL_LANG_SPECIFIC. 
+
 Wed Apr 23 14:43:06 1997  Mike Stump  <mrs@cygnus.com>
 
        * init.c (init_decl_processing): Add supoprt for setjmp/longjmp based
index b527738..8cddd98 100644 (file)
@@ -3587,7 +3587,7 @@ finish_struct_1 (t, warn_anon)
     }
 
   /* Effective C++ rule 11.  */
-  if (has_pointers && extra_warnings
+  if (has_pointers && warn_ecpp
       && ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
     {
       cp_warning ("`%#T' has pointer data members", t);
index ac00c5b..96dd147 100644 (file)
@@ -238,7 +238,12 @@ extern int warn_nonvdtor;
 
 extern int warn_pmf2ptr;
 
+/* Nonzero means warn about violation of some Effective C++ style rules.  */
+
+extern int warn_ecpp;
+
 /* Non-zero means warn when a function is declared extern and later inline.  */
+
 extern int warn_extern_inline;
 
 /* Nonzero means to treat bitfields as unsigned unless they say `signed'.  */
index 36dc140..749a2f3 100644 (file)
@@ -10137,7 +10137,7 @@ grok_op_properties (decl, virtualp, friendp)
            }
 
          /* More Effective C++ rule 6.  */
-         if (extra_warnings
+         if (warn_ecpp
              && (name == ansi_opname[(int) POSTINCREMENT_EXPR]
                  || name == ansi_opname[(int) POSTDECREMENT_EXPR]))
            {
@@ -10182,7 +10182,7 @@ grok_op_properties (decl, virtualp, friendp)
            }
 
          /* More Effective C++ rule 7.  */
-         if (extra_warnings
+         if (warn_ecpp
              && (name == ansi_opname [TRUTH_ANDIF_EXPR]
                  || name == ansi_opname [TRUTH_ORIF_EXPR]
                  || name == ansi_opname [COMPOUND_EXPR]))
@@ -10191,7 +10191,7 @@ grok_op_properties (decl, virtualp, friendp)
        }
 
       /* Effective C++ rule 23.  */
-      if (extra_warnings
+      if (warn_ecpp
          && list_length (argtypes) == 3
          && (name == ansi_opname [PLUS_EXPR]
              || name == ansi_opname [MINUS_EXPR]
@@ -10499,7 +10499,7 @@ xref_basetypes (code_type_node, name, ref, binfo)
 
          /* Effective C++ rule 14.  The case of virtual functions but
             non-virtual dtor is handled in finish_struct_1.  */
-         if (warn_nonvdtor && ! TYPE_VIRTUAL_P (basetype)
+         if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
              && TYPE_HAS_DESTRUCTOR (basetype))
            cp_warning ("base class `%#T' has a non-virtual destructor",
                        basetype);
@@ -11030,7 +11030,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
     warning ("return-type defaults to `int'");
 
   /* Effective C++ rule 15.  See also c_expand_return.  */
-  if (extra_warnings
+  if (warn_ecpp
       && DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR]
       && TREE_TYPE (fntype) == void_type_node)
     cp_warning ("`operator=' should return a reference to `*this'");
@@ -11379,10 +11379,22 @@ store_parm_decls ()
   if (! processing_template_decl)
     expand_function_start (fndecl, parms_have_cleanups);
 
+  current_function_parms_stored = 1;
+
+  /* If this function is `main', emit a call to `__main'
+     to run global initializers, etc.  */
+  if (DECL_NAME (fndecl)
+      && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4
+      && strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0
+      && DECL_CONTEXT (fndecl) == NULL_TREE)
+    {
+      expand_main_function ();
+    }
+
   /* Now that we have initialized the parms, we can start their
      cleanups.  We cannot do this before, since expand_decl_cleanup
      should not be called before the parm can be used.  */
-  if (parms_have_cleanups
+  if (cleanups
       && ! processing_template_decl)      
     {
       for (cleanups = nreverse (cleanups); cleanups; cleanups = TREE_CHAIN (cleanups))
@@ -11402,41 +11414,13 @@ store_parm_decls ()
       expand_start_bindings (0);
     }
 
-  current_function_parms_stored = 1;
-
-  /* If this function is `main', emit a call to `__main'
-     to run global initializers, etc.  */
-  if (DECL_NAME (fndecl)
-      && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4
-      && strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0
-      && DECL_CONTEXT (fndecl) == NULL_TREE)
-    {
-      expand_main_function ();
-    }
-
-  /* Take care of exception handling things. */
   if (! processing_template_decl && flag_exceptions)
     {
-      rtx insns;
-      start_sequence ();
-
-#if 0
-      /* Mark the start of a stack unwinder if we need one.  */
-      start_eh_unwinder ();
-#endif
-
-#if 0
       /* Do the starting of the exception specifications, if we have any.  */
       if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
        expand_start_eh_spec ();
-#endif
-
-      insns = get_insns ();
-      end_sequence ();
-
-      if (insns)
-       store_after_parms (insns);
     }
+
   last_dtor_insn = get_last_insn ();
 }
 
@@ -11881,6 +11865,9 @@ finish_function (lineno, call_poplevel, nested)
               && ! DECL_NAME (DECL_RESULT (current_function_decl)))
        no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
 
+      if (flag_exceptions)
+       expand_exception_blocks ();
+
       /* If this function is supposed to return a value, ensure that
         we do not fall into the cleanups by mistake.  The end of our
         function will look like this:
@@ -11913,11 +11900,10 @@ finish_function (lineno, call_poplevel, nested)
             to catch cleanup-generated temporaries.  */
          expand_end_bindings (0, 0, 0);
          poplevel (0, 0, 0);
-       }
 
-      if (cleanup_label)
-       /* Emit label at beginning of cleanup code for parameters.  */
-       emit_label (cleanup_label);
+         /* Emit label at beginning of cleanup code for parameters.  */
+         emit_label (cleanup_label);
+       }
 
       /* Get return value into register if that's where it's supposed to be.  */
       if (original_result_rtx)
@@ -11937,9 +11923,6 @@ finish_function (lineno, call_poplevel, nested)
 
       /* Generate rtl for function exit.  */
       expand_function_end (input_filename, lineno, 1);
-
-      if (flag_exceptions)
-       expand_exception_blocks ();
     }
 
   /* This must come after expand_function_end because cleanups might
index 1e8577a..f7e2064 100644 (file)
@@ -244,6 +244,10 @@ int warn_synth;
    into a pointer to (void or function).  */
 int warn_pmf2ptr = 1;
 
+/* Nonzero means warn about violation of some Effective C++ style rules.  */
+
+int warn_ecpp = 0;
+
 /* Nonzero means `$' can be in an identifier.
    See cccp.c for reasons why this breaks some obscure ANSI C programs.  */
 
@@ -579,6 +583,8 @@ lang_decode_option (p)
        warn_synth = setting;
       else if (!strcmp (p, "pmf-conversions"))
        warn_pmf2ptr = setting;
+      else if (!strcmp (p, "effc++"))
+       warn_ecpp = setting;
       else if (!strcmp (p, "comment"))
        ;                       /* cpp handles this one.  */
       else if (!strcmp (p, "comments"))
@@ -2413,7 +2419,7 @@ finish_prevtable_vardecl (prev, vars)
   tree ctype = DECL_CONTEXT (vars);
   import_export_template (ctype);
 
-#ifndef NO_LINKAGE_HEURISTICS
+#ifndef MULTIPLE_SYMBOL_SPACES
   if (CLASSTYPE_INTERFACE_UNKNOWN (ctype) && TYPE_VIRTUAL_P (ctype)
       && ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
     {
index efe9762..45994ce 100644 (file)
@@ -917,13 +917,11 @@ void
 expand_exception_blocks ()
 {
   rtx funcend;
-  rtx insn, insns;
-  rtx eh_spec_insns = NULL_RTX;
+  rtx insns;
 
   start_sequence ();
 
   funcend = gen_label_rtx ();
-  emit_jump (funcend);
 
   start_sequence ();
 
@@ -935,32 +933,26 @@ expand_exception_blocks ()
 
   insns = get_insns ();
   end_sequence ();
-  
-  /* Do this after we expand leftover cleanups, so that the expand_eh_region_end
-     that expand_end_eh_spec does will match the right expand_eh_region_start,
-     and make sure it comes out before the terminate protected region.  */
+
+#if 1
+  /* Do this after we expand leftover cleanups, so that the
+     expand_eh_region_end that expand_end_eh_spec does will match the
+     right expand_eh_region_start, and make sure it comes out before
+     the terminate protected region.  */
   if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
     {
-#if 1
-      {
-       rtx insns;
-       /* New...  */
-       start_sequence ();
-       expand_start_eh_spec ();
-       eh_spec_insns = get_insns ();
-       end_sequence ();
-      }
-#endif
-
-      expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)));
-      push_to_sequence (insns);
+     expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)));
+     push_to_sequence (insns);
 
-      /* Now expand any new ones.  */
-      expand_leftover_cleanups ();
+     /* Now expand any new ones.  */
+     expand_leftover_cleanups ();
 
-      insns = get_insns ();
-      end_sequence ();
+     insns = get_insns ();
+     end_sequence ();
     }
+#endif
+
+  emit_jump (funcend);
 
   if (insns)
     {
@@ -983,22 +975,6 @@ expand_exception_blocks ()
       expand_leftover_cleanups ();
     }
 
-  {
-    /* Mark the end of the stack unwinder.  */
-    rtx unwind_insns;
-    start_sequence ();
-#if 0
-    end_eh_unwinder ();
-#endif
-    unwind_insns = get_insns ();
-    end_sequence ();
-    if (unwind_insns)
-      {
-       insns = unwind_insns;
-       emit_insns (insns);
-      }
-  }
-
   emit_label (funcend);
 
   /* Only if we had previous insns do we want to emit the jump around
@@ -1007,22 +983,7 @@ expand_exception_blocks ()
     insns = get_insns ();
   end_sequence ();
 
-#if 1
-  if (eh_spec_insns)
-    emit_insns_after (eh_spec_insns, get_insns ());
-#else
-  if (eh_spec_insns)
-    store_after_parms (eh_spec_insns);
-#endif
-
-  insn = get_last_insn ();
-  while (GET_CODE (insn) == NOTE
-        || (GET_CODE (insn) == INSN
-            && (GET_CODE (PATTERN (insn)) == USE
-                || GET_CODE (PATTERN (insn)) == CLOBBER)))
-    insn = PREV_INSN (insn);
-    
-  emit_insns_after (insns, insn);
+  emit_insns (insns);
 }
 
 tree
index 118db30..9beee28 100644 (file)
@@ -444,6 +444,8 @@ do_case (start, end)
        {
          if (end)
            error ("case label within scope of cleanup or variable array");
+         else if (! start)
+           error ("`default' label within scope of cleanup or variable array");
          else
            cp_error ("case label `%E' within scope of cleanup or variable array", start);
        }
index 332679d..662434e 100644 (file)
@@ -647,7 +647,8 @@ emit_base_init (t, immediately)
          from_init_list = 0;
 
          /* Effective C++ rule 12.  */
-         if (extra_warnings && init == NULL_TREE
+         if (warn_ecpp && init == NULL_TREE
+             && !DECL_ARTIFICIAL (member)
              && TREE_CODE (TREE_TYPE (member)) != ARRAY_TYPE)
            cp_warning ("`%D' should be initialized in the member initialization list", member);            
        }
@@ -1895,7 +1896,6 @@ build_offset_ref (type, name)
          tree access;
 
          /* unique functions are handled easily.  */
-       unique:
          access = compute_access (basebinfo, t);
          if (access == access_protected_node)
            {
@@ -2415,10 +2415,12 @@ build_new (placement, decl, init, use_global_new)
       return error_mark_node;
     }
 
-  nothrow = (placement
-            && TREE_TYPE (placement)
-            && IS_AGGR_TYPE (TREE_TYPE (placement))
-            && (TYPE_IDENTIFIER (TREE_TYPE (placement))
+  /* If the first placement arg is of type nothrow_t, it's allowed to
+     return 0 on allocation failure.  */
+  nothrow = (placement && TREE_VALUE (placement)
+            && TREE_TYPE (TREE_VALUE (placement))
+            && IS_AGGR_TYPE (TREE_TYPE (TREE_VALUE (placement)))
+            && (TYPE_IDENTIFIER (TREE_TYPE (TREE_VALUE (placement)))
                 == get_identifier ("nothrow_t")));
 
   check_new = flag_check_new || nothrow;
@@ -3152,11 +3154,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
      int flags;
      int use_global_delete;
 {
-  tree function;
   tree member;
   tree expr;
   tree ref;
-  int ptr;
 
   if (addr == error_mark_node)
     return error_mark_node;
@@ -3190,7 +3190,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
       /* throw away const and volatile on target type of addr */
       addr = convert_force (build_pointer_type (type), addr, 0);
       ref = build_indirect_ref (addr, NULL_PTR);
-      ptr = 1;
     }
   else if (TREE_CODE (type) == ARRAY_TYPE)
     {
@@ -3221,7 +3220,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
        addr = convert_force (build_pointer_type (type), addr, 0);
 
       ref = build_indirect_ref (addr, NULL_PTR);
-      ptr = 0;
     }
 
   my_friendly_assert (IS_AGGR_TYPE (type), 220);
@@ -3250,12 +3248,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
      of the base classes; otherwise, we must do that here.  */
   if (TYPE_HAS_DESTRUCTOR (type))
     {
-      tree parms = build_tree_list (NULL_TREE, addr);
-      tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1));
       tree passed_auto_delete;
       tree do_delete = NULL_TREE;
       tree ifexp;
-      int nonnull;
 
       if (use_global_delete)
        {
index f2014c6..707282d 100644 (file)
@@ -102,3 +102,5 @@ Boston, MA 02111-1307, USA.  */
   "-Wno-synth",
   "-Wpmf-conversions",
   "-Wno-pmf-conversions",
+  "-Weffc++",
+  "-Wno-effc++",
index 358e24a..cf26ab1 100644 (file)
@@ -1698,30 +1698,29 @@ make_thunk (function, delta)
     }
   if (thunk == NULL_TREE)
     {
-      thunk = build_lang_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl));
-      DECL_RESULT (thunk)
-       = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (vtable_entry_type)));
-      TREE_READONLY (thunk) = TYPE_READONLY (TREE_TYPE (vtable_entry_type));
-      TREE_THIS_VOLATILE (thunk) = TYPE_VOLATILE (TREE_TYPE (vtable_entry_type));
-      make_function_rtl (thunk);
+      thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl));
+      TREE_READONLY (thunk) = TREE_READONLY (func_decl);
+      TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (func_decl);
       comdat_linkage (thunk);
       TREE_SET_CODE (thunk, THUNK_DECL);
       DECL_INITIAL (thunk) = function;
       THUNK_DELTA (thunk) = delta;
       DECL_EXTERNAL (thunk) = 1;
+      DECL_ARTIFICIAL (thunk) = 1;
       /* So that finish_file can write out any thunks that need to be: */
       pushdecl_top_level (thunk);
     }
   return thunk;
 }
 
+/* Emit the definition of a C++ multiple inheritance vtable thunk.  */
+
 void
 emit_thunk (thunk_fndecl)
      tree thunk_fndecl;
 {
   tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0);
   int delta = THUNK_DELTA (thunk_fndecl);
-  char *fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
 
   if (TREE_ASM_WRITTEN (thunk_fndecl))
     return;
@@ -1736,21 +1735,31 @@ emit_thunk (thunk_fndecl)
 
   TREE_SET_CODE (thunk_fndecl, FUNCTION_DECL);
 
+  {
 #ifdef ASM_OUTPUT_MI_THUNK
-  current_function_decl = thunk_fndecl;
-  temporary_allocation ();
-  assemble_start_function (thunk_fndecl, fnname);
-  ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function);
-  assemble_end_function (thunk_fndecl, fnname);
-  permanent_allocation (1);
-  current_function_decl = 0;
+    char *fnname;
+    current_function_decl = thunk_fndecl;
+    temporary_allocation ();
+    DECL_RESULT (thunk_fndecl)
+      = build_decl (RESULT_DECL, 0, integer_type_node);
+    make_function_rtl (thunk_fndecl);
+    fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
+    assemble_start_function (thunk_fndecl, fnname);
+    ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function);
+    assemble_end_function (thunk_fndecl, fnname);
+    permanent_allocation (1);
+    current_function_decl = 0;
 #else /* ASM_OUTPUT_MI_THUNK */
-  if (varargs_function_p (function))
-    cp_error ("generic thunk code does not work for variadic function `%#D'",
-             function);
-  {
+  /* If we don't have the necessary macro for efficient thunks, generate a
+     thunk function that just makes a call to the real function.
+     Unfortunately, this doesn't work for varargs.  */
+
     tree a, t;
 
+    if (varargs_function_p (function))
+      cp_error ("generic thunk code fails for method `%#D' which uses `...'",
+               function);
+
     /* Set up clone argument trees for the thunk.  */
     t = NULL_TREE;
     for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a))
@@ -1763,9 +1772,14 @@ emit_thunk (thunk_fndecl)
     a = nreverse (t);
     DECL_ARGUMENTS (thunk_fndecl) = a;
     DECL_RESULT (thunk_fndecl) = NULL_TREE;
+    DECL_LANG_SPECIFIC (thunk_fndecl) = DECL_LANG_SPECIFIC (function);
+    copy_lang_decl (thunk_fndecl);
+    DECL_INTERFACE_KNOWN (thunk_fndecl) = 1;
+    DECL_NOT_REALLY_EXTERN (thunk_fndecl) = 1;
 
     start_function (NULL_TREE, thunk_fndecl, NULL_TREE, 1);
     store_parm_decls ();
+    current_function_is_thunk = 1;
 
     /* Build up the call to the real function.  */
     t = build_int_2 (delta, -1 * (delta < 0));
@@ -1779,8 +1793,8 @@ emit_thunk (thunk_fndecl)
     c_expand_return (t);
 
     finish_function (lineno, 0, 0);
-  }
 #endif /* ASM_OUTPUT_MI_THUNK */
+  }
 
   TREE_SET_CODE (thunk_fndecl, THUNK_DECL);
 }
index 97b6fba..4aee8a6 100644 (file)
@@ -7105,7 +7105,7 @@ c_expand_return (retval)
     }
 
   /* Effective C++ rule 15.  See also start_function.  */
-  if (extra_warnings
+  if (warn_ecpp
       && DECL_NAME (current_function_decl) == ansi_opname[(int) MODIFY_EXPR]
       && retval != current_class_ref)
     cp_warning ("`operator=' should return a reference to `*this'");
@@ -7113,7 +7113,8 @@ c_expand_return (retval)
   if (valtype == NULL_TREE || TREE_CODE (valtype) == VOID_TYPE)
     {
       current_function_returns_null = 1;
-      if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
+      if ((pedantic && ! DECL_ARTIFICIAL (current_function_decl))
+         || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
        pedwarn ("`return' with a value, in function returning void");
       expand_return (retval);
       return;