54th Cygnus<->FSF merge
authorMike Stump <mrs@gcc.gnu.org>
Tue, 31 Jan 1995 22:18:02 +0000 (22:18 +0000)
committerMike Stump <mrs@gcc.gnu.org>
Tue, 31 Jan 1995 22:18:02 +0000 (22:18 +0000)
From-SVN: r8844

12 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/input.c
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/typeck2.c

index 9eea3c7..7422a38 100644 (file)
@@ -3,6 +3,128 @@ Wed Jan 25 15:02:09 1995  David S. Miller  (davem@nadzieja.rutgers.edu)
        * class.c (instantiate_type): Change error message text.
        * typeck2.c (store_init_value): Likewise.
 
+Tue Jan 31 13:28:56 1995  Mike Stump  <mrs@cygnus.com>
+
+       * gc.c (get_typeid): Pawn off error messages to build_t_desc.
+       (build_t_desc): Inform the user here if they try and build
+       with -frtti and don't include <typeinfo.h>.
+
+       * decl2.c (finish_prevtable_vardecl): Support rescanning.
+       (finish_file): Move finish_prevtable_vardecl up to before the global
+       initializers are done as tdecls are initialized in the global
+       initializer.  Also Pick up any new tdecls or vtables needed by
+       synthesized methods.
+
+       * class.c (finish_struct): Simplify.  We have to do rtti scanning at
+       end, so we might as well do all of it there.
+
+Tue Jan 31 05:35:02 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * call.c (build_method_call): Fix -fthis-is-variable for 32-bit
+       targets, too.
+
+Tue Jan 31 00:11:04 1995  Mike Stump  <mrs@cygnus.com>
+
+       * decl2.c (finish_prevtable_vardecl): New routine, mostly split from
+       finish_vtable_vardecl.  It has the first half functionality from
+       that routine.
+       * decl2.c (finish_vtable_vardecl): Update to not include stuff not
+       in  finish_prevtable_vardecl.
+       * decl2.c (finish_file): Call finish_prevtable_vardecl.
+       * gc.c (build_generic_desc): Allow it to be called when not at the
+       global binding layer, but behave as if we were.
+       (build_t_desc): Rearrange a bit so that it really works and is
+       easier to follow.
+       * class.c (finish_struct): Don't decide on tdecls here, as we have
+       to wait until the end of the file in general to decide whether or
+       not they come out.
+
+Mon Jan 30 01:00:40 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * init.c (build_delete): Check access to operator delete before
+       calling the destructor.
+       * method.c (build_opfncall, DELETE_EXPR): build_method is allowed to
+       return error_mark_node.
+       * call.c (build_method_call): Use the one-argument op delete even if
+       it's an error.
+
+       * init.c (build_new): Fix -fthis-is-variable support.
+       * call.c (build_method_call): Ditto.
+
+       * call.c (convert_harshness): Make conversion from a pointer to bool
+       worse than conversion to another pointer.
+
+Sat Jan 28 16:46:10 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * init.c (build_new): Check new return value if -fcheck-new.
+
+       * lex.c (check_newline): Clear end_of_file when we're done, too.
+
+Sat Jan 28 10:38:39 1995  Mike Stump  <mrs@cygnus.com>
+
+       * decl2.c (finish_vtable_vardecl): Make rtti TD tables follow
+       vtables whereever they go.
+
+       * gc.c (build_t_desc): Remove old way of setting it up, as it wasn't
+       right.
+
+Sat Jan 28 09:10:44 1995  Mike Stump  <mrs@cygnus.com>
+
+       * decl2.c (finish_vtable_vardecl): Now set the
+       interface/implementation of vtables on the first virtual function,
+       if one exists, otherwise we use the old method.  This is a major win
+       in terms of cutting down the size of objects and executables in
+       terms of text space and data space.  Now most of the savings that
+       #pragma interface/implementation gives is automatic in a fair number
+       of cases.
+
+Sat Jan 28 04:57:33 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * decl.c (grokdeclarator): Discard the template parameters in a
+       template constructor declaration so that the function is always
+       named constructor_name (ctype).
+
+       * lex.c (check_newline): Use ungetc to put back the character before
+       calling HANDLE_PRAGMA.
+
+Fri Jan 27 17:23:47 1995  Mike Stump  <mrs@cygnus.com>
+
+       * decl2.c (check_classfn): If the cname is T<int> and fn_name is T,
+       make sure we still match them.
+
+Fri Jan 27 16:32:10 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * parse.y: Add END_OF_LINE token.
+
+       * lex.c (check_newline): Set linemode when we see a # directive, and
+       unset it when we're done.  Turn all 'return's into 'goto skipline'.
+       Fix all uses of '\n', since we won't see it anymore.  Put back the
+       character we read before checking for a sysv or target pragma.
+       (real_yylex): If we see an EOF in linemode, return END_OF_LINE.
+       (handle_sysv_pragma): Don't look at the input stream; quit when we
+       see an END_OF_LINE token.
+
+       * input.c (getch): Return EOF if we're in line mode and at the end
+       of a line.
+       (put_back): Don't put back an EOF.
+
+Thu Jan 26 19:26:34 1995  Mike Stump  <mrs@cygnus.com>
+
+       * except.c (expand_throw): Do the newing of the exception object
+       before we load the type descriptor or the address so that we don't
+       wipe any of the values out.
+
+Thu Jan 26 19:20:00 1995  Mike Stump  <mrs@cygnus.com>
+
+       * except.c (init_exception_processing): Don't use r12 on the rs6000.
+
+Tue Jan 24 16:36:31 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * decl.c (grokparms): Don't try to build up a reference at this point.
+
+       * typeck2.c (build_functional_cast): Don't assume that a NOP_EXPR
+       will suffice to convert from integer_zero_node.
+
 Mon Jan 23 21:57:14 1995  Mike Stump  <mrs@cygnus.com>
 
        * pt.c (tsubst): When we copy a node, don't forget to copy
index 7a71f40..ee3e8bf 100644 (file)
@@ -309,9 +309,16 @@ convert_harshness (type, parmtype, parm)
 
   if (codel == BOOLEAN_TYPE)
     {
-      if (INTEGRAL_CODE_P (coder) || coder == REAL_TYPE
-         || coder == POINTER_TYPE || coder == OFFSET_TYPE)
+      if (INTEGRAL_CODE_P (coder) || coder == REAL_TYPE)
        return STD_RETURN (h);
+      else if (coder == POINTER_TYPE || coder == OFFSET_TYPE)
+       {
+         /* Make this worse than any conversion to another pointer.
+            FIXME this is how I think the language should work, but it may not
+            end up being how the language is standardized (jason 1/30/95).  */
+         h.distance = 32767;
+         return STD_RETURN (h);
+       }
       return EVIL_RETURN (h);
     }
 
@@ -1547,8 +1554,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
       result = build_method_call (instance, name, parms, basetype_path,
                                  (LOOKUP_SPECULATIVELY|flags)
                                  &~LOOKUP_COMPLAIN);
-      /* If it works, return it. */
-      if (result && result != error_mark_node)
+      /* If it finds a match, return it. */
+      if (result)
        return build_method_call (instance, name, parms, basetype_path, flags);
       /* If it doesn't work, two argument delete must work */
       TREE_CHAIN (parms) = save_last;
@@ -1896,9 +1903,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
        {
          constp = 0;
          volatilep = 0;
-         parms = tree_cons (NULL_TREE,
-                            build1 (NOP_EXPR, TYPE_POINTER_TO (basetype),
-                                    integer_zero_node), parms);
+         instance_ptr = build_int_2 (0, 0);
+         TREE_TYPE (instance_ptr) = TYPE_POINTER_TO (basetype);
+         parms = tree_cons (NULL_TREE, instance_ptr, parms);
        }
       else
        {
index 51bc827..ec624b9 100644 (file)
@@ -4062,47 +4062,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
   TYPE_BEING_DEFINED (t) = 0;
   hack_incomplete_structures (t);
 
-  if (flag_rtti && TYPE_VIRTUAL_P (t) && CLASSTYPE_VTABLE_NEEDS_WRITING (t))
-    {
-      tree variants;
-      tree tdecl, td;
-
-      /* Now instantiate its type descriptors.  */
-      td = build_t_desc (t, 1);
-      if (td == NULL_TREE)
-       {
-         cp_error ("failed to build type descriptor node of '%T', maybe typeinfo.h not included", t);
-         tdecl = NULL_TREE;
-       }
-      else
-        tdecl = TREE_OPERAND (td, 0);
-
-#if 0
-      /* I see no need for building the following TD */
-      variants = TYPE_POINTER_TO (t);
-      build_type_variant (variants, 1, 0);
-      while (variants)
-       {
-         build_t_desc (variants, 1);
-         variants = TYPE_NEXT_VARIANT (variants);
-       }
-#endif
-      variants = build_reference_type (t);
-      build_type_variant (variants, 1, 0);
-      while (variants)
-       {
-         build_t_desc (variants, 1);
-         variants = TYPE_NEXT_VARIANT (variants);
-       }
-      if (tdecl != NULL_TREE)
-        DECL_CONTEXT (tdecl) = t;
-    }
-#if 0
-  /* Still need to instantiate this C struct's type descriptor.  */
-  else if (flag_rtti && ! CLASSTYPE_RTTI (t))
-    build_t_desc (t, 1);
-#endif
-
 #if 0
   if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
     undo_template_name_overload (TYPE_IDENTIFIER (t), 1);
index 2bdb535..1cda932 100644 (file)
@@ -7239,9 +7239,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
              return 0;
            }
          innermost_code = TREE_CODE (decl);
-         decl = TREE_OPERAND (decl, 0);
          if (decl_context == FIELD && ctype == NULL_TREE)
            ctype = current_class_type;
+         if (ctype
+             && TREE_OPERAND (decl, 0) == constructor_name_full (ctype))
+           TREE_OPERAND (decl, 0) = constructor_name (ctype);
+         decl = TREE_OPERAND (decl, 0);
          if (ctype != NULL_TREE
              && decl != NULL_TREE && flags != DTOR_FLAG
              && decl == constructor_name (ctype))
@@ -7335,6 +7338,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                  }
              }
 
+           if (ctype
+               && TREE_OPERAND (decl, 1) == constructor_name_full (ctype))
+             TREE_OPERAND (decl, 1) = constructor_name (ctype);
            decl = TREE_OPERAND (decl, 1);
            if (ctype)
              {
@@ -7346,12 +7352,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
                  }
                else if (TREE_CODE (decl) == BIT_NOT_EXPR
                         && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE
-                        && constructor_name (ctype) == TREE_OPERAND (decl, 0))
+                        && (constructor_name (ctype) == TREE_OPERAND (decl, 0)
+                            || constructor_name_full (ctype) == TREE_OPERAND (decl, 0)))
                  {
                    return_type = return_dtor;
                    ctor_return_type = ctype;
                    flags = DTOR_FLAG;
-                   decl = TREE_OPERAND (decl, 0);
+                   decl = TREE_OPERAND (decl, 0) = constructor_name (ctype);
                  }
              }
          }
@@ -9552,9 +9559,15 @@ grokparms (first_parm, funcdef_flag)
                      else
                        init = require_instantiated_type (type, init, integer_zero_node);
 
-                     init = convert_for_initialization
-                       (NULL_TREE, type, init, LOOKUP_NORMAL,
-                        "argument passing", 0, 0);
+                     /* Don't actually try to build up a reference here.  */
+                     {
+                       tree t = type;
+                       if (TREE_CODE (t) == REFERENCE_TYPE)
+                         t = TREE_TYPE (t);
+                       init = convert_for_initialization
+                         (NULL_TREE, t, init, LOOKUP_NORMAL,
+                          "argument passing", 0, 0);
+                     }
                    }
 #if 0 /* This is too early to check; trailing parms might be merged in by
         duplicate_decls.  */
index ce51b9f..abbcead 100644 (file)
@@ -351,6 +351,11 @@ int flag_access_control = 1;
 
 int flag_operator_names;
 
+/* Nonzero if we want to check the return value of new and avoid calling
+   constructors if it is a null pointer.  */
+
+int flag_check_new;
+
 /* Table of language-dependent -f options.
    STRING is the option name.  VARIABLE is the address of the variable.
    ON_VALUE is the value to store in VARIABLE
@@ -395,7 +400,8 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
   {"access-control", &flag_access_control, 1},
   {"nonansi-builtins", &flag_no_nonansi_builtin, 0},
   {"gnu-keywords", &flag_no_gnu_keywords, 0},
-  {"operator-names", &flag_operator_names, 1}
+  {"operator-names", &flag_operator_names, 1},
+  {"check-new", &flag_check_new, 1}
 };
 
 /* Decode the string P as a language-specific option.
@@ -1154,7 +1160,8 @@ check_classfn (ctype, cname, function)
       end = TREE_VEC_END (method_vec);
 
       /* First suss out ctors and dtors.  */
-      if (*methods && fn_name == cname)
+      if (*methods
+         && (fn_name == cname || fn_name == DECL_NAME (*methods)))
        goto got_it;
 
       while (++methods != end)
@@ -2430,7 +2437,7 @@ mark_vtable_entries (decl)
     }
 }
 
-/* Set TREE_PUBLIC and/or TREE_EXTERN on the vtable DECL,
+/* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL,
    based on TYPE and other static flags.
 
    Note that anything public is tagged TREE_PUBLIC, whether
@@ -2472,14 +2479,14 @@ import_export_template (type)
 }
     
 static void
-finish_vtable_vardecl (prev, vars)
+finish_prevtable_vardecl (prev, vars)
      tree prev, vars;
 {
   tree ctype = DECL_CONTEXT (vars);
   import_export_template (ctype);
   import_export_vtable (vars, ctype);
 
-  if (flag_vtable_thunks && !CLASSTYPE_INTERFACE_KNOWN (ctype))
+  if (CLASSTYPE_INTERFACE_UNKNOWN (ctype))
     {
       tree method;
       for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE;
@@ -2489,6 +2496,7 @@ finish_vtable_vardecl (prev, vars)
              && !DECL_ABSTRACT_VIRTUAL_P (method))
            {
              SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
+             CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method);
              CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method);
              TREE_PUBLIC (vars) = 1;
              DECL_EXTERNAL (vars) = DECL_EXTERNAL (method);
@@ -2502,20 +2510,50 @@ finish_vtable_vardecl (prev, vars)
     {
       extern tree the_null_vtable_entry;
 
-      /* Stuff this virtual function table's size into
-        `pfn' slot of `the_null_vtable_entry'.  */
-#if 0
-      /* we do not put size as first entry any more */
-      tree nelts = array_type_nelts (TREE_TYPE (vars));
-      if (flag_vtable_thunks)
-       TREE_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (vars))) = nelts;
-      else
-       SET_FNADDR_FROM_VTABLE_ENTRY (the_null_vtable_entry, nelts);
-#endif
-
       /* Kick out the type descriptor before writing out the vtable.  */
       if (flag_rtti)
-       rest_of_decl_compilation (TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (vars)))), 0), 0, 1, 1);
+       {
+         build_t_desc (ctype, 1);
+       }
+
+      /* Write it out.  */
+      mark_vtable_entries (vars);
+    }
+}
+    
+static void
+finish_vtable_vardecl (prev, vars)
+     tree prev, vars;
+{
+  tree ctype = DECL_CONTEXT (vars);
+  import_export_template (ctype);
+  import_export_vtable (vars, ctype);
+
+  if (CLASSTYPE_INTERFACE_UNKNOWN (ctype))
+    {
+      tree method;
+      for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE;
+          method = DECL_NEXT_METHOD (method))
+       {
+         if (DECL_VINDEX (method) != NULL_TREE && !DECL_SAVED_INSNS (method)
+             && !DECL_ABSTRACT_VIRTUAL_P (method))
+           {
+             SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
+             CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method);
+             CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method);
+             TREE_PUBLIC (vars) = 1;
+             DECL_EXTERNAL (vars) = DECL_EXTERNAL (method);
+             if (flag_rtti)
+               cp_warning ("compiler error: rtti entry for `%T' decided too late", ctype);
+             break;
+           }
+       }
+    }
+
+  if (write_virtuals >= 0
+      && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars)))
+    {
+      extern tree the_null_vtable_entry;
 
       /* Write it out.  */
       mark_vtable_entries (vars);
@@ -2714,13 +2752,31 @@ finish_file ()
        needs_messing_up |= TYPE_NEEDS_CONSTRUCTING (type);
       vars = TREE_CHAIN (vars);
     }
-  if (needs_cleaning == 0)
-    goto mess_up;
 
   /* Otherwise, GDB can get confused, because in only knows
      about source for LINENO-1 lines.  */
   lineno -= 1;
 
+  interface_unknown = 1;
+  interface_only = 0;
+
+  /* Walk to mark the inline functions we need, then output them so
+     that we can pick up any other tdecls that those routines need. */
+  walk_vtables ((void (*)())0, finish_prevtable_vardecl);
+  for (vars = saved_inlines; vars; vars = TREE_CHAIN (vars))
+    {
+      tree decl = TREE_VALUE (vars);
+
+      if (DECL_ARTIFICIAL (decl)
+         && ! DECL_INITIAL (decl)
+         && (TREE_USED (decl) || ! DECL_EXTERNAL (decl)))
+       synthesize_method (decl);
+    }
+  walk_vtables ((void (*)())0, finish_prevtable_vardecl);
+
+  if (needs_cleaning == 0)
+    goto mess_up;
+
   fnname = get_file_function_name ('D');
   start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0);
   fnname = DECL_ASSEMBLER_NAME (current_function_decl);
@@ -2950,19 +3006,6 @@ finish_file ()
   pushdecl (vars);
 #endif
 
-  interface_unknown = 1;
-  interface_only = 0;
-
-  for (vars = saved_inlines; vars; vars = TREE_CHAIN (vars))
-    {
-      tree decl = TREE_VALUE (vars);
-
-      if (DECL_ARTIFICIAL (decl)
-         && ! DECL_INITIAL (decl)
-         && (TREE_USED (decl) || ! DECL_EXTERNAL (decl)))
-       synthesize_method (decl);
-    }
-
   walk_vtables ((void (*)())0, finish_vtable_vardecl);
   if (flag_handle_signatures)
     walk_sigtables ((void (*)())0, finish_sigtable_vardecl);
index 1490f6f..218818d 100644 (file)
@@ -1528,7 +1528,6 @@ expand_throw (exp)
      exception, so that the matching routine knows to search out.  */
   label = gen_label_rtx ();
   emit_label (label);
-  emit_move_insn (saved_pc, gen_rtx (LABEL_REF, Pmode, label));
 
   if (exp)
     {
@@ -1543,7 +1542,6 @@ expand_throw (exp)
        rtx throw_type_rtx = expand_expr (throw_type, NULL_RTX, VOIDmode, 0);
        rtx throw_value_rtx;
 
-       emit_move_insn (saved_throw_type, throw_type_rtx);
        exp = convert_to_reference (build_reference_type (build_type_variant (TREE_TYPE (exp), 1, 0)), exp, CONV_STATIC, LOOKUP_COMPLAIN, error_mark_node);
 
        /* Make a copy of the thrown object.  WP 15.1.5  */
@@ -1553,6 +1551,7 @@ expand_throw (exp)
          error ("  in thrown expression");
        throw_value_rtx = expand_expr (exp, NULL_RTX, VOIDmode, 0);
        emit_move_insn (saved_throw_value, throw_value_rtx);
+       emit_move_insn (saved_throw_type, throw_type_rtx);
       }
     }
   else
@@ -1561,6 +1560,7 @@ expand_throw (exp)
       /* This part is easy, as we dont' have to do anything else.  */
     }
 
+  emit_move_insn (saved_pc, gen_rtx (LABEL_REF, Pmode, label));
   make_first_label(throw_label);
   emit_jump (throw_label);
 }
index 02469d4..fd8bf2b 100644 (file)
@@ -2787,6 +2787,8 @@ build_builtin_call (type, node, arglist)
 
    PLACEMENT is the `placement' list for user-defined operator new ().  */
 
+extern int flag_check_new;
+
 tree
 build_new (placement, decl, init, use_global_new)
      tree placement;
@@ -2795,6 +2797,7 @@ build_new (placement, decl, init, use_global_new)
 {
   tree type, true_type, size, rval;
   tree nelts;
+  tree alloc_expr;
   int has_array = 0;
   enum tree_code code = NEW_EXPR;
 
@@ -3026,6 +3029,13 @@ build_new (placement, decl, init, use_global_new)
       TREE_CALLS_NEW (rval) = 1;
     }
 
+  if (flag_check_new)
+    {
+      if (rval)
+       rval = save_expr (rval);
+      alloc_expr = rval;
+    }
+
   /* if rval is NULL_TREE I don't have to allocate it, but are we totally
      sure we have some extra bytes in that case for the BI_header_size
      cookies? And how does that interact with the code below? (mrs) */
@@ -3081,7 +3091,7 @@ build_new (placement, decl, init, use_global_new)
       {
        tree tmp = rval;
        
-       if (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE)
+       if (tmp && TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE)
          tmp = build_indirect_ref (tmp, NULL_PTR);
       
        newrval = build_method_call (tmp, constructor_name_full (true_type),
@@ -3176,6 +3186,14 @@ build_new (placement, decl, init, use_global_new)
        }
     }
  done:
+
+  if (flag_check_new && alloc_expr && rval != alloc_expr)
+    {
+      tree ifexp = build_binary_op (NE_EXPR, alloc_expr, integer_zero_node, 1);
+      rval = build_conditional_expr (ifexp, rval, convert (TREE_TYPE (rval),
+                                                          integer_zero_node));
+    }
+
   if (rval && TREE_TYPE (rval) != build_pointer_type (type))
     {
       /* The type of new int [3][3] is not int *, but int [3] * */
@@ -3572,7 +3590,18 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
                                            auto_delete, integer_two_node));
        }
       else
-       passed_auto_delete = auto_delete;
+       {
+         if (TYPE_GETS_REG_DELETE (type))
+           {
+             /* Only do access checking here; we'll be calling op delete
+                 from the destructor.  */
+             tree t = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr,
+                                      size_zero_node, NULL_TREE);
+             if (t == error_mark_node)
+               return error_mark_node;
+           }
+         passed_auto_delete = auto_delete;
+       }
 
       if (flags & LOOKUP_PROTECT)
        {
index 1570489..378521e 100644 (file)
@@ -128,8 +128,8 @@ feed_input (str, len, delete)
 struct pending_input *to_be_restored; /* XXX */
 extern int end_of_file;
 
-int
-getch ()
+static inline int
+sub_getch ()
 {
   if (putback_char != -1)
     {
@@ -172,8 +172,25 @@ void
 put_back (ch)
      int ch;
 {
-  my_friendly_assert (putback_char == -1, 224);
-  putback_char = ch;
+  if (ch != EOF)
+    {
+      my_friendly_assert (putback_char == -1, 224);
+      putback_char = ch;
+    }
+}
+
+extern int linemode;
+
+int
+getch ()
+{
+  int ch = sub_getch ();
+  if (linemode && ch == '\n')
+    {
+      put_back (ch);
+      ch = EOF;
+    }
+  return ch;
 }
 
 inline
index 09424b0..d61de50 100644 (file)
@@ -2319,6 +2319,8 @@ get_last_nonwhite_on_line ()
    If the line is a #-directive, read the entire line and return a newline.
    Otherwise, return the line's first non-whitespace character.  */
 
+int linemode;
+
 int
 check_newline ()
 {
@@ -2340,6 +2342,9 @@ check_newline ()
       return c;
     }
 
+  /* Don't read beyond this line.  */
+  linemode = 1;
+  
   /* Read first nonwhite char after the `#'.  */
 
   do
@@ -2372,7 +2377,7 @@ check_newline ()
                  && getch () == 'b'
                  && getch () == 'l'
                  && getch () == 'e'
-                 && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+                 && ((c = getch ()) == ' ' || c == '\t'))
                {
                  extern tree pending_vtables;
 
@@ -2392,14 +2397,14 @@ check_newline ()
                  if (nextchar < 0)
                    nextchar = getch ();
                  c = nextchar;
-                 if (c != '\n')
+                 if (c != EOF)
                    warning ("trailing characters ignored");
                }
              else if (c == 'u'
                       && getch () == 'n'
                       && getch () == 'i'
                       && getch () == 't'
-                      && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+                      && ((c = getch ()) == ' ' || c == '\t'))
                {
                  /* More follows: it must be a string constant (unit name).  */
                  token = real_yylex ();
@@ -2413,7 +2418,7 @@ check_newline ()
                  if (nextchar < 0)
                    nextchar = getch ();
                  c = nextchar;
-                 if (c != '\n')
+                 if (c != EOF)
                    warning ("trailing characters ignored");
                }
              else if (c == 'i')
@@ -2429,7 +2434,7 @@ check_newline ()
                      && getch () == 'a'
                      && getch () == 'c'
                      && getch () == 'e'
-                     && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+                     && ((c = getch ()) == ' ' || c == '\t' || c == EOF))
                    {
                      int warned_already = 0;
                      char *main_filename = input_filename;
@@ -2437,7 +2442,7 @@ check_newline ()
                      main_filename = FILE_NAME_NONDIRECTORY (main_filename);
                      while (c == ' ' || c == '\t')
                        c = getch ();
-                     if (c != '\n')
+                     if (c != EOF)
                        {
                          put_back (c);
                          token = real_yylex ();
@@ -2455,10 +2460,10 @@ check_newline ()
                      while (c == ' ' || c == '\t')
                        c = getch ();
 
-                     while (c != '\n')
+                     while (c != EOF)
                        {
                          if (!warned_already && extra_warnings
-                             && c != ' ' && c != '\t' && c != '\n')
+                             && c != ' ' && c != '\t')
                            {
                              warning ("garbage after `#pragma interface' ignored");
                              warned_already = 1;
@@ -2506,7 +2511,7 @@ check_newline ()
                           && getch () == 'i'
                           && getch () == 'o'
                           && getch () == 'n'
-                          && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+                          && ((c = getch ()) == ' ' || c == '\t' || c == EOF))
                    {
                      int warned_already = 0;
                      char *main_filename = main_input_filename ? main_input_filename : input_filename;
@@ -2514,7 +2519,7 @@ check_newline ()
                      main_filename = FILE_NAME_NONDIRECTORY (main_filename);
                      while (c == ' ' || c == '\t')
                        c = getch ();
-                     if (c != '\n')
+                     if (c != EOF)
                        {
                          put_back (c);
                          token = real_yylex ();
@@ -2532,10 +2537,10 @@ check_newline ()
                      while (c == ' ' || c == '\t')
                        c = getch ();
 
-                     while (c != '\n')
+                     while (c != EOF)
                        {
                          if (!warned_already && extra_warnings
-                             && c != ' ' && c != '\t' && c != '\n')
+                             && c != ' ' && c != '\t')
                            {
                              warning ("garbage after `#pragma implementation' ignored");
                              warned_already = 1;
@@ -2591,11 +2596,19 @@ check_newline ()
                }
 #ifdef HANDLE_SYSV_PRAGMA
              else
-               return handle_sysv_pragma (finput, c);
+               {
+                 put_back (c);
+                 handle_sysv_pragma ();
+               }
 #else
 #ifdef HANDLE_PRAGMA
+             /* FIXME: This will break if we're doing any of the C++ input
+                 tricks.  */
              else
-               HANDLE_PRAGMA (finput);
+               {
+                 ungetc (c, finput);
+                 HANDLE_PRAGMA (finput);
+               }
 #endif
 #endif
            }
@@ -2608,7 +2621,7 @@ check_newline ()
              && getch () == 'i'
              && getch () == 'n'
              && getch () == 'e'
-             && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+             && ((c = getch ()) == ' ' || c == '\t'))
            {
 #ifdef DWARF_DEBUGGING_INFO
              if ((debug_info_level == DINFO_LEVEL_VERBOSE)
@@ -2624,7 +2637,7 @@ check_newline ()
              && getch () == 'd'
              && getch () == 'e'
              && getch () == 'f'
-             && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+             && ((c = getch ()) == ' ' || c == '\t'))
            {
 #ifdef DWARF_DEBUGGING_INFO
              if ((debug_info_level == DINFO_LEVEL_VERBOSE)
@@ -2662,8 +2675,8 @@ check_newline ()
                c = getch ();
 
              /* If no argument, ignore the line.  */
-             if (c == '\n')
-               return c;
+             if (c == EOF)
+               goto skipline;
 
              put_back (c);
              token = real_yylex ();
@@ -2715,8 +2728,8 @@ linenum:
 
   /* If the # is the only nonwhite char on the line,
      just ignore it.  Check the new newline.  */
-  if (c == '\n')
-    return c;
+  if (c == EOF)
+    goto skipline;
 
   /* Something follows the #; read a token.  */
 
@@ -2736,11 +2749,11 @@ linenum:
 
       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
       c = get_last_nonwhite_on_line ();
-      if (c == '\n')
+      if (c == EOF)
        {
          /* No more: store the line number and check following line.  */
          lineno = l;
-         return c;
+         goto skipline;
        }
       put_back (c);
 
@@ -2799,7 +2812,7 @@ linenum:
       extract_interface_info ();
 
       c = get_last_nonwhite_on_line ();
-      if (c != '\n')
+      if (c != EOF)
        {
          put_back (c);
 
@@ -2819,7 +2832,7 @@ linenum:
              if (action)
                {
                  c = get_last_nonwhite_on_line ();
-                 if (c != '\n')
+                 if (c != EOF)
                    {
                      put_back (c);
                      token = real_yylex ();
@@ -2836,7 +2849,7 @@ linenum:
              entering_system_header = 1;
 
              c = get_last_nonwhite_on_line ();
-             if (c != '\n')
+             if (c != EOF)
                {
                  put_back (c);
                  token = real_yylex ();
@@ -2852,7 +2865,7 @@ linenum:
              entering_c_header = 1;
 
              c = get_last_nonwhite_on_line ();
-             if (c != '\n')
+             if (c != EOF)
                {
                  put_back (c);
                  token = real_yylex ();
@@ -2927,16 +2940,16 @@ linenum:
        }
 
       /* If NEXTCHAR is not end of line, we don't care what it is.  */
-      if (nextchar == '\n')
-       return '\n';
+      if (nextchar == EOF)
+       c = EOF;
     }
   else
     error ("invalid #-line");
 
   /* skip the rest of this line.  */
  skipline:
-  if (c == '\n')
-    return c;
+  linemode = 0;
+  end_of_file = 0;
   while ((c = getch ()) != EOF && c != '\n');
   return c;
 }
@@ -3343,6 +3356,8 @@ real_yylex ()
       end_of_file = 1;
       if (input_redirected ())
        value = END_OF_SAVED_INPUT;
+      else if (linemode)
+       value = END_OF_LINE;
       else if (do_pending_expansions ())
        /* this will set yychar for us */
        return yychar;
@@ -4906,21 +4921,10 @@ yyerror (string)
 /* This function has to be in this file, in order to get at
    the token types.  */
 
-int
-handle_sysv_pragma (input, c)
-     FILE *input;
-     int c;
+handle_sysv_pragma ()
 {
   for (;;)
     {
-      while (c == ' ' || c == '\t')
-       c = getc (input);
-      if (c == '\n' || c == EOF)
-       {
-         handle_pragma_token (0, 0);
-         return c;
-       }
-      ungetc (c, input);
       switch (yylex ())
        {
        case IDENTIFIER:
@@ -4929,13 +4933,12 @@ handle_sysv_pragma (input, c)
        case CONSTANT:
          handle_pragma_token (token_buffer, yylval.ttype);
          break;
+       case END_OF_LINE:
+         handle_pragma_token (0, 0);
+         return;
        default:
          handle_pragma_token (token_buffer, 0);
        }
-      if (nextchar >= 0)
-       c = nextchar, nextchar = -1;
-      else
-       c = getc (input);
     }
 }
 #endif /* HANDLE_SYSV_PRAGMA */
index 92610ff..5a646a5 100644 (file)
@@ -1220,10 +1220,11 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
           fnname, tree_cons (NULL_TREE, xarg1,
                               build_tree_list (NULL_TREE, xarg2)),
           NULL_TREE, flags);
-       /* This happens when the user mis-declares `operator delete'.
-          Should now be impossible.  */
+#if 0
+       /* This can happen when operator delete is protected.  */
        my_friendly_assert (rval != error_mark_node, 250);
        TREE_TYPE (rval) = void_type_node;
+#endif
        return rval;
       }
       break;
index 882c2fd..6a4420c 100644 (file)
@@ -277,6 +277,9 @@ empty_parms ()
 
 %type <strtype> .pushlevel
 
+/* Used in lex.c for parsing pragmas.  */
+%token END_OF_LINE
+
 /* spew.c depends on this being the last token.  Define
    any new tokens before this one!  */
 %token END_OF_SAVED_INPUT
index fabba84..5a52fd3 100644 (file)
@@ -1424,7 +1424,7 @@ build_functional_cast (exp, parms)
     {
       /* this must build a C cast */
       if (parms == NULL_TREE)
-       return build1 (NOP_EXPR, type, integer_zero_node);
+       parms = integer_zero_node;
       else if (TREE_CHAIN (parms) != NULL_TREE)
        {
          pedwarn ("initializer list being treated as compound expression");