On Wed, Nov 25, 2015 at 09:45:46AM -0500, Jason Merrill wrote:
> On 11/24/2015 04:01 PM, Jakub Jelinek wrote:
> >2) the downcast check is just DERIVED_FROM_P check, but my undestanding
> >of that is that DERIVED_FROM_P (x, x) is true too
> 
> Yes, but you can use is_properly_derived_from instead.
> 
> With that change the first cast is OK for trunk and branch.

Thanks, this passed bootstrap/regtest on x86_64-linux and i686-linux
too, will apply tomorrow.

2015-11-25  Jakub Jelinek  <ja...@redhat.com>

        PR c++/68508
        * cp-tree.h (cp_ubsan_maybe_instrument_downcast): Add INTYPE argument.
        * cp-ubsan.c (cp_ubsan_maybe_instrument_downcast): Likewise.  Use
        it instead of or in addition to TREE_TYPE (op).  Use
        is_properly_derived_from, return NULL_TREE if TREE_TYPE (intype) and
        TREE_TYPE (type) are the same type minus qualifiers.
        * typeck.c (build_static_cast_1): Adjust callers.

        * g++.dg/ubsan/pr68508.C: New test.

--- gcc/cp/cp-ubsan.c.jj        2015-11-25 09:49:50.850231457 +0100
+++ gcc/cp/cp-ubsan.c   2015-11-25 18:07:11.083778395 +0100
@@ -245,13 +245,14 @@ cp_ubsan_instrument_member_accesses (tre
 /* Instrument downcast.  */
 
 tree
-cp_ubsan_maybe_instrument_downcast (location_t loc, tree type, tree op)
+cp_ubsan_maybe_instrument_downcast (location_t loc, tree type,
+                                   tree intype, tree op)
 {
   if (!POINTER_TYPE_P (type)
+      || !POINTER_TYPE_P (intype)
       || !POINTER_TYPE_P (TREE_TYPE (op))
-      || !CLASS_TYPE_P (TREE_TYPE (type))
       || !CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (op)))
-      || !DERIVED_FROM_P (TREE_TYPE (TREE_TYPE (op)), TREE_TYPE (type)))
+      || !is_properly_derived_from (TREE_TYPE (type), TREE_TYPE (intype)))
     return NULL_TREE;
 
   return cp_ubsan_maybe_instrument_vptr (loc, op, TREE_TYPE (type), true,
--- gcc/cp/cp-tree.h.jj 2015-11-25 09:49:50.816231943 +0100
+++ gcc/cp/cp-tree.h    2015-11-25 18:04:12.867310549 +0100
@@ -6854,7 +6854,7 @@ extern bool cilk_valid_spawn
 /* In cp-ubsan.c */
 extern void cp_ubsan_maybe_instrument_member_call (tree);
 extern void cp_ubsan_instrument_member_accesses (tree *);
-extern tree cp_ubsan_maybe_instrument_downcast (location_t, tree, tree);
+extern tree cp_ubsan_maybe_instrument_downcast (location_t, tree, tree, tree);
 extern tree cp_ubsan_maybe_instrument_cast_to_vbase (location_t, tree, tree);
 
 /* -- end of C++ */
--- gcc/cp/typeck.c.jj  2015-11-25 09:49:50.879231042 +0100
+++ gcc/cp/typeck.c     2015-11-25 18:04:12.871310493 +0100
@@ -6590,7 +6590,8 @@ build_static_cast_1 (tree type, tree exp
       if (flag_sanitize & SANITIZE_VPTR)
        {
          tree ubsan_check
-           = cp_ubsan_maybe_instrument_downcast (input_location, type, expr);
+           = cp_ubsan_maybe_instrument_downcast (input_location, type,
+                                                 intype, expr);
          if (ubsan_check)
            expr = ubsan_check;
        }
@@ -6737,7 +6738,8 @@ build_static_cast_1 (tree type, tree exp
       if (flag_sanitize & SANITIZE_VPTR)
        {
          tree ubsan_check
-           = cp_ubsan_maybe_instrument_downcast (input_location, type, expr);
+           = cp_ubsan_maybe_instrument_downcast (input_location, type,
+                                                 intype, expr);
          if (ubsan_check)
            expr = ubsan_check;
        }
--- gcc/testsuite/g++.dg/ubsan/pr68508.C.jj     2015-11-25 18:04:12.871310493 
+0100
+++ gcc/testsuite/g++.dg/ubsan/pr68508.C        2015-11-25 18:04:12.871310493 
+0100
@@ -0,0 +1,15 @@
+// PR c++/68508
+// { dg-do compile }
+// { dg-options "-std=c++14 -fsanitize=vptr" }
+
+struct A
+{
+  virtual int foo () { return 0; }
+};
+
+const A &
+bar ()
+{
+  static A x = A ();
+  return (x);
+}


        Jakub

Reply via email to