langhooks-def.h (LANG_HOOKS_EXPR_SIZE): New macro.
authorJason Merrill <jason@redhat.com>
Fri, 2 Aug 2002 11:57:22 +0000 (07:57 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 2 Aug 2002 11:57:22 +0000 (07:57 -0400)
        * langhooks-def.h (LANG_HOOKS_EXPR_SIZE): New macro.
        * langhooks.c (lhd_expr_size): Define default.
        * langhooks.h (struct lang_hooks): Add expr_size.
        * explow.c (expr_size): Call it.
        * expr.c (store_expr): Don't copy an expression of size zero.
        (expand_expr) [CONSTRUCTOR]: Use expr_size to calculate how much
        to store.
        * Makefile.in (builtins.o): Depend on langhooks.h.

        * cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
        (cp_expr_size): New fn.
        * call.c (build_over_call): Lose empty class hackery.
        (convert_arg_to_ellipsis): Promote non-POD warning to error.
        * typeck.c (build_modify_expr): Don't use save_expr on an lvalue.

From-SVN: r55983

gcc/ChangeLog
gcc/Makefile.in
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-lang.c
gcc/cp/typeck.c
gcc/explow.c
gcc/expr.c
gcc/langhooks-def.h
gcc/langhooks.c
gcc/langhooks.h

index 579e1dfc6b8ce6b492d5e69ced277a77a8950d69..6480ba94aeffb8b501a1f17eab0cac3af17bc34e 100644 (file)
@@ -1,3 +1,14 @@
+2002-08-02  Jason Merrill  <jason@redhat.com>
+
+       * langhooks-def.h (LANG_HOOKS_EXPR_SIZE): New macro.
+       * langhooks.c (lhd_expr_size): Define default.
+       * langhooks.h (struct lang_hooks): Add expr_size.
+       * explow.c (expr_size): Call it.
+       * expr.c (store_expr): Don't copy an expression of size zero.
+       (expand_expr) [CONSTRUCTOR]: Use expr_size to calculate how much
+       to store.
+       * Makefile.in (builtins.o): Depend on langhooks.h.
+
 2002-08-02  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * Makefile.in (ra-debug.o): Depend on $(TM_P_H).
index 75ba49c251b393cf2ec8b62b56b61a02705e50cc..c27b5d8f75ace3d04133d69b68458c1a4dc874e4 100644 (file)
@@ -1427,7 +1427,7 @@ expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \
 builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
    $(TARGET_H) function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) insn-config.h \
    $(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
-   except.h $(TM_P_H) $(PREDICT_H) libfuncs.h real.h
+   except.h $(TM_P_H) $(PREDICT_H) libfuncs.h real.h langhooks.h
 calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
    $(EXPR_H) langhooks.h \
    libfuncs.h $(REGS_H) toplev.h output.h function.h $(TIMEVAR_H) $(TM_P_H)
index f9e22ca2388ba4803b0d06f3b1257a032889ad9c..e4def020fb70a339900c0526b346edfbd149c041 100644 (file)
@@ -1,5 +1,11 @@
 2002-08-02  Jason Merrill  <jason@redhat.com>
 
+       * cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
+       (cp_expr_size): New fn.
+       * call.c (build_over_call): Lose empty class hackery.
+       (convert_arg_to_ellipsis): Promote non-POD warning to error.
+       * typeck.c (build_modify_expr): Don't use save_expr on an lvalue.
+
        * semantics.c (expand_body): Do tree optimization in the function
        context, too.
 
index 403d8b53ee3265bd9ee69149714a0218cd45477e..9029a7072dca319719a19ef99c2853090bc23c50 100644 (file)
@@ -4111,9 +4111,12 @@ convert_arg_to_ellipsis (arg)
   
   if (arg != error_mark_node && ! pod_type_p (TREE_TYPE (arg)))
     {
-      /* Undefined behaviour [expr.call] 5.2.2/7.  */
-      warning ("cannot pass objects of non-POD type `%#T' through `...'",
-                 TREE_TYPE (arg));
+      /* Undefined behaviour [expr.call] 5.2.2/7.  We used to just warn
+        here and do a bitwise copy, but now cp_expr_size will abort if we
+        try to do that.  */
+      error ("cannot pass objects of non-POD type `%#T' through `...'",
+            TREE_TYPE (arg));
+      arg = error_mark_node;
     }
 
   return arg;
@@ -4436,15 +4439,8 @@ build_over_call (cand, args, flags)
          else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
            return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
        }
-      else if ((!real_lvalue_p (arg)
-               || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
-              /* Empty classes have padding which can be hidden
-                 inside an (empty) base of the class. This must not
-                 be touched as it might overlay things. When the
-                 gcc core learns about empty classes, we can treat it
-                 like other classes. */
-              && !(is_empty_class (DECL_CONTEXT (fn))
-                   && TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))))
+      else if (!real_lvalue_p (arg)
+              || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
        {
          tree address;
          tree to = stabilize_reference
@@ -4466,24 +4462,7 @@ build_over_call (cand, args, flags)
        (build_indirect_ref (TREE_VALUE (converted_args), 0));
 
       arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0);
-      if (is_empty_class (TREE_TYPE (to)))
-       {
-         TREE_USED (arg) = 1;
-
-         val = build (COMPOUND_EXPR, DECL_CONTEXT (fn), arg, to);
-         /* Even though the assignment may not actually result in any
-            code being generated, we do not want to warn about the
-            assignment having no effect.  That would be confusing to
-            users who may be performing the assignment as part of a
-            generic algorithm, for example.
-            
-            Ideally, the notions of having side-effects and of being
-            useless would be orthogonal.  */
-         TREE_SIDE_EFFECTS (val) = 1;
-         TREE_NO_UNUSED_WARNING (val) = 1;
-       }
-      else
-       val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
+      val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
       return val;
     }
 
index a44d4b6b8a19f10df861631416044a4f63098075..024534e2831706cdc27d405bb08aafd1b90fbb7f 100644 (file)
@@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA.  */
 static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
 static bool ok_to_generate_alias_set_for_type PARAMS ((tree));
 static bool cxx_warn_unused_global_decl PARAMS ((tree));
+static tree cp_expr_size PARAMS ((tree));
 
 #undef LANG_HOOKS_NAME
 #define LANG_HOOKS_NAME "GNU C++"
@@ -133,6 +134,8 @@ static bool cxx_warn_unused_global_decl PARAMS ((tree));
 #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree
 #undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN
 #define LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN cp_type_quals
+#undef LANG_HOOKS_EXPR_SIZE
+#define LANG_HOOKS_EXPR_SIZE cp_expr_size
 
 #undef LANG_HOOKS_MAKE_TYPE
 #define LANG_HOOKS_MAKE_TYPE cxx_make_type
@@ -280,3 +283,28 @@ cxx_warn_unused_global_decl (decl)
 
   return true;
 }
+
+/* Langhook for expr_size: Tell the backend that the value of an expression
+   of non-POD class type does not include any tail padding; a derived class
+   might have allocated something there.  */
+
+static tree
+cp_expr_size (exp)
+     tree exp;
+{
+  if (CLASS_TYPE_P (TREE_TYPE (exp)))
+    {
+      /* The backend should not be interested in the size of an expression
+        of a type with both of these set; all copies of such types must go
+        through a constructor or assignment op.  */
+      if (TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (exp))
+         && TYPE_HAS_COMPLEX_ASSIGN_REF (TREE_TYPE (exp)))
+       abort ();
+      /* This would be wrong for a type with virtual bases, but they are
+        caught by the abort above.  */
+      return CLASSTYPE_SIZE_UNIT (TREE_TYPE (exp));
+    }
+  else
+    /* Use the default code.  */
+    return lhd_expr_size (exp);
+}
index def5e687509b0b5904b1658b19678052cdcbd6e4..965f3f4399d8468d9f5a5a3856ca003e12fb43e5 100644 (file)
@@ -5077,8 +5077,9 @@ build_modify_expr (lhs, modifycode, rhs)
           except that the RHS goes through a save-expr
           so the code to compute it is only emitted once.  */
        tree cond;
+       tree preeval = NULL_TREE;
 
-       rhs = save_expr (rhs);
+       rhs = stabilize_expr (rhs, &preeval);
        
        /* Check this here to avoid odd errors when trying to convert
           a throw to the type of the COND_EXPR.  */
@@ -5098,10 +5099,7 @@ build_modify_expr (lhs, modifycode, rhs)
          return cond;
        /* Make sure the code to compute the rhs comes out
           before the split.  */
-       return build (COMPOUND_EXPR, TREE_TYPE (lhs),
-                     /* Cast to void to suppress warning
-                        from warn_if_unused_value.  */
-                     cp_convert (void_type_node, rhs), cond);
+       return build (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
       }
       
     case OFFSET_REF:
index 3cda410467232e6bd142c211b83ba17dfe353f41..5bc34517e8e303ddecfc3a7dad2aa5972231e7e4 100644 (file)
@@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "insn-config.h"
 #include "ggc.h"
 #include "recog.h"
+#include "langhooks.h"
 
 static rtx break_out_memory_refs       PARAMS ((rtx));
 static void emit_stack_probe           PARAMS ((rtx));
@@ -285,20 +286,13 @@ rtx
 expr_size (exp)
      tree exp;
 {
-  tree size;
-
-  if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
-      && DECL_SIZE_UNIT (exp) != 0)
-    size = DECL_SIZE_UNIT (exp);
-  else
-    size = size_in_bytes (TREE_TYPE (exp));
+  tree size = (*lang_hooks.expr_size) (exp);
 
   if (TREE_CODE (size) != INTEGER_CST
       && contains_placeholder_p (size))
     size = build (WITH_RECORD_EXPR, sizetype, size, exp);
 
   return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
-
 }
 \f
 /* Return a copy of X in which all memory references
index 4aa0195dfb06503e7ef9e9020354ef121b1b9174..dddd26877709b88b1081679c6d0fbce2bd8e9ada 100644 (file)
@@ -4241,6 +4241,8 @@ store_expr (exp, target, want_value)
        || (temp != target && (side_effects_p (temp)
                              || side_effects_p (target))))
       && TREE_CODE (exp) != ERROR_MARK
+      /* If there's nothing to copy, don't bother.  */
+      && expr_size (exp) != const0_rtx
       && ! dont_store_target
         /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
            but TARGET is not valid memory reference, TEMP will differ
@@ -6810,8 +6812,7 @@ expand_expr (exp, target, tmode, modifier)
                                                       * TYPE_QUAL_CONST))),
                             0, TREE_ADDRESSABLE (exp), 1);
 
-         store_constructor (exp, target, 0,
-                            int_size_in_bytes (TREE_TYPE (exp)));
+         store_constructor (exp, target, 0, INTVAL (expr_size (exp)));
          return target;
        }
 
index 246fea93214a4d6b4ca06968b32f5e4515127b97..d8628513559ef55c6a562a392255d8df3c0b71c3 100644 (file)
@@ -62,6 +62,7 @@ extern void lhd_set_decl_assembler_name PARAMS ((tree));
 extern bool lhd_warn_unused_global_decl PARAMS ((tree));
 extern void lhd_incomplete_type_error PARAMS ((tree, tree));
 extern tree lhd_type_promotes_to PARAMS ((tree));
+extern tree lhd_expr_size PARAMS ((tree));
 
 /* Declarations of default tree inlining hooks.  */
 tree lhd_tree_inlining_walk_subtrees           PARAMS ((tree *, int *,
@@ -109,6 +110,7 @@ tree lhd_tree_inlining_convert_parm_for_inlining PARAMS ((tree, tree, tree));
 #define LANG_HOOKS_PRINT_IDENTIFIER    lhd_print_tree_nothing
 #define LANG_HOOKS_PRINT_ERROR_FUNCTION lhd_print_error_function
 #define LANG_HOOKS_DECL_PRINTABLE_NAME lhd_decl_printable_name
+#define LANG_HOOKS_EXPR_SIZE           lhd_expr_size
 
 #define LANG_HOOKS_FUNCTION_INIT       lhd_do_nothing_f
 #define LANG_HOOKS_FUNCTION_FINAL      lhd_do_nothing_f
@@ -247,6 +249,7 @@ int lhd_tree_dump_type_quals                        PARAMS ((tree));
   LANG_HOOKS_PRINT_IDENTIFIER, \
   LANG_HOOKS_DECL_PRINTABLE_NAME, \
   LANG_HOOKS_PRINT_ERROR_FUNCTION, \
+  LANG_HOOKS_EXPR_SIZE, \
   LANG_HOOKS_ATTRIBUTE_TABLE, \
   LANG_HOOKS_COMMON_ATTRIBUTE_TABLE, \
   LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE, \
index 79eb7f4c2ec47276f9cfb962b88c61ca8933e108..e2feb06736040ab135df139a0af99343dcc6c2b5 100644 (file)
@@ -421,3 +421,17 @@ lhd_tree_dump_type_quals (t)
 {
   return TYPE_QUALS (t);
 }
+
+/* lang_hooks.expr_size: Determine the size of the value of an expression T
+   in a language-specific way.  Returns a tree for the size in bytes.  */
+
+tree
+lhd_expr_size (exp)
+     tree exp;
+{
+  if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
+      && DECL_SIZE_UNIT (exp) != 0)
+    return DECL_SIZE_UNIT (exp);
+  else
+    return size_in_bytes (TREE_TYPE (exp));
+}
index 0ec3c88c29d880d44f604f9fe421a43b9a575021..7ddd32c88f7c7166d26c265407975148a421e826 100644 (file)
@@ -328,6 +328,12 @@ struct lang_hooks
   void (*print_error_function) PARAMS ((struct diagnostic_context *,
                                        const char *));
 
+  /* Called from expr_size to calculate the size of the value of an
+     expression in a language-dependent way.  Returns a tree for the size
+     in bytes.  A frontend can call lhd_expr_size to get the default
+     semantics in cases that it doesn't want to handle specially.  */
+  tree (*expr_size) PARAMS ((tree));
+
   /* Pointers to machine-independent attribute tables, for front ends
      using attribs.c.  If one is NULL, it is ignored.  Respectively, a
      table of attributes specific to the language, a table of