PR sanitizer/59306
authormpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Nov 2013 11:40:22 +0000 (11:40 +0000)
committermpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Nov 2013 11:40:22 +0000 (11:40 +0000)
* ubsan.c (instrument_null): Use gimple_store_p/gimple_assign_load_p
instead of walk_gimple_op.
(ubsan_pass): Adjust.  Call instrument_null only if SANITIZE_NULL.
testsuite/
* g++.dg/ubsan/pr59306.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205443 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 2b8ce47..31e9670 100644 (file)
@@ -1,3 +1,10 @@
+2013-11-27  Marek Polacek  <polacek@redhat.com>
+
+       PR sanitizer/59306
+       * ubsan.c (instrument_null): Use gimple_store_p/gimple_assign_load_p
+       instead of walk_gimple_op.
+       (ubsan_pass): Adjust.  Call instrument_null only if SANITIZE_NULL.
+
 2013-11-27  Aldy Hernandez  <aldyh@redhat.com>
            Jakub Jelinek  <jakub@redhat.com>
 
index 20e885a..084e812 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-27  Marek Polacek  <polacek@redhat.com>
+
+       PR sanitizer/59306
+       * g++.dg/ubsan/pr59306.C: New test.
+
 2013-11-27  Aldy Hernandez  <aldyh@redhat.com>
            Jakub Jelinek  <jakub@redhat.com>
 
diff --git a/gcc/testsuite/g++.dg/ubsan/pr59306.C b/gcc/testsuite/g++.dg/ubsan/pr59306.C
new file mode 100644 (file)
index 0000000..426e6a5
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-do compile }
+// { dg-options "-fsanitize=undefined" }
+// { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
+
+class A {
+  void bar (void (A::*) (int));
+  void foo (int);
+  void B ();
+};
+
+void A::B()
+{
+  bar (&A::foo);
+}
index fa6b42a..e33e62a 100644 (file)
@@ -614,24 +614,22 @@ instrument_mem_ref (tree t, gimple_stmt_iterator *iter, bool is_lhs)
   gsi_insert_before (iter, g, GSI_SAME_STMT);
 }
 
-/* Callback function for the pointer instrumentation.  */
+/* Perform the pointer instrumentation.  */
 
-static tree
-instrument_null (tree *tp, int * /*walk_subtree*/, void *data)
+static void
+instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
 {
-  tree t = *tp;
+  gimple stmt = gsi_stmt (gsi);
+  tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
+  t = get_base_address (t);
   const enum tree_code code = TREE_CODE (t);
-  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
-
   if (code == MEM_REF
       && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
-    instrument_mem_ref (TREE_OPERAND (t, 0), &wi->gsi, wi->is_lhs);
+    instrument_mem_ref (TREE_OPERAND (t, 0), &gsi, is_lhs);
   else if (code == ADDR_EXPR
           && POINTER_TYPE_P (TREE_TYPE (t))
           && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == METHOD_TYPE)
-    instrument_member_call (&wi->gsi);
-
-  return NULL_TREE;
+    instrument_member_call (&gsi);
 }
 
 /* Gate and execute functions for ubsan pass.  */
@@ -646,7 +644,6 @@ ubsan_pass (void)
     {
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
        {
-         struct walk_stmt_info wi;
          gimple stmt = gsi_stmt (gsi);
          if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
            {
@@ -654,9 +651,14 @@ ubsan_pass (void)
              continue;
            }
 
-         memset (&wi, 0, sizeof (wi));
-         wi.gsi = gsi;
-         walk_gimple_op (stmt, instrument_null, &wi);
+         if (flag_sanitize & SANITIZE_NULL)
+           {
+             if (gimple_store_p (stmt))
+               instrument_null (gsi, true);
+             if (gimple_assign_load_p (stmt))
+               instrument_null (gsi, false);
+           }
+
          gsi_next (&gsi);
        }
     }