re PR sanitizer/64984 (ICE in check_noexcept_t with ubsan)
authorJakub Jelinek <jakub@redhat.com>
Thu, 12 Feb 2015 15:38:33 +0000 (16:38 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 12 Feb 2015 15:38:33 +0000 (16:38 +0100)
PR sanitizer/64984
* except.c (check_noexcept_r): Return NULL for internal
calls.

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

From-SVN: r220649

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

index 73d1b931fb17307bfa6ae20fd166b16c6f5d387d..b66231d2febdf122e5b93808e40357d52e36f331 100644 (file)
@@ -1,3 +1,9 @@
+2015-02-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/64984
+       * except.c (check_noexcept_r): Return NULL for internal
+       calls.
+
 2015-02-10  Jason Merrill  <jason@redhat.com>
 
        PR c++/64994
index 6aff7b594391431382c332058f350516211ed2f2..3ff1ce607ee6bc62efa63669525a8feeeda3d2d6 100644 (file)
@@ -1148,7 +1148,7 @@ check_noexcept_r (tree *tp, int * /*walk_subtrees*/, void * /*data*/)
 {
   tree t = *tp;
   enum tree_code code = TREE_CODE (t);
-  if (code == CALL_EXPR
+  if ((code == CALL_EXPR && CALL_EXPR_FN (t))
       || code == AGGR_INIT_EXPR)
     {
       /* We can only use the exception specification of the called function
index 51e65ca41a03d5736c8d88a442ac8f23836500ca..276d6e17d4eabe507afca5d4d96ab07c5eefb0e8 100644 (file)
@@ -1,3 +1,8 @@
+2015-02-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/64984
+       * g++.dg/ubsan/pr64984.C: New test.
+
 2015-02-12  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * gfortran.dg/pr45636.f90: XFAIL for aarch64* targets.
diff --git a/gcc/testsuite/g++.dg/ubsan/pr64984.C b/gcc/testsuite/g++.dg/ubsan/pr64984.C
new file mode 100644 (file)
index 0000000..34f8926
--- /dev/null
@@ -0,0 +1,76 @@
+// PR sanitizer/64984
+// { dg-do compile }
+// { dg-options "-fsanitize=vptr -std=gnu++11" }
+
+template <typename X, X> struct K
+{
+  static constexpr X v = 0;
+  typedef K t;
+};
+template <typename...> struct A;
+template <typename X, typename Y>
+struct A<X, Y> : Y
+{
+};
+template <typename X> X M ();
+template <typename...> struct B;
+template <typename X, typename Y>
+struct B<X, Y> : K<int, noexcept (static_cast<X>(M<Y>()))>
+{
+};
+template <typename X, typename... Y>
+struct G : A<int, B<X, Y...>>::t
+{
+};
+template <typename X> struct J : G<X, X&&>
+{
+};
+template <typename X> X&& foo (X&);
+template <typename X> X&& bar (X&&);
+template <typename X> struct P
+{
+  P (X& x) : q (x) {}
+  X q;
+};
+template <typename...> struct Q;
+template <typename X>
+struct Q<X> : P<X>
+{
+  typedef P<X> r;
+  X& s (Q&);
+  Q (X& x) : r (x) {}
+  Q (Q&& x) noexcept (J<X>::v) : r (foo<X>(s (x)))
+  {
+  }
+};
+template <typename... X> struct I : Q<X...>
+{
+  I ();
+  I (X&... x) : Q<X...>(x...)
+  {
+  }
+};
+template <typename... X>
+I<X&&...> baz (X&&... x)
+{
+  return I <X&&...> (foo<X>(x)...);
+}
+template <typename X> struct F
+{
+  int p;
+  void operator[] (X&& x)
+  {
+    baz (bar (x));
+  }
+};
+struct U
+{
+  virtual ~U ();
+};
+
+int
+main ()
+{
+  F<U> m;
+  m[U ()];
+}