[gnu.g++.bug] GNU C++ 1.35.0+ to 1.35.1

tiemann@YAHI.STANFORD.EDU (Michael Tiemann) (05/23/89)

These diffs fix bugs reported with MI, configuration file problems,
and other minor problems.  I will release 1.35.1 when that seems
appropriate.  Changes to fold-const.c provide a performance
improvement over previous versions of the compiler.  After profiling,
it appears that the parser itself is the major hog of CPU cycles.  I
suspect that this is due to epsilon rules needed to parse C++ with an
LALR parser.

yahi% diff -rc2H g++-1.35.0+ src-g++
diff -rc2H g++-1.35.0+/ChangeLog src-g++/ChangeLog
*** g++-1.35.0+/ChangeLog	Fri May 19 14:22:31 1989
--- src-g++/ChangeLog	Tue May 23 01:12:46 1989
***************
*** 1,28 ****
  Fri May 19 13:20:07 1989  Michael Tiemann  (tiemann at yahi)
  
! 	* cplus-class.c: handle case where user requests member function
! 	  using object, i.e., `x.f'.  If f is virtual, return the function
! 	  found in the virtual function table.
  
! 	* stor-layout.c: language dependent code removed from
! 	layout_basetypes, put in cplus-class.c
! 
! 	* stmt.c: if cleanups were called on leaving a binding contour,
! 	  and EXIT_IGNORE_STACK is not defined, call
! 	  do_pending_stack_adjust (expand_goto_internal,
! 	  expand_end_bindings, fixup_cleanups).
  
  	* gcc.c: recognize ".cxx" as a C++ file name extension.
  
! 	* cplus-typeck.c: convert_for_initialization,
! 	  convert_for_assignment convert MEMBER_REFs, if possible, to
  	  members or component refs as appropriate.
  
! 	* cplus-typeck.c: build_member_ref recognizes member refs which
  	  are not associated with any object in particular (i.e., could
  	  be, but need not be `this').
  
! 	* cplus-search.c: get_vbase_types now orders the virtual
! 	  base classes so that initialization and anti-initialization are
  	  performed in correct order.  A virtual baseclass is not
  	  destroyed until all parts of the object which could be using
--- 1,71 ----
+ Tue May 23 01:10:51 1989  Michael Tiemann  (tiemann at yahi)
+ 
+ 	* cplus-cvt.c: (convert_to_pointer) convert to virtual baseclasses
+ 	  through virtual baseclass pointers.  Also, give error if
+ 	  converting up from a virtual baseclass type.
+ 
+ Mon May 22 22:03:24 1989  Michael Tiemann  (tiemann at yahi)
+ 
+ 	* cplus-class.c: (finish_struct) remember to give dynamic classes
+ 	  a vfield even if they don't define virtual functions (-fSOS).
+ 
+ 	* cplus-decl.c: (init_decl_processing) fixed typo: TYPE_POINTER_TO
+ 	  does not build a pointer type, but build_pointer_type does.
+ 
+ 	* cplus-decl.c, cplus-init.c: allow builtin functions to be
+ 	  declared friends.
+ 
+ 	* cplus-class.c: (ideal_candidate) if the best candidates require
+ 	  user-defined type conversions, don't reject as ambiguous the
+ 	  case where one candidate comes from one class, and the other
+ 	  candidates come from base classes of that class.
+ 
+ 	* stor-layout.c: (layout_type) after laying out a type, make sure
+ 	  that all type variants get the type's size.
+ 
  Fri May 19 13:20:07 1989  Michael Tiemann  (tiemann at yahi)
  
! 	* cplus-class.c: (popclass) don't kill out prev_class_type's decls
! 	  if not at the global binding level.
  
! 	* cplus-decl.c: added new field `class_shadowed', which may some
! 	  day be used to implement nested clases.
! 
! 	* newld.c: (various places) round up size to double word boundary
! 	  if defined(sparc) || defined(sun).
! 
! 	* tree.c: (lvalue_p) A CALL_EXPR is an lvalue if the return type
! 	  is an addressable type.
! 
! 	* cplus-init.c: (make_friend_class) fix typo in error message.
! 
! 	* cplus-class.c: (finish_struct) Don't give error message if class
! 	  is does not define virtual functions which must be defined if
! 	  that class has some of its own.
! 
! 	* cplus-class.c: (instantiate_type) handle case where user
! 	  requests member function using object, i.e., `x.f'.  If f is
! 	  virtual, return the function found in the virtual function table.
! 
! 	* stor-layout.c: (layout_basetypes) language dependent code
! 	  removed, put in cplus-class.c
! 
! 	* stmt.c: (expand_goto_internal, expand_end_bindings,
! 	  fixup_cleanups) if cleanups were called on leaving a binding
! 	  contour, and EXIT_IGNORE_STACK is not defined, call
! 	  do_pending_stack_adjust.
  
  	* gcc.c: recognize ".cxx" as a C++ file name extension.
  
! 	* cplus-typeck.c: (convert_for_initialization,
! 	  convert_for_assignment) convert MEMBER_REFs, if possible, to
  	  members or component refs as appropriate.
  
! 	* cplus-typeck.c: (build_member_ref) recognize member refs which
  	  are not associated with any object in particular (i.e., could
  	  be, but need not be `this').
  
! 	* cplus-search.c: (get_vbase_types) orders the virtual base
! 	  classes so that initialization and anti-initialization are 
  	  performed in correct order.  A virtual baseclass is not
  	  destroyed until all parts of the object which could be using
***************
*** 31,37 ****
  	* cplus-parse.y: call build_vbase_delete if appropriate.
  
! 	* cplus-init.c: expand_delete now calls build_vbase_delete if
! 	  appropriate.  build_delete no longer deletes parts of objects
! 	  via virtual base classes.
  
  	* cplus-init.c: new function build_vbase_delete, performs
--- 74,80 ----
  	* cplus-parse.y: call build_vbase_delete if appropriate.
  
! 	* cplus-init.c: (expand_delete) call build_vbase_delete if
! 	  appropriate.  No longer deletes parts of objects via virtual
! 	  base classes.
  
  	* cplus-init.c: new function build_vbase_delete, performs
***************
*** 40,44 ****
  	  running destructors.
  
! 	* cplus-decl.c: make pushdecl, shadow_tag, and xref_tag have
  	  C-like behavior in "C" language scope vis a vis type
  	  declarations.
--- 83,87 ----
  	  running destructors.
  
! 	* cplus-decl.c: (pushdecl, shadow_tag, and xref_tag) implement
  	  C-like behavior in "C" language scope vis a vis type
  	  declarations.
***************
*** 56,61 ****
  	  to cplus-class.c.
  
! 	* cplus-class.c: changed `finish_struct' to call
! 	  `propagate_basetype_offsets'.
  
  	* cplus-class.c: new function `propagate_basetype_offsets' gives
--- 99,103 ----
  	  to cplus-class.c.
  
! 	* cplus-class.c: (finish_struct) call `propagate_basetype_offsets'.
  
  	* cplus-class.c: new function `propagate_basetype_offsets' gives
diff -rc2H g++-1.35.0+/config.g++ src-g++/config.g++
*** g++-1.35.0+/config.g++	Fri May 19 14:22:32 1989
--- src-g++/config.g++	Fri May 19 16:02:24 1989
***************
*** 134,138 ****
  		sed 's/-e start/-e __start/' < config/xm-sunos4.h > config/xm-sunos4+.h
  		configuration_file=xm-sunos4+.h
- 		configuration_file=xm-sunos4.h
  		machine_type=sun3-nfp
  		;;
--- 134,137 ----
diff -rc2H g++-1.35.0+/cplus-class.c src-g++/cplus-class.c
*** g++-1.35.0+/cplus-class.c	Fri May 19 14:22:33 1989
--- src-g++/cplus-class.c	Tue May 23 08:14:38 1989
***************
*** 918,921 ****
--- 918,922 ----
    tree friend_list = 0;
    int nonprivate_method = 0;
+   int uninheritable_virtuals = 0;
  
    if (TREE_CODE (name) == TYPE_DECL)
***************
*** 998,1002 ****
        TYPE_USES_VIRTUAL_BASECLASSES (t)
  	|= (TYPE_USES_VIRTUAL_BASECLASSES (basetype) | CLASSTYPE_VIA_VIRTUAL (t, i));
!       CLASSTYPE_HAS_UNINHERITABLE_VIRTUALS (t)
  	|= CLASSTYPE_HAS_UNINHERITABLE_VIRTUALS (basetype) | (CLASSTYPE_UNINHERITED_VIRTUALS (basetype) != 0);
        CLASSTYPE_ALTERS_VISIBILITIES_P (t)
--- 999,1003 ----
        TYPE_USES_VIRTUAL_BASECLASSES (t)
  	|= (TYPE_USES_VIRTUAL_BASECLASSES (basetype) | CLASSTYPE_VIA_VIRTUAL (t, i));
!       uninheritable_virtuals
  	|= CLASSTYPE_HAS_UNINHERITABLE_VIRTUALS (basetype) | (CLASSTYPE_UNINHERITED_VIRTUALS (basetype) != 0);
        CLASSTYPE_ALTERS_VISIBILITIES_P (t)
***************
*** 1774,1777 ****
--- 1775,1792 ----
        has_virtual = has_absolute;
        CLASSTYPE_VSIZE (t) = has_virtual;
+       if (vfield == 0)
+ 	{
+ 	  /* We build this decl with ptr_type_node, and
+ 	     change the type when we know what it should be.  */
+ 	  vfield = build_lang_decl (FIELD_DECL, get_vfield_name (t), ptr_type_node);
+ 	  DECL_FIELD_CONTEXT (vfield) = t;
+ 	  DECL_VCONTEXT (vfield) = t;
+ 	  DECL_SIZE_UNIT (vfield) = 0;
+ 	  y = tree_last (fields);
+ 	  if (y)
+ 	    TREE_CHAIN (y) = vfield;
+ 	  else
+ 	    fields = vfield;
+ 	}
      }
  #endif
***************
*** 1821,1829 ****
  	}
  
        /* Now that we know all virtual functions defined for this class,
  	 make sure we don't inherit any from a base class we are not
! 	 supposed to inherit.  */
!       if (CLASSTYPE_HAS_UNINHERITABLE_VIRTUALS (t))
  	{
  	  x = TREE_CHAIN (CLASSTYPE_VIRTUALS (t));
  	  while (x != NULL_TREE)
--- 1836,1851 ----
  	}
  
+       CLASSTYPE_HAS_UNINHERITABLE_VIRTUALS (t)
+ 	= (uninheritable_virtuals || CLASSTYPE_UNINHERITED_VIRTUALS (t));
+ 
        /* Now that we know all virtual functions defined for this class,
  	 make sure we don't inherit any from a base class we are not
! 	 supposed to inherit, but only if we don't define any such
! 	 virtual functions ourself.  */
! 
!       if (uninheritable_virtuals
! 	  && ! CLASSTYPE_UNINHERITED_VIRTUALS (t))
  	{
+ 	  int errors = 0;
  	  x = TREE_CHAIN (CLASSTYPE_VIRTUALS (t));
  	  while (x != NULL_TREE)
***************
*** 1835,1840 ****
  		  && value_member (decl, CLASSTYPE_UNINHERITED_VIRTUALS (context)))
  		{
! 		  error_with_decl (decl, "Virtual function `%s' cannot be inherited from base class");
! 		  error ("at this point in file");
  		}
  	      x = TREE_CHAIN (x);
--- 1857,1866 ----
  		  && value_member (decl, CLASSTYPE_UNINHERITED_VIRTUALS (context)))
  		{
! 		  if (errors == 0)
! 		    {
! 		      errors = 1;
! 		      error ("at this point in file, ");
! 		    }
! 		  error_with_decl (decl, "virtual function `%s' cannot be inherited from base class");
  		}
  	      x = TREE_CHAIN (x);
***************
*** 1934,1940 ****
    if (TYPE_NEEDS_CONSTRUCTING (t) || TYPE_NEEDS_DESTRUCTOR (t))
      {
!       TYPE_MODE (t) = BLKmode;
        DECL_MODE (TYPE_NAME (t)) = BLKmode;
!       TREE_ADDRESSABLE (t) = 1;
      }
  
--- 1960,1972 ----
    if (TYPE_NEEDS_CONSTRUCTING (t) || TYPE_NEEDS_DESTRUCTOR (t))
      {
!       tree variants = t;
! 
        DECL_MODE (TYPE_NAME (t)) = BLKmode;
!       while (variants)
! 	{
! 	  TYPE_MODE (variants) = BLKmode;
! 	  TREE_ADDRESSABLE (variants) = 1;
! 	  variants = TYPE_NEXT_VARIANT (variants);
! 	}
      }
  
***************
*** 2610,2613 ****
--- 2642,2646 ----
        tree tta = parms;
        tree ttf;
+       tree f1, p1;
  
  #if AMBIGUOUS_WORKING
***************
*** 2664,2670 ****
  	    {
  	      if (best == 0)
! 		best = i;
  	      else
! 		return 0;
  	    }
  	} while (cp + i != candidates);
--- 2697,2724 ----
  	    {
  	      if (best == 0)
! 		{
! 		  best = i;
! 		  f1 = cp[best].function;
! 		  p1 = TYPE_ARG_TYPES (TREE_TYPE (f1));
! 		}
  	      else
! 		{
! 		  /* Don't complain if next best is from base class.  */
! 		  tree f2 = cp[i].function;
! 		  tree p2 = TYPE_ARG_TYPES (TREE_TYPE (f2));
! 
! 		  if (TREE_CODE (TREE_TYPE (f1)) == METHOD_TYPE
! 		      && TREE_CODE (TREE_TYPE (f2)) == METHOD_TYPE
! 		      && (cp[i].harshness[0] & 4) != 0
! 		      && cp[best].harshness[0] < cp[i].harshness[0])
! 		    {
! 		      if (! compparms (TREE_CHAIN (p1), TREE_CHAIN (p2), 1))
! 			return 0;
! 		      else
! 			continue;
! 		    }
! 		  else
! 		    return 0;
! 		}
  	    }
  	} while (cp + i != candidates);
***************
*** 3585,3589 ****
  		       IDENTIFIER_POINTER (name));
  	      else
! 		error_with_aggr_type (save_basetype, "no member function `%s' defined within type `%s'",
  				      IDENTIFIER_POINTER (name));
  	      return error_mark_node;
--- 3639,3643 ----
  		       IDENTIFIER_POINTER (name));
  	      else
! 		error_with_aggr_type (save_basetype, "no member function `%s::%s'",
  				      IDENTIFIER_POINTER (name));
  	      return error_mark_node;
***************
*** 4045,4049 ****
    current_class_type = type;
  
!   if (type != prev_class_type && prev_class_type != NULL_TREE)
      {
        popclass (-1);
--- 4099,4104 ----
    current_class_type = type;
  
!   if (type != prev_class_type && prev_class_type != NULL_TREE
!       && current_class_stack == current_class_base + 1)
      {
        popclass (-1);
diff -rc2H g++-1.35.0+/cplus-cvt.c src-g++/cplus-cvt.c
*** g++-1.35.0+/cplus-cvt.c	Fri May 19 14:22:33 1989
--- src-g++/cplus-cvt.c	Tue May 23 06:08:22 1989
***************
*** 86,89 ****
--- 86,90 ----
  	  && IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype)))
  	{
+ 	  enum tree_code code = PLUS_EXPR;
  	  tree basetype = get_base_type (TREE_TYPE (TYPE_MAIN_VARIANT (type)),
  					 TREE_TYPE (intype), 1);
***************
*** 90,119 ****
  	  if (basetype == error_mark_node)
  	    return error_mark_node;
! 	  if (basetype && DECL_OFFSET (TYPE_NAME (basetype)) != 0)
  	    {
! 	      tree addr = TREE_CODE (expr) == ADDR_EXPR
! 		? expr : save_expr (expr);
! 	      tree temp = build (NOP_EXPR, string_type_node, addr);
! 
! 	      return build (COND_EXPR, type,
! 			    build (EQ_EXPR, integer_type_node, temp, integer_zero_node),
! 			    build (NOP_EXPR, type, temp),
! 			    build (PLUS_EXPR, type, temp, CLASSTYPE_OFFSET (basetype)));
  	    }
! 	  basetype = get_base_type (TREE_TYPE (intype),
! 				    TREE_TYPE (TYPE_MAIN_VARIANT (type)), 1);
! 	  if (basetype == error_mark_node)
! 	    return error_mark_node;
! 	  if (basetype && DECL_OFFSET (TYPE_NAME (basetype)) != 0)
  	    {
! 	      tree addr = TREE_CODE (expr) == ADDR_EXPR
! 		? expr : save_expr (expr);
! 	      tree temp = build (NOP_EXPR, string_type_node, addr);
  
! 	      return build (COND_EXPR, type,
! 			    build (EQ_EXPR, integer_type_node, temp, integer_zero_node),
! 			    build (NOP_EXPR, type, temp),
! 			    build (MINUS_EXPR, type, temp,
! 				   CLASSTYPE_OFFSET (basetype)));
  	    }
  	}
--- 91,141 ----
  	  if (basetype == error_mark_node)
  	    return error_mark_node;
! 	  if (basetype == NULL_TREE)
  	    {
! 	      basetype = get_base_type (TREE_TYPE (intype),
! 					TREE_TYPE (TYPE_MAIN_VARIANT (type)), 1);
! 	      if (basetype == error_mark_node)
! 		return error_mark_node;
! 	      code = MINUS_EXPR;
  	    }
! 	  if (basetype)
  	    {
! 	      if (TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (type))
! 		  || TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (intype)))
! 		{
! 		  /* Need to get the path we took.  */
! 		  tree path;
! 		  if (code == PLUS_EXPR)
! 		    get_base_distance (TREE_TYPE (type), TREE_TYPE (intype), 0, &path);
! 		  else
! 		    get_base_distance (TREE_TYPE (intype), TREE_TYPE (type), 0, &path);
! 		  while (path)
! 		    {
! 		      if (TREE_VIA_VIRTUAL (path))
! 			{
! 			  if (code == PLUS_EXPR)
! 			    expr = build_vbase_pointer (build_indirect_ref (expr), TREE_VALUE (path));
! 			  else
! 			    {
! 			      error_with_aggr_type (TREE_VALUE (path), "cannot cast up from virtual baseclass `%s'");
! 			      return error_mark_node;
! 			    }
! 			}
! 		      path = TREE_CHAIN (path);
! 		    }
! 		  return build (NOP_EXPR, type, expr);
! 		}
! 	      if (basetype && DECL_OFFSET (TYPE_NAME (basetype)) != 0)
! 		{
! 		  tree addr = TREE_CODE (expr) == ADDR_EXPR
! 		    ? expr : save_expr (expr);
! 		  tree temp = build (NOP_EXPR, string_type_node, addr);
  
! 		  return build (COND_EXPR, type,
! 				build (EQ_EXPR, integer_type_node, temp, integer_zero_node),
! 				build (NOP_EXPR, type, temp),
! 				build (code, type,
! 				       temp, CLASSTYPE_OFFSET (basetype)));
! 		}
  	    }
  	}
diff -rc2H g++-1.35.0+/cplus-decl.c src-g++/cplus-decl.c
*** g++-1.35.0+/cplus-decl.c	Fri May 19 14:22:35 1989
--- src-g++/cplus-decl.c	Tue May 23 06:07:52 1989
***************
*** 99,103 ****
--- 99,105 ----
     multiple error messages from one error in the input.  */
  
+ #undef error_mark_node
  tree error_mark_node;
+ #define error_mark_node (&ERROR_MARK_NODE)
  
  /* Erroneous argument lists can use this *IFF* they do not modify it.  */
***************
*** 543,546 ****
--- 545,551 ----
      tree shadowed;
  
+     /* Same, for IDENTIFIER_CLASS_VALUE.  */
+     tree class_shadowed;
+ 
      /* For each level (except not the global one),
         a chain of LET_STMT nodes for all the levels
***************
*** 593,597 ****
  
  static struct binding_level clear_binding_level
!   = {NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0};
  
  #define PUSH_BINDING_LEVEL(NEWLEVEL, TAG_TRANSPARENT, TEMPORARY) \
--- 598,602 ----
  
  static struct binding_level clear_binding_level
!   = {NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0};
  
  #define PUSH_BINDING_LEVEL(NEWLEVEL, TAG_TRANSPARENT, TEMPORARY) \
***************
*** 809,812 ****
--- 814,821 ----
    for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
      IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
+   for (link = current_binding_level->class_shadowed;
+        link;
+        link = TREE_CHAIN (link))
+     IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
  
    /* If the level being exited is the top level of a function,
***************
*** 2405,2408 ****
--- 2414,2419 ----
     Make definitions for built-in primitive functions.  */
  
+ union tree_node ERROR_MARK_NODE;
+ 
  void
  init_decl_processing ()
***************
*** 2416,2420 ****
--- 2427,2438 ----
  
    /* Must lay these out before anything else gets laid out.  */
+ #if 0
    error_mark_node = make_node (ERROR_MARK);
+ #else
+ #undef error_mark_node
+   error_mark_node = &ERROR_MARK_NODE;
+ #define error_mark_node (&ERROR_MARK_NODE)
+   TREE_PERMANENT (error_mark_node) = 1;
+ #endif
    TREE_TYPE (error_mark_node) = error_mark_node;
    error_mark_list = build_tree_list (error_mark_node, error_mark_node);
***************
*** 2553,2557 ****
    default_function_type
      = build_function_type (integer_type_node, NULL_TREE);
!   TYPE_POINTER_TO (default_function_type);
  
    ptr_type_node = build_pointer_type (void_type_node);
--- 2571,2575 ----
    default_function_type
      = build_function_type (integer_type_node, NULL_TREE);
!   build_pointer_type (default_function_type);
  
    ptr_type_node = build_pointer_type (void_type_node);
***************
*** 6375,6379 ****
  	    init = decl_constant_value (init);
  	  assert (TREE_PERMANENT (init));
! 	  if (! TREE_LITERAL (init))
  	    {
  	      /* We can allow references to things that are effectively
--- 6393,6398 ----
  	    init = decl_constant_value (init);
  	  assert (TREE_PERMANENT (init));
! 	  if (init != error_mark_node
! 	      && ! TREE_LITERAL (init))
  	    {
  	      /* We can allow references to things that are effectively
***************
*** 8072,8075 ****
--- 8091,8098 ----
      for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
        IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
+   for (link = current_binding_level->class_shadowed;
+        link;
+        link = TREE_CHAIN (link))
+     IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
  
      POP_BINDING_LEVEL;
diff -rc2H g++-1.35.0+/cplus-init.c src-g++/cplus-init.c
*** g++-1.35.0+/cplus-init.c	Fri May 19 14:22:36 1989
--- src-g++/cplus-init.c	Tue May 23 06:08:49 1989
***************
*** 436,439 ****
--- 436,440 ----
  {
    tree vtbl, vtbl_ptr;
+   tree vtype;
  
    if (for_type != type)
***************
*** 450,457 ****
        vtbl = build (ADDR_EXPR, TYPE_POINTER_TO (TREE_TYPE (vtbl)), vtbl);
      }
  
-   decl = convert_to_nonzero_pointer (TYPE_POINTER_TO (type), decl);
-   vtbl_ptr = build_vfield_ref (build_indirect_ref (decl, 0), type);
- 
    return build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl);
  }
--- 451,458 ----
        vtbl = build (ADDR_EXPR, TYPE_POINTER_TO (TREE_TYPE (vtbl)), vtbl);
      }
+   vtype = DECL_CONTEXT (CLASSTYPE_VFIELD (type));
+   decl = convert_to_nonzero_pointer (TYPE_POINTER_TO (vtype), decl);
+   vtbl_ptr = build_vfield_ref (build_indirect_ref (decl, 0), vtype);
  
    return build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl);
  }
***************
*** 1859,1863 ****
    if (classes)
      warning ("class `%s' is already friends with class `%s'",
! 	     TYPE_NAME_STRING (type), TYPE_NAME_STRING (type));
    else
      {
--- 1860,1864 ----
    if (classes)
      warning ("class `%s' is already friends with class `%s'",
! 	     TYPE_NAME_STRING (TREE_VALUE (classes)), TYPE_NAME_STRING (type));
    else
      {
***************
*** 1936,1944 ****
      }
    else if (TREE_CODE (decl) == FUNCTION_DECL
! 	   && IDENTIFIER_LENGTH (declarator) == 4
! 	   && IDENTIFIER_POINTER (declarator)[0] == 'm'
! 	   && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
      {
!       /* raw "main" never gets overloaded, but it can become a friend.  */
        add_friend (current_class_type, decl);
        DECL_FRIEND_P (decl) = 1;
--- 1937,1951 ----
      }
    else if (TREE_CODE (decl) == FUNCTION_DECL
! 	   && ((IDENTIFIER_LENGTH (declarator) == 4
! 		&& IDENTIFIER_POINTER (declarator)[0] == 'm'
! 		&& ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
! 	       || (IDENTIFIER_LENGTH (declarator) > 10
! 		   && IDENTIFIER_POINTER (declarator)[0] == '_'
! 		   && IDENTIFIER_POINTER (declarator)[1] == '_'
! 		   && strncmp (IDENTIFIER_POINTER (declarator)+2,
! 			       "builtin_", 8) == 0)))
      {
!       /* raw "main", and builtin functions never gets overloaded,
! 	 but they can become friends.  */
        add_friend (current_class_type, decl);
        DECL_FRIEND_P (decl) = 1;
***************
*** 2659,2667 ****
    else
      {
!       ref = addr;
!       if (ref == C_C_D)
! 	addr = current_class_decl;
        else
! 	addr = build (ADDR_EXPR, build_pointer_type (type), addr);
        ptr = 0;
      }
--- 2666,2676 ----
    else
      {
!       addr = convert (build_pointer_type (type),
! 		      build_unary_op (ADDR_EXPR, addr, 0));
!       if (TREE_CODE (addr) == NOP_EXPR
! 	  && TREE_OPERAND (addr, 0) == current_class_decl)
! 	ref = C_C_D;
        else
! 	ref = build_indirect_ref (addr, 0);
        ptr = 0;
      }
diff -rc2H g++-1.35.0+/cplus-lex.c src-g++/cplus-lex.c
*** g++-1.35.0+/cplus-lex.c	Fri May 19 14:22:37 1989
--- src-g++/cplus-lex.c	Tue May 23 07:31:22 1989
***************
*** 1468,1473 ****
--- 1468,1478 ----
  }
  
+ #if 0
  #define isalnum(char) (char >= 'a' ? char <= 'z' : char >= '0' ? char <= '9' || (char >= 'A' && char <= 'Z') : 0)
  #define isdigit(char) (char >= '0' && char <= '9')
+ #else
+ #include <ctype.h>
+ #endif
+ 
  #define ENDFILE -1  /* token that represents end-of-file */
  
***************
*** 1904,1909 ****
  		    || ANON_AGGRNAME_P (tmp)
  		    || ANON_PARMNAME_P (tmp)))
! 		  fatal ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
! 			 token_buffer);
  
  	    /* Come into here if we must reprocess an identifier.  */
--- 1909,1914 ----
  		    || ANON_AGGRNAME_P (tmp)
  		    || ANON_PARMNAME_P (tmp)))
! 	      warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
! 		       token_buffer);
  
  	    /* Come into here if we must reprocess an identifier.  */
***************
*** 2595,2601 ****
  	}
        /* Go down for a (X::*) or (X::&).  */
!       else if (nextchar >= 'a' && nextchar <= 'z'
! 	       || nextchar >= 'A' && nextchar <= 'Z'
! 	       || nextchar == '_' || nextchar == '$')
  	{
  	  YYSTYPE this_yylval = yylval;
--- 2600,2604 ----
  	}
        /* Go down for a (X::*) or (X::&).  */
!       else if (isalpha (nextchar) || nextchar == '_' || nextchar == '$')
  	{
  	  YYSTYPE this_yylval = yylval;
diff -rc2H g++-1.35.0+/cplus-tree.h src-g++/cplus-tree.h
*** g++-1.35.0+/cplus-tree.h	Fri May 19 14:22:40 1989
--- src-g++/cplus-tree.h	Tue May 23 06:05:31 1989
***************
*** 1086,1092 ****
  #define PRINT_LANG_TYPE
  
- /* -- end of C++ */
- 
  #define UNKNOWN_TYPE LANG_TYPE
  
  #define NO_AUTO_OVERLOAD
--- 1086,1096 ----
  #define PRINT_LANG_TYPE
  
  #define UNKNOWN_TYPE LANG_TYPE
  
  #define NO_AUTO_OVERLOAD
+ 
+ extern union tree_node ERROR_MARK_NODE;
+ 
+ #define error_mark_node (&ERROR_MARK_NODE)
+ 
+ /* -- end of C++ */
diff -rc2H g++-1.35.0+/cplus-typeck.c src-g++/cplus-typeck.c
*** g++-1.35.0+/cplus-typeck.c	Fri May 19 14:22:41 1989
--- src-g++/cplus-typeck.c	Tue May 23 08:14:44 1989
***************
*** 4069,4073 ****
       value get promoted if necessary.  */
  
!   if (type1 == type2
        && TREE_CODE (type2) != ARRAY_TYPE
        && TREE_CODE (type2) != ENUMERAL_TYPE
--- 4069,4073 ----
       value get promoted if necessary.  */
  
!   if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)
        && TREE_CODE (type2) != ARRAY_TYPE
        && TREE_CODE (type2) != ENUMERAL_TYPE
***************
*** 4084,4087 ****
--- 4084,4093 ----
        if (TREE_READONLY (op2) && TREE_CODE (op2) == VAR_DECL)
  	op2 = decl_constant_value (op2);
+       if (type1 != type2)
+ 	{
+ 	  int constp = TREE_READONLY (type1) || TREE_READONLY (type2);
+ 	  int volatilep = TREE_VOLATILE (type1) || TREE_VOLATILE (type2);
+ 	  type1 = build_type_variant (type1, constp, volatilep);
+ 	}
        return build (COND_EXPR, type1, ifexp, op1, op2);
      }
***************
*** 4104,4109 ****
    /* Quickly detect the usual case where op1 and op2 have the same type
       after promotion.  */
!   if (type1 == type2)
!     result_type = type1;
    else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE)
             && (code2 == INTEGER_TYPE || code2 == REAL_TYPE))
--- 4110,4123 ----
    /* Quickly detect the usual case where op1 and op2 have the same type
       after promotion.  */
!   if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
!     {
!       if (type1 != type2)
! 	{
! 	  int constp = TREE_READONLY (type1) || TREE_READONLY (type2);
! 	  int volatilep = TREE_VOLATILE (type1) || TREE_VOLATILE (type2);
! 	  type1 = build_type_variant (type1, constp, volatilep);
! 	}
!       result_type = type1;
!     }
    else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE)
             && (code2 == INTEGER_TYPE || code2 == REAL_TYPE))
diff -rc2H g++-1.35.0+/flags.h src-g++/flags.h
*** g++-1.35.0+/flags.h	Fri May 19 14:22:43 1989
--- src-g++/flags.h	Mon May 22 21:02:57 1989
***************
*** 184,187 ****
--- 184,191 ----
  extern int flag_delayed_branch;
  
+ /* Nonzero means do basic-block instruction scheduling.  */
+ 
+ extern int flag_schedule_insns;
+ 
  /* 1 means write out virtual function tables and give them
     (C) public visibility.
diff -rc2H g++-1.35.0+/fold-const.c src-g++/fold-const.c
*** g++-1.35.0+/fold-const.c	Fri May 19 14:22:44 1989
--- src-g++/fold-const.c	Fri May 19 22:55:12 1989
***************
*** 208,211 ****
--- 208,242 ----
    register int i, j, k;
  
+   /* These two cases are used extensively, arising from pointer
+      combinations.  */
+   if (h2 == 0)
+     {
+       if (l2 == 4)
+ 	{
+ 	  unsigned temp = l1 + l1;
+ 	  h1 = (temp < l1) << 1;
+ 	  l1 = temp;
+ 	  temp += temp;
+ 	  h1 += (temp < l1);
+ 	  *lv = temp;
+ 	  *hv = h1;
+ 	  return;
+ 	}
+       if (l2 == 8)
+ 	{
+ 	  unsigned temp = l1 + l1;
+ 	  h1 += (temp < l1) << 2;
+ 	  l1 = temp;
+ 	  temp += temp;
+ 	  h1 += (temp < l1) << 1;
+ 	  l1 = temp;
+ 	  temp += temp;
+ 	  h1 += (temp < l1);
+ 	  *lv = temp;
+ 	  *hv = h1;
+ 	  return;
+ 	}
+     }
+ 
    encode (arg1, l1, h1);
    encode (arg2, l2, h2);
***************
*** 606,614 ****
  
  	/* get absolute values */
! 	if (*hrem < 0) neg_double(*lrem, *hrem, &labs_rem, &habs_rem);
! 	if (hden < 0) neg_double(lden, hden, &labs_den, &habs_den);
  
  	/* if (2 * abs (lrem) >= abs (lden)) */
! 	mul_double(2, 0, labs_rem, habs_rem, &ltwice, &htwice);
  	if (((unsigned) habs_den < (unsigned) htwice)
  	    || (((unsigned) habs_den == (unsigned) htwice)
--- 637,645 ----
  
  	/* get absolute values */
! 	if (*hrem < 0) neg_double (*lrem, *hrem, &labs_rem, &habs_rem);
! 	if (hden < 0) neg_double (lden, hden, &labs_den, &habs_den);
  
  	/* if (2 * abs (lrem) >= abs (lden)) */
! 	mul_double (2, 0, labs_rem, habs_rem, &ltwice, &htwice);
  	if (((unsigned) habs_den < (unsigned) htwice)
  	    || (((unsigned) habs_den == (unsigned) htwice)
***************
*** 784,787 ****
--- 815,834 ----
  
  	case PLUS_EXPR:
+ 	  if (int1h == 0)
+ 	    {
+ 	      int2l += int1l;
+ 	      if ((unsigned) int2l < int1l)
+ 		int2h += 1;
+ 	      t = build_int_2 (int2l, int2h);
+ 	      break;
+ 	    }
+ 	  if (int2h == 0)
+ 	    {
+ 	      int1l += int2l;
+ 	      if ((unsigned) int1l < int2l)
+ 		int1h += 1;
+ 	      t = build_int_2 (int1l, int1h);
+ 	      break;
+ 	    }
  	  add_double (int1l, int1h, int2l, int2h, &low, &hi);
  	  t = build_int_2 (low, hi);
***************
*** 789,792 ****
--- 836,849 ----
  
  	case MINUS_EXPR:
+ 	  if (int1h == 0 && int1l == 0)
+ 	    {
+ 	      t = build_int_2 (- int2l, - int2h);
+ 	      break;
+ 	    }
+ 	  if (int2h == 0 && int2l == 0)
+ 	    {
+ 	      t = build_int_2 (int1l, int1h);
+ 	      break;
+ 	    }
  	  neg_double (int2l, int2h, &int2l, &int2h);
  	  add_double (int1l, int1h, int2l, int2h, &low, &hi);
***************
*** 795,798 ****
--- 852,921 ----
  
  	case MULT_EXPR:
+   /* Optimize simple cases.  */
+ 	  if (int1h == 0)
+ 	    {
+ 	      unsigned temp;
+ 
+ 	      switch (int1l)
+ 		{
+ 		case 0:
+ 		  t = build_int_2 (0, 0);
+ 		  goto got_it;
+ 		case 1:
+ 		  t = build_int_2 (int2l, int2h);
+ 		  goto got_it;
+ 		case 2:
+ 		  temp = int2l + int2l;
+ 		  int2h += (temp < int2l);
+ 		  t = build_int_2 (temp, int2h);
+ 		  goto got_it;
+ 		case 3:
+ 		  temp = int2l + int2l + int2l;
+ 		  int2h += (temp < int2l);
+ 		  t = build_int_2 (temp, int2h);
+ 		  goto got_it;
+ 		case 4:
+ 		  temp = int2l + int2l;
+ 		  int2h += (temp < int2l) << 1;
+ 		  int2l = temp;
+ 		  temp += temp;
+ 		  int2h += (temp < int2l);
+ 		  t = build_int_2 (temp, int2h);
+ 		  goto got_it;
+ 		case 5:
+ 		case 6:
+ 		case 7:
+ 		  /* Don't bother with these.  */
+ 		  break;
+ 		case 8:
+ 		  temp = int2l + int2l;
+ 		  int2h += (temp < int2l) << 2;
+ 		  int2l = temp;
+ 		  temp += temp;
+ 		  int2h += (temp < int2l) << 1;
+ 		  int2l = temp;
+ 		  temp += temp;
+ 		  int2h += (temp < int2l);
+ 		  t = build_int_2 (temp, int2h);
+ 		  goto got_it;
+ 		default:
+ 		  break;
+ 		}
+ 	    }
+ 
+ 	  if (int2h == 0)
+ 	    {
+ 	      if (int2l == 0)
+ 		{
+ 		  t = build_int_2 (0, 0);
+ 		  break;
+ 		}
+ 	      if (int2l == 1)
+ 		{
+ 		  t = build_int_2 (int1l, int1h);
+ 		  break;
+ 		}
+ 	    }
+ 
  	  mul_double (int1l, int1h, int2l, int2h, &low, &hi);
  	  t = build_int_2 (low, hi);
***************
*** 802,805 ****
--- 925,941 ----
  	case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR:
  	case EXACT_DIV_EXPR:
+ 	  if (int2h == 0 && int2l == 1)
+ 	    {
+ 	      t = build_int_2 (int1l, int1h);
+ 	      break;
+ 	    }
+ 	  if (int1l == int2l && int1h == int2h)
+ 	    {
+ 	      if ((int1l | int1h) == 0)
+ 		abort ();
+ 	      t = build_int_2 (1, 0);
+ 	      TREE_UNSIGNED (t) = uns;
+ 	      break;
+ 	    }
  	  div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
  				&low, &hi, &garbagel, &garbageh);
***************
*** 837,840 ****
--- 973,977 ----
  	  abort ();
  	}
+     got_it:
        TREE_TYPE (t) = TREE_TYPE (arg1);
        force_fit_type (t);
diff -rc2H g++-1.35.0+/g++.texinfo src-g++/g++.texinfo
*** g++-1.35.0+/g++.texinfo	Fri May 19 14:22:45 1989
--- src-g++/g++.texinfo	Mon May 22 23:56:39 1989
***************
*** 1120,1128 ****
  
  @item -flabels-ok
! Allow labels to be found in name-space.  The compiler will allow a variable
! to be assigned to the value of a label, thus making complex jump tables
! constructible within GNU C++.  Note that labels are not lvalues, and cannot
! be assigned to variables.
  
  @item -d@var{letters}
  Says to make debugging dumps at times specified by @var{letters}.
--- 1120,1171 ----
  
  @item -flabels-ok
! Allow labels to be found in name-space.  The compiler will allow a
! variable to be assigned to the value of a label, thus making complex
! jump tables constructible within GNU C++.  Note that labels are not
! lvalues, and cannot be assigned to variables.  (This option is not
! currently implemented...)
! 
! @item -felide-constructors
! Using this option instructs the compiler to be smarter about when it can
! elide constructors.  With out this flag, GNU C++ and cfront both
! generate effectively the same code for:
  
+ @group
+ @example
+ A foo ();
+ A x (foo ());   // x is initialized by `foo ()', no ctor called here
+ A y = foo ();   // call to `foo ()' heads to temporary,
+                 // y is initialized from the temporary.
+ @end @example
+ @end @group
+ 
+ Note the difference!  With this flag, GNU C++ initializes `y' directly
+ from the call to `foo ()' without going through a temporary.
+  
+ @item -fall-virtual
+ When the -fall-virtual option is used, all member functions (except for
+ constructor functions and new/delete member operators) declared in the
+ same class with a ``method-call'' operator method have entries made for
+ them in the vtable for the given class.  In effect, all of these methods
+ become ``implicitly virtual.''
+ 
+ This does @emph{not} mean that all calls to these methods will be made
+ through the vtable.  There are some circumstances under which it is
+ obvious that a call to a given virtual function can be made directly,
+ and in these cases the calls still go direct.
+ 
+ The effect of making all methods of a class with a declared
+ `operator->()()' implicitly virtual using -fall-virtual extends also to
+ all non-constructor methods of any class derived from such a class.
+ 
+ @item -fsave-memoized
+ TBA
+ 
+ @item -fmemoize-lookups
+ TBA
+ 
+ @item -fSOS
+ TBA
+ 
  @item -d@var{letters}
  Says to make debugging dumps at times specified by @var{letters}.
***************
*** 2051,2073 ****
  @item
  The design of the C++ programming language did not take into account the
! usefulness of being able to specify that language using an LALR(1) grammar.
! As a result, in order to correctly parse it, one needs a look-ahead lexical
! analyzer (with infinite lookahead), and a recursive descent parser, guided
! by some good heuristics.  This approach was not taken in GNU C++, because
! it is considered archaic, notoriously difficult to extend syntactically,
! and generally offensive.  GNU C++ uses an LALR(1) grammar so that users can
! easily understand, and readily modify the compiler to suit their needs.
! Free software is useless if it becomes captive to an inaccessible or
! undesirable technology.  However, in providing such a grammar, some
! syntactic forms were lost, most notably old-style C function declarations
! and occasionally function parameters which are declared longhand to be
! pointers to functions are not recognized properly.  The first problem is
! solved by converting old-style C code to the ANSI-standard function
! prototype form.  The second problem can always be solved by using a
! @code{typedef} for the pointer to function, and working from there.
! Another hack which can be used, if the parameter can legitimately be
! declared with a storage class (such as `register', or `auto') is to make
! that storage class explicit: @w{@code{int f (register int (*pf)(int,int))
! @{...@}}}.
  
  @end itemize
--- 2094,2119 ----
  @item
  The design of the C++ programming language did not take into account the
! usefulness of being able to specify that language using an LALR(1)
! grammar.  As a result, in order to correctly parse C++, one needs a
! look-ahead lexical analyzer (with infinite lookahead), and a recursive
! descent parser, guided by some good heuristics.  This approach was not
! taken in GNU C++, because it is considered archaic, notoriously
! difficult to extend syntactically, and generally offensive.  GNU C++
! uses an LALR(1) grammar so that users can easily understand, and readily
! modify the compiler to suit their needs.  Free software is useless if it
! becomes captive to an inaccessible or undesirable technology.
! 
! Some syntactic forms were lost by utilizing an LALR(1) grammar, however.
! Most notably old-style C function declarations and function parameters
! and local variables that are declared longhand to be pointers to
! functions are not recognized properly (note that GNU C++ @emph{can} grok
! pointer-to-function casts, for example, (void (*)())0 is parsed
! correctly).  The first problem is solved by converting old-style C code
! to the ANSI-standard function prototype form.  The second problem can
! always be solved by using a @code{typedef} for the pointer to function,
! and working from there.  Another hack which can be used, if the
! parameter can legitimately be declared with a storage class (such as
! `register', or `auto') is to make that storage class explicit:
! @w{@code{int f (register int (*pf)(int,int)) @{...@}}}.
  
  @end itemize
***************
*** 3177,3181 ****
  @section Static Member Functions
  
! Could someone please write about this?
  
  @node Features, Bugs, Extensions, Top
--- 3223,3313 ----
  @section Static Member Functions
  
! Programmers familiar with Ada packages, Pascal units, or Modula-2
! modules recognize the benefits of hiding functions within an
! encapsulation unit.  GNU G++ further augments C++'s data abstraction
! capability with @dfn{static member functions}.  Static member functions
! are subject to the same inlining and visibility features available with
! regular member functions.  The major differences between static and
! non-static member functions are that:
! 
! @itemize @bullet 
! @item 
! It is possible to call any visible static class member function
! regardless of whether a class instance exists.
! 
! @item 
! Static member functions may only access global variables and static
! class data elements.
! 
! @item
! Static member functions may not be declared virtual.
! 
! @end itemize
! 
! Since static member functions exist independently of any class
! instances they lack an implicit `this' pointer.  Therefore, they have
! no access to any @emph{non}-static class member functions or data.
! 
! Here's an familiar Abstract Data Type application demonstrating static
! member functions:
! 
! @group
! @example
! #include <stream.h>
! 
! static const int MAX_STACK = 100;
! 
! class Stack
! @{
! private:
!   static int  stack[MAX_STACK];
!   static int  top;
!      
! public:
!   static void push (int item) @{ stack[top++] = item; @}
!   static int pop () @{ return stack[--top]; @}
!   static int is_empty () @{ return top == 0; @}
!   static int is_full () @{ return top >= MAX_STACK; @}
! @};
! 
! main ()
! @{
!   for (srandom (time (0L)); !Stack::is_full (); Stack::push (random ()))
!     ;
! 
!   while (!Stack::is_empty ())
!     cout << Stack::pop () << "\n";
! @}
! @end example
! @end group
! 
! This example is similar in spirit to how an Ada or Modula-2 programmer
! might design a bounded-stack abstraction.  Note how there is only
! @strong{one} @var{stack} array for all instances of class Stack.
! Naturally, in this particular case it isn't very useful to declare
! multiple instances of class Stack, since the data would be shared
! between all class instances.
! 
! Several benefits accrue from the use of static member functions:
! 
! @itemize @bullet 
! @item 
! Static member functions have no access to the class instance pointer
! `this'.  Thus, there is no need to pass an extra hidden parameter for
! each static member function call, thereby decreasing parameter passing
! overhead.
! 
! @item
! Static member functions provide an encapsulation mechanism for
! manipulating static data objects.
! 
! @end itemize
! 
! Another important use of static member functions is writing type-safe
! handler routines.  Doug Lea can explain how this works with the Fix{xx} 
! classes in libg++.
! 
! Note that it is possible to mix static and non-static member functions
! in the same class.
  
  @node Features, Bugs, Extensions, Top
***************
*** 4133,4138 ****
  declarations.
  
! GNU C++ does not yet handle local class declarations.  I.e., a local class
! declaration will permanently shadow a previous declaration.  
  
  The @samp{-p} and @samp{-pg} options are not yet supported.  The reason for
--- 4265,4274 ----
  declarations.
  
! GNU C++ does not yet handle local class declarations.  A local class
! declaration permanently shadows a previous declaration.  GNU C++ does
! however support local enum declarations.  Access to class-level enum
! values are checked the same way that access is checked for class
! members and member functions, so it is possible to have private and
! protected enum values.
  
  The @samp{-p} and @samp{-pg} options are not yet supported.  The reason for
***************
*** 4158,4164 ****
  containing class objects with constructors and destructors.
  
! Work on supporting multiple inheritance is underway, but it is not yet
! fully operational in the current implementation.  You help with testing
! and debugging multiple inheritance in GNU C++ would be very useful.
  
  @node Articles, Bibliography, BugList, Top
--- 4294,4300 ----
  containing class objects with constructors and destructors.
  
! Work on supporting multiple inheritance is underway, and appears almost
! fully operational in the current implementation.  Your help with testing
! and debugging multiple inheritance in GNU C++ is very useful.
  
  @node Articles, Bibliography, BugList, Top
diff -rc2H g++-1.35.0+/make-links.g++ src-g++/make-links.g++
*** g++-1.35.0+/make-links.g++	Fri May 19 14:22:47 1989
--- src-g++/make-links.g++	Sun May 21 14:24:11 1989
***************
*** 34,38 ****
  then
  	DIR="../gcc"
- else
  fi
  CDIR="../${DIR}/config"
--- 34,37 ----
diff -rc2H g++-1.35.0+/newld.c src-g++/newld.c
*** g++-1.35.0+/newld.c	Fri May 19 14:22:49 1989
--- src-g++/newld.c	Fri May 19 15:33:24 1989
***************
*** 2873,2877 ****
  #endif
  
! #ifdef sparc
    data_size = (data_size + sizeof(double) - 1) & ~(sizeof(double)-1);
  #endif
--- 2873,2877 ----
  #endif
  
! #if defined(sun) || defined(sparc)
    data_size = (data_size + sizeof(double) - 1) & ~(sizeof(double)-1);
  #endif
***************
*** 2994,2997 ****
--- 2994,3001 ----
  	}
      }
+ 
+ #if defined(sun) || defined(sparc)
+   bss_size = (bss_size + sizeof(double) - 1) & ~(sizeof(double)-1);
+ #endif
  
    if (end_symbol)		/* These are null if -r.  */
diff -rc2H g++-1.35.0+/stor-layout.c src-g++/stor-layout.c
*** g++-1.35.0+/stor-layout.c	Fri May 19 14:22:51 1989
--- src-g++/stor-layout.c	Tue May 23 07:40:21 1989
***************
*** 468,475 ****
        else
  	{
  	  CLASSTYPE_THIS_BASECLASS (rec, i) = basetype
! 	    = build_classtype_variant (basetype,
! 				       convert_units (build_int (const_size), 1, BITS_PER_UNIT),
! 				       0);
  
  	  if (const_size != 0)
--- 468,480 ----
        else
  	{
+ 	  tree class_offset;
+ 
+ 	  if (const_size == 0)
+ 	    class_offset = integer_zero_node;
+ 	  else
+ 	    class_offset = convert_units (build_int (const_size), 1, BITS_PER_UNIT);
+ 
  	  CLASSTYPE_THIS_BASECLASS (rec, i) = basetype
! 	    = build_classtype_variant (basetype, class_offset, 0);
  
  	  if (const_size != 0)
***************
*** 1067,1070 ****
--- 1072,1094 ----
    if (TYPE_SIZE (type) != 0 && ! TREE_LITERAL (TYPE_SIZE (type)))
      TYPE_SIZE (type) = variable_size (TYPE_SIZE (type));
+ 
+   if (TYPE_NEXT_VARIANT (type)
+       || type != TYPE_MAIN_VARIANT (type))
+     {
+       /* Lay out this type for all variants as well.  */
+       tree size = TYPE_SIZE (type);
+       int size_unit = TYPE_SIZE_UNIT (type);
+       int align = TYPE_ALIGN (type);
+       enum machine_mode mode = TYPE_MODE (type);
+       type = TYPE_MAIN_VARIANT (type);
+       while (type)
+ 	{
+ 	  TYPE_SIZE (type) = size;
+ 	  TYPE_SIZE_UNIT (type) = size_unit;
+ 	  TYPE_ALIGN (type) = align;
+ 	  TYPE_MODE (type) = mode;
+ 	  type = TYPE_NEXT_VARIANT (type);
+ 	}
+     }
  
    if (temporary)
diff -rc2H g++-1.35.0+/toplev.c src-g++/toplev.c
*** g++-1.35.0+/toplev.c	Fri May 19 14:22:52 1989
--- src-g++/toplev.c	Mon May 22 21:03:37 1989
***************
*** 285,288 ****
--- 285,292 ----
  int flag_delayed_branch;
  
+ /* Nonzero means schedule instructions within basic blocks.  */
+ 
+ int flag_schedule_insns = 0;
+ 
  /* Name for output file of assembly code, specified with -o.  */
  
***************
*** 318,322 ****
    {"caller-saves", &flag_caller_saves, 1},
    {"pcc-struct-return", &flag_pcc_struct_return, 1},
!   {"delayed-branch", &flag_delayed_branch, 1}
  };
  
--- 322,327 ----
    {"caller-saves", &flag_caller_saves, 1},
    {"pcc-struct-return", &flag_pcc_struct_return, 1},
!   {"delayed-branch", &flag_delayed_branch, 1},
!   {"schedule-insns", &flag_schedule_insns, 1}
  };
  
diff -rc2H g++-1.35.0+/tree.c src-g++/tree.c
*** g++-1.35.0+/tree.c	Fri May 19 14:22:53 1989
--- src-g++/tree.c	Fri May 19 15:30:37 1989
***************
*** 1104,1108 ****
  
        case CALL_EXPR:
! 	if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
  	  return 1;
  	break;
--- 1104,1110 ----
  
        case CALL_EXPR:
! 	if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE
! 	    /* unary_complex_lvalue knows how to deal with this case.  */
! 	    || TREE_ADDRESSABLE (TREE_TYPE (ref)))
  	  return 1;
  	break;
diff -rc2H g++-1.35.0+/version.c src-g++/version.c
*** g++-1.35.0+/version.c	Fri May 19 14:22:54 1989
--- src-g++/version.c	Tue May 23 07:14:12 1989
***************
*** 1,1 ****
! char *version_string = "1.35.0+";
--- 1,1 ----
! char *version_string = "1.35.1-";
yahi% 

Michael