Hi!

cp_genericize_r now instruments INTEGER_CSTs that have REFERENCE_TYPE,
so that we can diagnose binding references to NULL in some cases,
see PR79572.  As the following testcase shows, there is one exception
when we do not want to do that - in MEM_EXPR, the second operand
is an INTEGER_CST whose value is an offset, but type is something
unrelated - what should be used for aliasing purposes.  So, that
is something we do not want to diagnose, and it is also invalid IL,
as the second argument has to be an INTEGER_CST, not some expression
with side-effects.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk/7.x?

2017-06-08  Jakub Jelinek  <ja...@redhat.com>

        PR c++/80973
        * cp-gimplify.c (cp_genericize_r): Don't instrument MEM_REF second
        argument even if it has REFERENCE_TYPE.

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

--- gcc/cp/cp-gimplify.c.jj     2017-06-08 13:24:48.000000000 +0200
+++ gcc/cp/cp-gimplify.c        2017-06-08 17:48:13.466868875 +0200
@@ -1476,6 +1476,21 @@ cp_genericize_r (tree *stmt_p, int *walk
                cp_ubsan_maybe_instrument_member_call (stmt);
            }
        }
+      else if (TREE_CODE (stmt) == MEM_REF)
+       {
+         /* For MEM_REF, make sure not to sanitize the second operand even
+            if it has reference type.  It is just an offset with a type
+            holding other information.  */
+         if (TREE_CODE (TREE_OPERAND (stmt, 1)) == INTEGER_CST
+             && (TREE_CODE (TREE_TYPE (TREE_OPERAND (stmt, 1)))
+                 == REFERENCE_TYPE)
+             && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)))
+           {
+             cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r,
+                           data, NULL);
+             *walk_subtrees = 0;
+           }
+       }
     }
 
   p_set->add (*stmt_p);
--- gcc/testsuite/g++.dg/ubsan/pr80973.C.jj     2017-06-08 17:49:55.491622907 
+0200
+++ gcc/testsuite/g++.dg/ubsan/pr80973.C        2017-06-08 17:49:51.056677069 
+0200
@@ -0,0 +1,16 @@
+// PR c++/80973
+// { dg-do compile }
+// { dg-options "-fsanitize=undefined -std=c++14" }
+
+struct A {
+  A();
+  A(const A &);
+};
+struct B {
+  B();
+  template <typename... Args> auto g(Args &&... p1) {
+    return [=] { f(p1...); };
+  }
+  void f(A, const char *);
+};
+B::B() { g(A(), ""); }

        Jakub

Reply via email to