]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/5607 (No pointer adjustment in covariant return types)
authorJason Merrill <jason@redhat.com>
Fri, 23 Aug 2002 12:00:43 +0000 (08:00 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 23 Aug 2002 12:00:43 +0000 (08:00 -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.
        (int_expr_size): New fn.
        * expr.h: Declare it.
        * expr.c (expand_expr) [CONSTRUCTOR]: Use it to calculate how
        much to store.
cp/
        PR c++/5607
        * search.c (check_final_overrider): No longer static.
        * class.c (update_vtable_entry_for_fn): Call it.
        * cp-tree.h: Adjust.

        * cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
        (cp_expr_size): New fn.
        * call.c (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: r56539

14 files changed:
gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-lang.c
gcc/cp/cp-tree.h
gcc/cp/search.c
gcc/cp/typeck.c
gcc/explow.c
gcc/expr.c
gcc/expr.h
gcc/langhooks-def.h
gcc/langhooks.c
gcc/langhooks.h

index ea095095199a2840fed1d43b9baa7168213b5199..ba97b86d670a8cd7d272c66a18093017cd11369c 100644 (file)
@@ -1,3 +1,14 @@
+2002-08-22  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.
+       (int_expr_size): New fn.
+       * expr.h: Declare it.
+       * expr.c (expand_expr) [CONSTRUCTOR]: Use it to calculate how 
+       much to store.
+
 2002-08-23  Alan Modra  <amodra@bigpond.net.au>
 
        * config/rs6000/rs6000.c (output_mi_thunk): Don't determine insns
index ac16fcd2c9f6cec6484a0eb742fe0ae7abfbc7e7..8e84fe6f62e53b55ebfec331701076a316f47549 100644 (file)
@@ -1,3 +1,15 @@
+2002-08-22  Jason Merrill  <jason@redhat.com>
+
+       PR c++/5607
+       * search.c (check_final_overrider): No longer static.
+       * class.c (update_vtable_entry_for_fn): Call it.
+       * cp-tree.h: Adjust.
+
+       * cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
+       (cp_expr_size): New fn.
+       * call.c (convert_arg_to_ellipsis): Promote non-POD warning to error.
+       * typeck.c (build_modify_expr): Don't use save_expr on an lvalue.
+
 2002-08-14  Release Manager
 
        * GCC 3.2 Released.
index 5527066a39e45c7147dbfeb12fac603c5f88cacc..c8dcaf021189a97ea0842b315df7a86f982ed7ae 100644 (file)
@@ -4022,9 +4022,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;
index 279072669b6804b6608342dc9d61c4c50f2e1da4..f655846e060c5ceb0a8081b3cb60157e5721e85e 100644 (file)
@@ -2454,6 +2454,10 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
   if (overrider == error_mark_node)
     return;
 
+  /* Check for unsupported covariant returns again now that we've
+     calculated the base offsets.  */
+  check_final_overrider (TREE_PURPOSE (overrider), fn);
+
   /* Assume that we will produce a thunk that convert all the way to
      the final overrider, and not to an intermediate virtual base.  */
   virtual_base = NULL_TREE;
index 931523e8e012e116214da381fb0bb0eb2981639c..7b1d860a08e65c98ac0217c91e72d114c91fd2f2 100644 (file)
@@ -28,7 +28,8 @@ Boston, MA 02111-1307, USA.  */
 #include "langhooks.h"
 #include "langhooks-def.h"
 
-static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
+static HOST_WIDE_INT cxx_get_alias_set         PARAMS ((tree));
+static tree cp_expr_size                       PARAMS ((tree));
 
 #undef LANG_HOOKS_NAME
 #define LANG_HOOKS_NAME "GNU C++"
@@ -91,6 +92,8 @@ static HOST_WIDE_INT cxx_get_alias_set 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
 
 /* Each front end provides its own hooks, for toplev.c.  */
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -108,3 +111,28 @@ cxx_get_alias_set (t)
 
   return c_common_get_alias_set (t);
 }
+
+/* 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 6fe5875ada74dcdb40e0dccab5d76395a0628bf6..48b615bf8d790991ea00794445e04698ff8ed0ee 100644 (file)
@@ -4084,6 +4084,7 @@ extern tree lookup_conversions                    PARAMS ((tree));
 extern tree binfo_for_vtable                   PARAMS ((tree));
 extern tree binfo_from_vbase                   PARAMS ((tree));
 extern tree look_for_overrides_here            PARAMS ((tree, tree));
+extern int check_final_overrider               PARAMS ((tree, tree));
 extern tree dfs_walk                            PARAMS ((tree,
                                                       tree (*) (tree, void *),
                                                       tree (*) (tree, void *),
index ab6e25d8bb65fa0765c4bfcc48df739a73c75f4c..9821907377f77fab7c46c88a0737da93834af4b2 100644 (file)
@@ -100,7 +100,6 @@ static tree dfs_push_decls PARAMS ((tree, void *));
 static tree dfs_unuse_fields PARAMS ((tree, void *));
 static tree add_conversions PARAMS ((tree, void *));
 static int covariant_return_p PARAMS ((tree, tree));
-static int check_final_overrider PARAMS ((tree, tree));
 static int look_for_overrides_r PARAMS ((tree, tree));
 static struct search_level *push_search_level
        PARAMS ((struct stack_level *, struct obstack *));
@@ -1800,7 +1799,7 @@ covariant_return_p (brettype, drettype)
 /* Check that virtual overrider OVERRIDER is acceptable for base function
    BASEFN. Issue diagnostic, and return zero, if unacceptable.  */
 
-static int
+int
 check_final_overrider (overrider, basefn)
      tree overrider, basefn;
 {
index f3ba665aa57523d32607709d102adeb946e2bd97..d32696996bfbcaf1ca5cef755621efeb388da74c 100644 (file)
@@ -5450,7 +5450,10 @@ build_modify_expr (lhs, modifycode, rhs)
           so the code to compute it is only emitted once.  */
        tree cond;
 
-       rhs = save_expr (rhs);
+       if (lvalue_p (rhs))
+         rhs = stabilize_reference (rhs);
+       else
+         rhs = save_expr (rhs);
        
        /* Check this here to avoid odd errors when trying to convert
           a throw to the type of the COND_EXPR.  */
index 7a770ee897cfa04e17f37d2b566b81e4e432af54..97435a703b985983c8f2b3057f0f661dfd93b9eb 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,33 @@ 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);
+}
+
+/* Return a wide integer for the size in bytes of the value of EXP, or -1
+   if the size can vary or is larger than an integer.  */
+
+HOST_WIDE_INT
+int_expr_size (exp)
+     tree exp;
+{
+  tree t = (*lang_hooks.expr_size) (exp);
+
+  if (t == 0
+      || TREE_CODE (t) != INTEGER_CST
+      || TREE_OVERFLOW (t)
+      || TREE_INT_CST_HIGH (t) != 0
+      /* If the result would appear negative, it's too big to represent.  */
+      || (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
+    return -1;
 
+  return TREE_INT_CST_LOW (t);
 }
 \f
 /* Return a copy of X in which all memory references
index a6ec5466c8f58acde34b6fa5abbe7c67985331ed..2a5c6f9b890b8fb8f03d7383db4624ca7539e58f 100644 (file)
@@ -6661,8 +6661,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, int_expr_size (exp));
          return target;
        }
 
index 91ffa3f0507dde0d1f932cb0adcf1c398a6093e4..97d734b5d307c4eefdce122a7b1654ba179c0e24 100644 (file)
@@ -548,6 +548,10 @@ extern unsigned int case_values_threshold PARAMS ((void));
 /* Return an rtx for the size in bytes of the value of an expr.  */
 extern rtx expr_size PARAMS ((tree));
 
+/* Return a wide integer for the size in bytes of the value of EXP, or -1
+   if the size can vary or is larger than an integer.  */
+extern HOST_WIDE_INT int_expr_size PARAMS ((tree));
+
 extern rtx lookup_static_chain PARAMS ((tree));
 
 /* Convert a stack slot address ADDR valid in function FNDECL
index bb00b501cc6ceb92aa30cbb2bf3c9ed18cecc45a..e80b798798ae08f62c82bff0019e1b406ca2975e 100644 (file)
@@ -48,6 +48,7 @@ extern int lhd_staticp PARAMS ((tree));
 extern void lhd_clear_binding_stack PARAMS ((void));
 extern void lhd_print_tree_nothing PARAMS ((FILE *, tree, int));
 extern void lhd_set_yydebug PARAMS ((int));
+extern tree lhd_expr_size PARAMS ((tree));
 
 /* Declarations of default tree inlining hooks.  */
 tree lhd_tree_inlining_walk_subtrees           PARAMS ((tree *, int *,
@@ -85,6 +86,7 @@ tree lhd_tree_inlining_convert_parm_for_inlining PARAMS ((tree, tree, tree));
 #define LANG_HOOKS_PRINT_TYPE          lhd_print_tree_nothing
 #define LANG_HOOKS_PRINT_IDENTIFIER    lhd_print_tree_nothing
 #define LANG_HOOKS_SET_YYDEBUG         lhd_set_yydebug
+#define LANG_HOOKS_EXPR_SIZE           lhd_expr_size
 
 /* Tree inlining hooks.  */
 #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES lhd_tree_inlining_walk_subtrees
@@ -156,6 +158,7 @@ int lhd_tree_dump_type_quals                        PARAMS ((tree));
   LANG_HOOKS_PRINT_TYPE, \
   LANG_HOOKS_PRINT_IDENTIFIER, \
   LANG_HOOKS_SET_YYDEBUG, \
+  LANG_HOOKS_EXPR_SIZE, \
   LANG_HOOKS_TREE_INLINING_INITIALIZER, \
   LANG_HOOKS_TREE_DUMP_INITIALIZER \
 }
index c0ee16cbcad688e044a172bd1dc01397465e7914..e50ebc9812b51cd88118f8c291547c22f4364330 100644 (file)
@@ -303,3 +303,16 @@ 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 368f47d31a55cb892a8d01072d474cf8d016ceae..7a3c3bd0201e3348f4ecec1427730c87abbf57b5 100644 (file)
@@ -156,6 +156,12 @@ struct lang_hooks
      warning that the front end does not use such a parser.  */
   void (*set_yydebug) PARAMS ((int));
 
+  /* 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));
+
   struct lang_hooks_for_tree_inlining tree_inlining;
   
   struct lang_hooks_for_tree_dump tree_dump;