This patch fixes another instance of unchecked return value of 
gimple_call_fn.

Only one thing is interesting: I found an ICE with -fvtable-verify=std
and -flto, that's why I don't run the test with LTO.  This ICE is
unrelated to ubsan.

Regtested/bootstrapped on x86_64-linux, ok for trunk?

2013-12-09  Marek Polacek  <pola...@redhat.com>

        PR sanitizer/59437
        * vtable-verify.c (var_is_used_for_virtual_call_p): Check the
        return value of gimple_call_fn.  Use is_gimple_call/is_gimple_assign
        instead of gimple_code.
testsuite/
        * g++.dg/ubsan/pr59437.C: New test.

--- gcc/vtable-verify.c.mp      2013-12-09 16:51:24.199748082 +0100
+++ gcc/vtable-verify.c 2013-12-09 23:48:09.540307271 +0100
@@ -513,10 +513,10 @@ var_is_used_for_virtual_call_p (tree lhs
     {
       gimple stmt2 = USE_STMT (use_p);
 
-      if (gimple_code (stmt2) == GIMPLE_CALL)
+      if (is_gimple_call (stmt2))
         {
           tree fncall = gimple_call_fn (stmt2);
-          if (TREE_CODE (fncall) == OBJ_TYPE_REF)
+          if (fncall && TREE_CODE (fncall) == OBJ_TYPE_REF)
             found_vcall = true;
          else
            return false;
@@ -527,7 +527,7 @@ var_is_used_for_virtual_call_p (tree lhs
                                                    (gimple_phi_result (stmt2),
                                                     mem_ref_depth);
         }
-      else if (gimple_code (stmt2) == GIMPLE_ASSIGN)
+      else if (is_gimple_assign (stmt2))
         {
          tree rhs = gimple_assign_rhs1 (stmt2);
          if (TREE_CODE (rhs) == ADDR_EXPR
--- gcc/testsuite/g++.dg/ubsan/pr59437.C.mp     2013-12-09 23:47:59.102262161 
+0100
+++ gcc/testsuite/g++.dg/ubsan/pr59437.C        2013-12-09 23:55:23.350994212 
+0100
@@ -0,0 +1,24 @@
+// { dg-do compile }
+// { dg-options "-fsanitize=null -fvtable-verify=std" }
+// { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
+
+template < typename T > struct A
+{
+  T foo ();
+};
+template < typename T > struct C: virtual public A < T >
+{
+  C & operator<< (C & (C &));
+};
+template < typename T >
+C < T > &endl (C < int > &c)
+{
+  c.foo ();
+  return c;
+}
+C < int > cout;
+void
+fn ()
+{
+  cout << endl;
+}

        Marek

Reply via email to