re PR sanitizer/80973 (ICE with lambda and -fsanitize=undefined)
authorJakub Jelinek <jakub@redhat.com>
Tue, 13 Jun 2017 20:05:20 +0000 (22:05 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 13 Jun 2017 20:05:20 +0000 (22:05 +0200)
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.

From-SVN: r249174

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

index ae91a9ddbf6888361899a2cd5c5715ad9c76772b..ca0f9b200149f97c7d474d6a6e43a10e4f0944b1 100644 (file)
@@ -1,5 +1,9 @@
 2017-06-13  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/80973
+       * cp-gimplify.c (cp_genericize_r): Don't instrument MEM_REF second
+       argument even if it has REFERENCE_TYPE.
+
        PR c++/80984
        * cp-gimplify.c (cp_genericize): Only look for VAR_DECLs in
        BLOCK_VARS (outer) chain.
index d5462087598f005744cf76436f63f19ce172d330..a0abd51440da45c3ffbf83438fc65a2356ac157a 100644 (file)
@@ -1450,6 +1450,16 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
       *stmt_p = cplus_expand_constant (stmt);
       *walk_subtrees = 0;
     }
+  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.  There is no other processing we
+        need to do for INTEGER_CSTs, so just ignore the second argument
+        unconditionally.  */
+      cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
+      *walk_subtrees = 0;
+    }
   else if (sanitize_flags_p ((SANITIZE_NULL
                              | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
           && !wtd->no_sanitize_p)
index 5164fa987b87da55effb1c46ff947c08ef8571b4..f32b8c8258680c61325196a981924a2613ebb808 100644 (file)
@@ -1,5 +1,8 @@
 2017-06-13  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/80973
+       * g++.dg/ubsan/pr80973.C: New test.
+
        PR c++/80984
        * g++.dg/opt/nrv18.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/ubsan/pr80973.C b/gcc/testsuite/g++.dg/ubsan/pr80973.C
new file mode 100644 (file)
index 0000000..b534fdb
--- /dev/null
@@ -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(), ""); }