OSDN Git Service

57 Cygnus<->FSF merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 18 Feb 1995 22:06:40 +0000 (22:06 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 18 Feb 1995 22:06:40 +0000 (22:06 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@8971 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/Makefile.in
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/init.c
gcc/cp/parse.y
gcc/cp/typeck.c

index a092c8d..df22c23 100644 (file)
@@ -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
index ab3f58b..2e5f013 100644 (file)
@@ -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)
index b5edebd..b0332e9 100644 (file)
@@ -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
index 4cb8af9..27b616a 100644 (file)
@@ -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) \
index 32090e9..b38f1db 100644 (file)
@@ -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
index cf8b0e7..63a909c 100644 (file)
@@ -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;
        }
index 102ca63..b85ffc9 100644 (file)
@@ -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
index d36fa8d..b21bbe9 100644 (file)
@@ -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.  */