re PR sanitizer/63813 ([UBSAN] ICE in ubsan_type_descriptor, at ubsan.c:346)
authorJakub Jelinek <jakub@redhat.com>
Tue, 18 Nov 2014 22:15:42 +0000 (23:15 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 18 Nov 2014 22:15:42 +0000 (23:15 +0100)
PR sanitizer/63813
* c-ubsan.c (ubsan_maybe_instrument_reference_or_call): Change type
argument to ptype, set type to TREE_TYPE (ptype).  Don't call
get_pointer_alignment for non-pointers.  Use ptype, or if it is
reference type, corresponding pointer type, as type of kind
argument.
(ubsan_maybe_instrument_reference,
ubsan_maybe_instrument_member_call): Adjust callers.

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

From-SVN: r217741

gcc/c-family/ChangeLog
gcc/c-family/c-ubsan.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ubsan/pr63813.C [new file with mode: 0644]

index fa0518a63ebc9370db7dff5a7d0c671a5195069f..cc6771a1bf59d9813a87a0aa81602e7fa603788c 100644 (file)
@@ -1,3 +1,14 @@
+2014-11-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/63813
+       * c-ubsan.c (ubsan_maybe_instrument_reference_or_call): Change type
+       argument to ptype, set type to TREE_TYPE (ptype).  Don't call
+       get_pointer_alignment for non-pointers.  Use ptype, or if it is
+       reference type, corresponding pointer type, as type of kind
+       argument.
+       (ubsan_maybe_instrument_reference,
+       ubsan_maybe_instrument_member_call): Adjust callers.
+
 2014-11-15  Marek Polacek  <polacek@redhat.com>
 
        PR middle-end/63884
index ab16799b0c9303043ef876840421266b7c7c300f..90b03f23e73993497ab19d0a9b2c5a6d88650aa8 100644 (file)
@@ -383,18 +383,19 @@ ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
 }
 
 static tree
-ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree type,
+ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype,
                                          enum ubsan_null_ckind ckind)
 {
-  tree orig_op = op;
-  bool instrument = false;
-  unsigned int mina = 0;
-
   if (current_function_decl == NULL_TREE
       || lookup_attribute ("no_sanitize_undefined",
                           DECL_ATTRIBUTES (current_function_decl)))
     return NULL_TREE;
 
+  tree type = TREE_TYPE (ptype);
+  tree orig_op = op;
+  bool instrument = false;
+  unsigned int mina = 0;
+
   if (flag_sanitize & SANITIZE_ALIGNMENT)
     {
       mina = min_align_of_type (type);
@@ -431,13 +432,20 @@ ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree type,
        }
       else if (flag_sanitize & SANITIZE_NULL)
        instrument = true;
-      if (mina && mina > get_pointer_alignment (op) / BITS_PER_UNIT)
-       instrument = true;
+      if (mina && mina > 1)
+       {
+         if (!POINTER_TYPE_P (TREE_TYPE (op))
+             || mina > get_pointer_alignment (op) / BITS_PER_UNIT)
+           instrument = true;
+       }
     }
   if (!instrument)
     return NULL_TREE;
   op = save_expr (orig_op);
-  tree kind = build_int_cst (TREE_TYPE (op), ckind);
+  gcc_assert (POINTER_TYPE_P (ptype));
+  if (TREE_CODE (ptype) == REFERENCE_TYPE)
+    ptype = build_pointer_type (TREE_TYPE (ptype));
+  tree kind = build_int_cst (ptype, ckind);
   tree align = build_int_cst (pointer_sized_int_node, mina);
   tree call
     = build_call_expr_internal_loc (loc, IFN_UBSAN_NULL, void_type_node,
@@ -453,7 +461,7 @@ ubsan_maybe_instrument_reference (tree stmt)
 {
   tree op = TREE_OPERAND (stmt, 0);
   op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
-                                                TREE_TYPE (TREE_TYPE (stmt)),
+                                                TREE_TYPE (stmt),
                                                 UBSAN_REF_BINDING);
   if (op)
     TREE_OPERAND (stmt, 0) = op;
@@ -471,7 +479,7 @@ ubsan_maybe_instrument_member_call (tree stmt, bool is_ctor)
       || !POINTER_TYPE_P (TREE_TYPE (op)))
     return;
   op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
-                                                TREE_TYPE (TREE_TYPE (op)),
+                                                TREE_TYPE (op),
                                                 is_ctor ? UBSAN_CTOR_CALL
                                                 : UBSAN_MEMBER_CALL);
   if (op)
index ad651fa7830e24f3549f94eb735555e572d445ab..49f497396f71b1bf4e30b0a1d4e1405aa7eb92f4 100644 (file)
@@ -1,5 +1,8 @@
 2014-11-18  Jakub Jelinek  <jakub@redhat.com>
 
+       PR sanitizer/63813
+       * g++.dg/ubsan/pr63813.C: New test.
+
        PR tree-optimization/61042
        * gcc.c-torture/compile/pr61042.c: New test.
 
diff --git a/gcc/testsuite/g++.dg/ubsan/pr63813.C b/gcc/testsuite/g++.dg/ubsan/pr63813.C
new file mode 100644 (file)
index 0000000..6ca5b2d
--- /dev/null
@@ -0,0 +1,12 @@
+// PR sanitizer/63813
+// { dg-do compile }
+// { dg-options "-fsanitize=undefined -O1" }
+
+struct A {};
+struct B { long foo () const; A &bar () const; };
+
+A &
+B::bar () const
+{
+  return *reinterpret_cast <A *> (foo ());
+}