diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a092c8db65b61353e2d5c26e13eb93e4563cf9a8..df22c23039381493e67c2e50594147af25d61fc7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -10,6 +10,59 @@ 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.
 
+Fri Feb 17 15:31:31 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+	* decl2.c (reparse_decl_as_expr): Support being called without a
+	type argument.
+
+	* parse.y (primary): Add '(' expr_or_declarator ')'.  Adds 4 r/r
+	conflicts.  Sigh.
+
+Fri Feb 17 12:02:06 1995  Mike Stump  <mrs@cygnus.com>
+
+	* parse.y (template_def, fndef, fn.def1, return_init, condition,
+	initdcl0, initdcl, notype_initdcl0, nomods_initdcl0,
+	component_decl_1, after_type_component_declarator0,
+	notype_component_declarator0, after_type_component_declarator,
+	notype_component_declarator, after_type_component_declarator,
+	full_parm, maybe_raises, exception_specification_opt): Fix up,
+	include exception_specification_opt maybeasm maybe_attribute and
+	maybe_init if missing.  Rename maybe_raises to
+	exception_specification_opt to match draft wording.  Use maybe_init
+	to simplify rules.
+
+Fri Feb 17 01:54:46 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+	* init.c (build_new): Set TREE_NO_UNUSED_WARNING on COMPOUND_EXPRs
+	built for news of scalar types.
+
+Thu Feb 16 17:48:28 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+	* typeck.c (build_binary_op_nodefault): Update code for warning
+	about signed/unsigned comparisons from C frontend.  Realize that the
+	code in the C frontend is, if anything, even more bogus.  Fix it.
+	(build_binary_op): Undo default_conversion if it wasn't useful.
+
+	* typeck.c (build_unary_op, ADDR_EXPR): Lose bogus special case for
+	PRE*CREMENT_EXPR.
+
+	* decl2.c (import_export_vtable): Don't try the vtable hack
+	if the class doesn't have any real non-inline virtual functions.
+	(finish_vtable_vardecl): Don't bother trying to find a non-inline
+	virtual function in a non-polymorphic class.
+	(finish_prevtable_vardecl): Ditto.
+
+	* decl2.c (import_export_vtable): Use and set DECL_INTERFACE_KNOWN.
+
+	* cp-tree.h (DECL_INTERFACE_KNOWN): Use DECL_LANG_FLAG_5.
+
+	* init.c (expand_virtual_init): Always call assemble_external.
+
+	* class.c (build_vfn_ref): Always call assemble_external.
+	(build_vtable): Always call import_export_vtable.
+	(prepare_fresh_vtable): Ditto.
+	(add_virtual_function): Don't bother setting TREE_ADDRESSABLE.
+
 Thu Feb 16 03:28:49 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
 
 	* class.c (finish_struct): Use TYPE_{MIN,MAX}_VALUE to determine
diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in
index ab3f58b9e12bfffe46cf52d66033cbeedca94c9c..2e5f0136c68cf6442089c31ed52805939880f166 100644
--- a/gcc/cp/Makefile.in
+++ b/gcc/cp/Makefile.in
@@ -196,12 +196,12 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
 
 $(PARSE_H) : $(PARSE_C)
 $(PARSE_C) : $(srcdir)/parse.y
-	@echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts.
+	@echo expect 1 shift/reduce confict and 39 reduce/reduce conflicts.
 	cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y
 	cd $(srcdir); grep '^#define[ 	]*YYEMPTY' parse.c >>parse.h
 #$(PARSE_C) $(PARSE_H) : stamp-parse ; @true
 #stamp-parse: $(srcdir)/parse.y
-#	@echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts.
+#	@echo expect 1 shift/reduce confict and 39 reduce/reduce conflicts.
 #	$(BISON) $(BISONFLAGS) -d $(srcdir)/parse.y
 #	grep '^#define[ 	]*YYEMPTY' y.tab.c >>y.tab.h
 #	$(srcdir)/../move-if-change y.tab.c $(PARSE_C)
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index b5edebd54591de9abcfe6246a04f0aead1739231..b0332e9af76716852734eac0ce64a456329964aa 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -478,8 +478,7 @@ build_vfn_ref (ptr_to_instptr, instance, idx)
 	vtbl = build_indirect_ref (build_vfield_ref (instance, basetype),
 				   NULL_PTR);
     }
-  if (!flag_vtable_thunks)
-    assemble_external (vtbl);
+  assemble_external (vtbl);
   aref = build_array_ref (vtbl, idx);
 
   /* Save the intermediate result in a SAVE_EXPR so we don't have to
@@ -552,8 +551,7 @@ build_vtable (binfo, type)
 #endif
 
   /* Set TREE_PUBLIC and TREE_EXTERN as appropriate.  */
-  if (! flag_vtable_thunks)
-    import_export_vtable (decl, type);
+  import_export_vtable (decl, type, 0);
 
   IDENTIFIER_GLOBAL_VALUE (name) = decl = pushdecl_top_level (decl);
   /* Initialize the association list for this type, based
@@ -699,8 +697,7 @@ prepare_fresh_vtable (binfo, for_type)
 #endif
 
   /* Set TREE_PUBLIC and TREE_EXTERN as appropriate.  */
-  if (! flag_vtable_thunks)
-    import_export_vtable (new_decl, for_type);
+  import_export_vtable (new_decl, for_type, 0);
 
   if (TREE_VIA_VIRTUAL (binfo))
     my_friendly_assert (binfo == binfo_member (BINFO_TYPE (binfo),
@@ -803,9 +800,6 @@ add_virtual_function (pending_virtuals, has_virtual, fndecl, t)
 		fndecl);
 #endif
 
-  if (!flag_vtable_thunks)
-    TREE_ADDRESSABLE (fndecl) = CLASSTYPE_VTABLE_NEEDS_WRITING (t);
-
   /* If the virtual function is a redefinition of a prior one,
      figure out in which base class the new definition goes,
      and if necessary, make a fresh virtual function table
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4cb8af9e90ef8d0098004782549c513772bd3787..27b616aee0a1e0d7cfc8e1ffcc2b871a9333b1b2 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -954,10 +954,9 @@ struct lang_decl_flags
   unsigned saved_inline : 1;
   unsigned use_template : 2;
 
-  unsigned interface_known : 1;
   unsigned declared_static : 1;
   unsigned nonconverting : 1;
-  unsigned dummy : 5;
+  unsigned dummy : 6;
 
   tree access;
   tree context;
@@ -1131,7 +1130,7 @@ struct lang_decl
 
 #if 0
 /* Same, but tells if this field is private in current context.  */
-#define DECL_PRIVATE(NODE) (DECL_LANG_FLAG_5 (NODE))
+#define DECL_PRIVATE(NODE) (FOO)
 
 /* Same, but tells if this field is private in current context.  */
 #define DECL_PROTECTED(NODE) (DECL_LANG_FLAG_6 (NODE))
@@ -1337,8 +1336,7 @@ struct lang_decl
   (CLASSTYPE_USE_TEMPLATE(NODE) = 3)
 
 /* We know what we're doing with this decl now.  */
-#define DECL_INTERFACE_KNOWN(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.interface_known)
+#define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE)
 
 /* This decl was declared to have internal linkage.  */
 #define DECL_DECLARED_STATIC(NODE) \
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 32090e974a6a6ec9cfbcb134c1dd4192ee0ff958..b38f1db079ca66d87dbb3a27accbd629c735ea3d 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -144,10 +144,8 @@ int warn_implicit = 1;
 int warn_ctor_dtor_privacy = 1;
 
 /* True if we want to implement vtbvales using "thunks".
-   The default is off now, but will be on later.
+   The default is off now, but will be on later. */
 
-   Also causes output of vtables to be controlled by whether
-   we seen the class's first non-inline virtual function. */
 int flag_vtable_thunks;
 
 /* Nonzero means give string constants the type `const char *'
@@ -2466,23 +2464,61 @@ mark_vtable_entries (decl)
    it's public in this file or in another one.  */
 
 void
-import_export_vtable (decl, type)
-  tree decl, type;
+import_export_vtable (decl, type, final)
+     tree decl, type;
+     int final;
 {
-  if (write_virtuals >= 2
-      || CLASSTYPE_TEMPLATE_INSTANTIATION (type))
-    {
-      if (CLASSTYPE_INTERFACE_KNOWN (type))
-	{
-	  TREE_PUBLIC (decl) = 1;
-	  DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type);
-	}
-    }
-  else if (write_virtuals != 0)
+  if (DECL_INTERFACE_KNOWN (decl))
+    return;
+
+  /* +e0 or +e1 */
+  if (write_virtuals < 2 && write_virtuals != 0)
     {
       TREE_PUBLIC (decl) = 1;
       if (write_virtuals < 0)
 	DECL_EXTERNAL (decl) = 1;
+      DECL_INTERFACE_KNOWN (decl) = 1;
+    }
+  else if (CLASSTYPE_INTERFACE_KNOWN (type))
+    {
+      TREE_PUBLIC (decl) = 1;
+      DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type);
+      DECL_INTERFACE_KNOWN (decl) = 1;
+    }
+  else
+    {
+      /* We can only do this optimization if we have real non-inline
+	 virtual functions in our class, or if we come from a template.  */
+
+      int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type);
+
+      if (! found && ! final)
+	{
+	  /* This check only works before the method definitions are seen,
+	     since DECL_INLINE may get bashed.  */
+	  tree method;
+	  for (method = CLASSTYPE_METHODS (type); method != NULL_TREE;
+	       method = DECL_NEXT_METHOD (method))
+	    if (DECL_VINDEX (method) != NULL_TREE && ! DECL_INLINE (method)
+		&& ! DECL_ABSTRACT_VIRTUAL_P (method))
+	      {
+		found = 1;
+		break;
+	      }
+	}
+
+      if (final || ! found)
+	{
+	  TREE_PUBLIC (decl) = 0;
+	  DECL_EXTERNAL (decl) = 0;
+	  DECL_INTERFACE_KNOWN (decl) = 1;
+	}
+      else
+	{
+	  TREE_PUBLIC (decl) = 1;
+	  DECL_EXTERNAL (decl) = 1;
+	  DECL_INTERFACE_KNOWN (decl) = 0;
+	}
     }
 }
 
@@ -2506,9 +2542,8 @@ finish_prevtable_vardecl (prev, vars)
 {
   tree ctype = DECL_CONTEXT (vars);
   import_export_template (ctype);
-  import_export_vtable (vars, ctype);
 
-  if (CLASSTYPE_INTERFACE_UNKNOWN (ctype))
+  if (CLASSTYPE_INTERFACE_UNKNOWN (ctype) && TYPE_VIRTUAL_P (ctype))
     {
       tree method;
       for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE;
@@ -2520,13 +2555,13 @@ finish_prevtable_vardecl (prev, vars)
 	      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);
 	      break;
 	    }
 	}
     }
 
+  import_export_vtable (vars, ctype, 1);
+
   if (write_virtuals >= 0
       && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars)))
     {
@@ -2549,9 +2584,8 @@ finish_vtable_vardecl (prev, vars)
 {
   tree ctype = DECL_CONTEXT (vars);
   import_export_template (ctype);
-  import_export_vtable (vars, ctype);
 
-  if (CLASSTYPE_INTERFACE_UNKNOWN (ctype))
+  if (CLASSTYPE_INTERFACE_UNKNOWN (ctype) && TYPE_VIRTUAL_P (ctype))
     {
       tree method;
       for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE;
@@ -2563,8 +2597,6 @@ finish_vtable_vardecl (prev, vars)
 	      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;
@@ -2572,6 +2604,8 @@ finish_vtable_vardecl (prev, vars)
 	}
     }
 
+  import_export_vtable (vars, ctype, 1);
+
   if (write_virtuals >= 0
       && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars)))
     {
@@ -2612,7 +2646,7 @@ finish_vtable_vardecl (prev, vars)
 
       rest_of_decl_compilation (vars, NULL_PTR, 1, 1);
     }
-  else if (TREE_USED (vars) && flag_vtable_thunks)
+  else if (TREE_USED (vars))
     assemble_external (vars);
   /* We know that PREV must be non-zero here.  */
   TREE_CHAIN (prev) = TREE_CHAIN (vars);
@@ -3230,8 +3264,11 @@ tree
 reparse_decl_as_expr (type, decl)
      tree type, decl;
 {
-  decl = build_tree_list (NULL_TREE, reparse_decl_as_expr1 (decl));
-  return build_functional_cast (type, decl);
+  decl = reparse_decl_as_expr1 (decl);
+  if (type)
+    return build_functional_cast (type, build_tree_list (NULL_TREE, decl));
+  else
+    return decl;
 }
 
 /* This is something of the form `int (*a)' that has turned out to be a
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index cf8b0e7772a19825cf20c0754d3fe8a62174b45d..63a909cb457835a87e59fd8d58fae9ed8aa3fb85 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -730,8 +730,7 @@ expand_virtual_init (binfo, decl)
   vtype = DECL_CONTEXT (CLASSTYPE_VFIELD (type));
   vtype_binfo = get_binfo (vtype, TREE_TYPE (TREE_TYPE (decl)), 0);
   vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (type)), binfo));
-  if (!flag_vtable_thunks)
-    assemble_external (vtbl);
+  assemble_external (vtbl);
   TREE_USED (vtbl) = 1;
   vtbl = build1 (ADDR_EXPR, TYPE_POINTER_TO (TREE_TYPE (vtbl)), vtbl);
   decl = convert_pointer_to_real (vtype_binfo, decl);
@@ -3093,6 +3092,7 @@ build_new (placement, decl, init, use_global_new)
 	  rval = build (COMPOUND_EXPR, TREE_TYPE (rval),
 			build_modify_expr (deref, NOP_EXPR, init),
 			rval);
+	  TREE_NO_UNUSED_WARNING (rval) = 1;
 	  TREE_SIDE_EFFECTS (rval) = 1;
 	  TREE_CALLS_NEW (rval) = 1;
 	}
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 102ca63e131b81ab070c04d7aca361aa021577b1..b85ffc9d49926cf38c0c9a5f5fb96c8195ebe715 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -205,7 +205,7 @@ empty_parms ()
 %type <ttype> declmods typespec typespecqual_reserved
 %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
 %type <itype> initdecls notype_initdecls initdcl	/* C++ modification */
-%type <ttype> init initlist maybeasm
+%type <ttype> init initlist maybeasm maybe_init
 %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
 %type <ttype> maybe_attribute attributes attribute attribute_list attrib
 %type <ttype> any_word
@@ -244,7 +244,7 @@ empty_parms ()
 %type <ttype> class_head base_class_list
 %type <itype> base_class_access_list
 %type <ttype> base_class maybe_base_class_list base_class.1
-%type <ttype> maybe_raises ansi_raise_identifier ansi_raise_identifiers
+%type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers
 %type <ttype> component_declarator0
 %type <ttype> forhead.1 operator_name
 %type <ttype> object aggr
@@ -495,7 +495,7 @@ template_def:
 		  /* declare $2 as template name with $1 parm list */
 		}
 	| template_header /* notype_initdcl0 ';' */
-	  notype_declarator maybe_raises maybeasm maybe_attribute
+	  notype_declarator exception_specification_opt maybeasm maybe_attribute
 	  fn_tmpl_end
 		{
 		  tree d;
@@ -512,7 +512,7 @@ template_def:
 		  resume_momentary (momentary);
 		}
 	| template_header typed_declspecs /*initdcl0*/
-	  declarator maybe_raises maybeasm maybe_attribute
+	  declarator exception_specification_opt maybeasm maybe_attribute
 	  fn_tmpl_end
 		{
 		  tree d;
@@ -649,17 +649,17 @@ fndef:
 	;
 
 fn.def1:
-	  typed_declspecs declarator maybe_raises
+	  typed_declspecs declarator exception_specification_opt
 		{ if (! start_function ($$, $2, $3, 0))
 		    YYERROR1;
 		  reinit_parse_for_function ();
 		  $$ = NULL_TREE; }
-	| declmods notype_declarator maybe_raises
+	| declmods notype_declarator exception_specification_opt
 		{ if (! start_function ($$, $2, $3, 0))
 		    YYERROR1;
 		  reinit_parse_for_function ();
 		  $$ = NULL_TREE; }
-	| notype_declarator maybe_raises
+	| notype_declarator exception_specification_opt
 		{ if (! start_function (NULL_TREE, $$, $2, 0))
 		    YYERROR1;
 		  reinit_parse_for_function ();
@@ -672,7 +672,7 @@ fn.def1:
 /* more C++ complexity.  See component_decl for a comment on the
    reduce/reduce conflict introduced by these rules.  */
 fn.def2:
-	  typed_declspecs '(' parmlist ')' type_quals maybe_raises
+	  typed_declspecs '(' parmlist ')' type_quals exception_specification_opt
 		{
 		  $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5);
 		  $$ = start_method (TREE_CHAIN ($1), $$, $6);
@@ -682,18 +682,18 @@ fn.def2:
 		  if (yychar == YYEMPTY)
 		    yychar = YYLEX;
 		  reinit_parse_for_method (yychar, $$); }
-	| typed_declspecs LEFT_RIGHT type_quals maybe_raises
+	| typed_declspecs LEFT_RIGHT type_quals exception_specification_opt
 		{
 		  $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
 					 empty_parms (), $3);
 		  $$ = start_method (TREE_CHAIN ($1), $$, $4);
 		  goto rest_of_mdef;
 		}
-	| typed_declspecs declarator maybe_raises
+	| typed_declspecs declarator exception_specification_opt
 		{ $$ = start_method ($$, $2, $3); goto rest_of_mdef; }
-	| declmods notype_declarator maybe_raises
+	| declmods notype_declarator exception_specification_opt
 		{ $$ = start_method ($$, $2, $3); goto rest_of_mdef; }
-	| notype_declarator maybe_raises
+	| notype_declarator exception_specification_opt
 		{ $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; }
 	;
 
@@ -705,10 +705,8 @@ return_id: RETURN IDENTIFIER
 		}
 	;
 
-return_init: return_id
-		{ store_return_init ($<ttype>$, NULL_TREE); }
-	| return_id '=' init
-		{ store_return_init ($<ttype>$, $3); }
+return_init: return_id maybe_init
+		{ store_return_init ($<ttype>$, $2); }
 	| return_id '(' nonnull_exprlist ')'
 		{ store_return_init ($<ttype>$, $3); }
 	| return_id LEFT_RIGHT
@@ -962,7 +960,7 @@ xcond:
 	;
 
 condition:
-	type_specifier_seq declarator maybe_raises maybeasm maybe_attribute '='
+	type_specifier_seq declarator exception_specification_opt maybeasm maybe_attribute '='
 		{ {
 		  tree d;
 		  for (d = getdecls (); d; d = TREE_CHAIN (d))
@@ -1334,12 +1332,21 @@ primary:
 	| string
 		{ $$ = combine_strings ($$); }
 	| '(' expr ')'
-		{ char class = TREE_CODE_CLASS (TREE_CODE ($2));
+		{ char class;
+		  $$ = $2;
+		  class = TREE_CODE_CLASS (TREE_CODE ($$));
+		  if (class == 'e' || class == '1'
+		      || class == '2' || class == '<')
+                    /* This inhibits warnings in truthvalue_conversion. */
+		    C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); }
+	| '(' expr_or_declarator ')'
+		{ char class;
+		  $$ = reparse_decl_as_expr (NULL_TREE, $2);
+		  class = TREE_CODE_CLASS (TREE_CODE ($$));
 		  if (class == 'e' || class == '1'
 		      || class == '2' || class == '<')
                     /* This inhibits warnings in truthvalue_conversion. */
-		    C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK);
-		  $$ = $2; }
+		    C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); }
 	| '(' error ')'
 		{ $$ = error_mark_node; }
 	| '('
@@ -1948,7 +1955,7 @@ maybeasm:
 	;
 
 initdcl0:
-	  declarator maybe_raises maybeasm maybe_attribute '='
+	  declarator exception_specification_opt maybeasm maybe_attribute '='
 		{ current_declspecs = $<ttype>0;
 		  if (TREE_CODE (current_declspecs) != TREE_LIST)
 		    current_declspecs = get_decl_list (current_declspecs);
@@ -1966,7 +1973,7 @@ initdcl0:
 /* Note how the declaration of the variable is in effect while its init is parsed! */
 		{ finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING);
 		  $$ = $<itype>5; }
-	| declarator maybe_raises maybeasm maybe_attribute
+	| declarator exception_specification_opt maybeasm maybe_attribute
 		{ tree d;
 		  current_declspecs = $<ttype>0;
 		  if (TREE_CODE (current_declspecs) != TREE_LIST)
@@ -1985,20 +1992,20 @@ initdcl0:
 	;
 
 initdcl:
-	  declarator maybe_raises maybeasm maybe_attribute '='
+	  declarator exception_specification_opt maybeasm maybe_attribute '='
 		{ $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2);
 		  cplus_decl_attributes ($<ttype>$, $4); }
 	  init
 /* Note how the declaration of the variable is in effect while its init is parsed! */
 		{ finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING); }
-	| declarator maybe_raises maybeasm maybe_attribute
+	| declarator exception_specification_opt maybeasm maybe_attribute
 		{ $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, $2);
 		  cplus_decl_attributes ($<ttype>$, $4);
 		  finish_decl ($<ttype>$, NULL_TREE, $3, 0, 0); }
 	;
 
 notype_initdcl0:
-	  notype_declarator maybe_raises maybeasm maybe_attribute '='
+	  notype_declarator exception_specification_opt maybeasm maybe_attribute '='
 		{ current_declspecs = $<ttype>0;
 		  $<itype>5 = suspend_momentary ();
 		  $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2);
@@ -2007,7 +2014,7 @@ notype_initdcl0:
 /* Note how the declaration of the variable is in effect while its init is parsed! */
 		{ finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING);
 		  $$ = $<itype>5; }
-	| notype_declarator maybe_raises maybeasm maybe_attribute
+	| notype_declarator exception_specification_opt maybeasm maybe_attribute
 		{ tree d;
 		  current_declspecs = $<ttype>0;
 		  $$ = suspend_momentary ();
@@ -2017,7 +2024,7 @@ notype_initdcl0:
 	;
 
 nomods_initdcl0:
-	  notype_declarator maybe_raises maybeasm maybe_attribute '='
+	  notype_declarator exception_specification_opt maybeasm maybe_attribute '='
 		{ current_declspecs = NULL_TREE;
 		  $<itype>5 = suspend_momentary ();
 		  $<ttype>$ = start_decl ($1, current_declspecs, 1, $2);
@@ -2026,7 +2033,7 @@ nomods_initdcl0:
 /* Note how the declaration of the variable is in effect while its init is parsed! */
 		{ finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING);
 		  $$ = $<itype>5; }
-	| notype_declarator maybe_raises maybeasm maybe_attribute
+	| notype_declarator exception_specification_opt maybeasm maybe_attribute
 		{ tree d;
 		  current_declspecs = NULL_TREE;
 		  $$ = suspend_momentary ();
@@ -2094,6 +2101,12 @@ identifiers_or_typenames:
 		{ $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
 	;
 
+maybe_init:
+	%prec EMPTY /* empty */
+		{ $$ = NULL_TREE; }
+	| '=' init
+		{ $$ = $2; }
+
 init:
 	  expr_no_commas %prec '='
 	| '{' '}'
@@ -2593,8 +2606,8 @@ component_decl_1:
 		{ 
 		  $$ = grok_x_components ($$, $2);
 		}
-	| notype_declarator maybe_raises maybeasm maybe_attribute
-		{ $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, $3);
+	| notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
+		{ $$ = grokfield ($$, NULL_TREE, $2, $5, $3);
 		  cplus_decl_attributes ($$, $4); }
 	| ':' expr_no_commas
 		{ $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
@@ -2609,16 +2622,16 @@ component_decl_1:
 	   should "A::foo" be declared as a function or "A::bar" as a data
 	   member? In other words, is "bar" an after_type_declarator or a
 	   parmlist? */
-	| typed_declspecs '(' parmlist ')' type_quals
+	| typed_declspecs '(' parmlist ')' type_quals exception_specification_opt maybeasm maybe_attribute maybe_init
 		{ $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
 					 $3, $5);
-		  $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE,
-				  NULL_TREE); }
-	| typed_declspecs LEFT_RIGHT type_quals
+		  $$ = grokfield ($$, TREE_CHAIN ($1), $6, $9, $7);
+		  cplus_decl_attributes ($$, $8); }
+	| typed_declspecs LEFT_RIGHT type_quals exception_specification_opt maybeasm maybe_attribute maybe_init
 		{ $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
 					 empty_parms (), $3);
-		  $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE,
-				  NULL_TREE); }
+		  $$ = grokfield ($$, TREE_CHAIN ($1), $4, $7, $5);
+		  cplus_decl_attributes ($$, $6); }
 	| using_decl
 	;
 
@@ -2664,13 +2677,9 @@ component_declarator:
 	;
 
 after_type_component_declarator0:
-	  after_type_declarator maybe_raises maybeasm maybe_attribute
-		{ current_declspecs = $<ttype>0;
-		  $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
-		  cplus_decl_attributes ($$, $4); }
-	| after_type_declarator maybe_raises maybeasm maybe_attribute '=' init
+	  after_type_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
 		{ current_declspecs = $<ttype>0;
-		  $$ = grokfield ($$, current_declspecs, $2, $6, $3);
+		  $$ = grokfield ($$, current_declspecs, $2, $5, $3);
 		  cplus_decl_attributes ($$, $4); }
 	| TYPENAME ':' expr_no_commas maybe_attribute
 		{ current_declspecs = $<ttype>0;
@@ -2679,13 +2688,9 @@ after_type_component_declarator0:
 	;
 
 notype_component_declarator0:
-	  notype_declarator maybe_raises maybeasm maybe_attribute
-		{ current_declspecs = $<ttype>0;
-		  $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
-		  cplus_decl_attributes ($$, $4); }
-	| notype_declarator maybe_raises maybeasm maybe_attribute '=' init
+	  notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
 		{ current_declspecs = $<ttype>0;
-		  $$ = grokfield ($$, current_declspecs, $2, $6, $3);
+		  $$ = grokfield ($$, current_declspecs, $2, $5, $3);
 		  cplus_decl_attributes ($$, $4); }
 	| IDENTIFIER ':' expr_no_commas maybe_attribute
 		{ current_declspecs = $<ttype>0;
@@ -2698,11 +2703,8 @@ notype_component_declarator0:
 	;
 
 after_type_component_declarator:
-	  after_type_declarator maybe_raises maybeasm maybe_attribute
-		{ $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
-		  cplus_decl_attributes ($$, $4); }
-	| after_type_declarator maybe_raises maybeasm maybe_attribute '=' init
-		{ $$ = grokfield ($$, current_declspecs, $2, $6, $3);
+	  after_type_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
+		{ $$ = grokfield ($$, current_declspecs, $2, $5, $3);
 		  cplus_decl_attributes ($$, $4); }
 	| TYPENAME ':' expr_no_commas maybe_attribute
 		{ $$ = grokbitfield ($$, current_declspecs, $3);
@@ -2710,11 +2712,8 @@ after_type_component_declarator:
 	;
 
 notype_component_declarator:
-	  notype_declarator maybe_raises maybeasm maybe_attribute
-		{ $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
-		  cplus_decl_attributes ($$, $4); }
-	| notype_declarator maybe_raises maybeasm maybe_attribute '=' init
-		{ $$ = grokfield ($$, current_declspecs, $2, $6, $3);
+	  notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
+		{ $$ = grokfield ($$, current_declspecs, $2, $5, $3);
 		  cplus_decl_attributes ($$, $4); }
 	| IDENTIFIER ':' expr_no_commas maybe_attribute
 		{ $$ = grokbitfield ($$, current_declspecs, $3);
@@ -3702,10 +3701,8 @@ named_parm:
 	;
 
 full_parm:
-	  parm
-		{ $$ = build_tree_list (NULL_TREE, $$); }
-	| parm '=' init
-		{ $$ = build_tree_list ($3, $$); }
+	  parm maybe_init
+		{ $$ = build_tree_list ($2, $$); }
 	;
 
 parm:
@@ -3748,7 +3745,7 @@ bad_parm:
 		}
 	;
 
-maybe_raises:
+exception_specification_opt:
 	  %prec EMPTY /* empty */
 		{ $$ = NULL_TREE; }
 	| THROW '(' ansi_raise_identifiers  ')' %prec EMPTY
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index d36fa8d1ac856d7d8f928044a9d344a7d99f5aca..b21bbe94567fbced996377bdec94850397d22047 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2723,8 +2723,9 @@ build_binary_op (code, arg1, arg2, convert_p)
 
   if (convert_p)
     {
-      args[0] = default_conversion (args[0]);
-      args[1] = default_conversion (args[1]);
+      tree args_save [2];
+      args[0] = args_save [0] = default_conversion (args[0]);
+      args[1] = args_save [1] = default_conversion (args[1]);
 
       if (type_unknown_p (args[0]))
 	{
@@ -2780,6 +2781,11 @@ build_binary_op (code, arg1, arg2, convert_p)
 	    error ("ambiguous pointer conversion");
 	  args[convert_index] = try;
 	}
+
+      if (args[0] == args_save[0])
+	args[0] = arg1;
+      if (args[1] == args_save[1])
+	args[1] = arg2;
     }
   return build_binary_op_nodefault (code, args[0], args[1], code);
 }
@@ -3457,19 +3463,34 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
 
       if (short_compare && extra_warnings)
 	{
+	  int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
+	  int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
+
+	  tree comp_type = TREE_TYPE (op0);
+
 	  int unsignedp0, unsignedp1;
 	  tree primop0 = get_narrower (op0, &unsignedp0);
 	  tree primop1 = get_narrower (op1, &unsignedp1);
 
-	  /* Warn if signed and unsigned are being compared in a size larger
-	     than their original size, as this will always fail.  */
-
-	  if (unsignedp0 != unsignedp1
-	      && (TYPE_PRECISION (TREE_TYPE (primop0))
-		  < TYPE_PRECISION (result_type))
-	      && (TYPE_PRECISION (TREE_TYPE (primop1))
-		  < TYPE_PRECISION (result_type)))
-	    warning ("comparison between promoted unsigned and signed");
+	  /* Give warnings for comparisons between signed and unsigned
+	     quantities that may fail.  Do not warn if the signed quantity
+	     is an unsuffixed integer literal (or some static constant
+	     expression involving such literals) and it is positive.
+	     Do not warn if the comparison is being done in a signed type,
+	     since the signed type will only be chosen if it can represent
+	     all the values of the unsigned type.  */
+	  /* Do the checking based on the original operand trees, so that
+	     casts will be considered, but default promotions won't be.  */
+	  if (TREE_UNSIGNED (comp_type)
+	      && ((op0_signed
+		   && (TREE_CODE (op0) != INTEGER_CST
+		       || (TREE_CODE (op0) == INTEGER_CST
+			   && INT_CST_LT (op0, integer_zero_node))))
+		  || (op1_signed
+		      && (TREE_CODE (op1) != INTEGER_CST
+			  || (TREE_CODE (op1) == INTEGER_CST
+			      && INT_CST_LT (op1, integer_zero_node))))))
+	    warning ("comparison between signed and unsigned");
 
 	  /* Warn if two unsigned values are being compared in a size
 	     larger than their original size, and one (and only one) is the
@@ -3509,7 +3530,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
 		    }
 
 		  bits = TYPE_PRECISION (TREE_TYPE (primop));
-		  if (bits < TYPE_PRECISION (result_type)
+		  if (bits < TYPE_PRECISION (comp_type)
 		      && bits < HOST_BITS_PER_LONG && unsignedp)
 		    {
 		      mask = (~ (HOST_WIDE_INT) 0) << bits;
@@ -3519,9 +3540,9 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
 		}
 	      else if (unsignedp0 && unsignedp1
 		       && (TYPE_PRECISION (TREE_TYPE (primop0))
-			   < TYPE_PRECISION (result_type))
+			   < TYPE_PRECISION (comp_type))
 		       && (TYPE_PRECISION (TREE_TYPE (primop1))
-			   < TYPE_PRECISION (result_type)))
+			   < TYPE_PRECISION (comp_type)))
 		warning ("comparison of promoted ~unsigned with unsigned");
 	    }
 	}
@@ -4120,15 +4141,6 @@ build_unary_op (code, xarg, noconvert)
 				  TREE_OPERAND (arg, 1), 1);
 	}
 
-      /* For &(++foo), we are really taking the address of the variable
-	 being acted upon by the increment/decrement operator.  ARM $5.3.1
-	 However, according to ARM $5.2.5, we don't allow postfix ++ and
-	 --, since the prefix operators return lvalues, but the postfix
-	 operators do not.  */
-      if (TREE_CODE (arg) == PREINCREMENT_EXPR
-	  || TREE_CODE (arg) == PREDECREMENT_EXPR)
-	arg = TREE_OPERAND (arg, 0);
-
       /* Uninstantiated types are all functions.  Taking the
 	 address of a function is a no-op, so just return the
 	 argument.  */