99 lines
2.0 KiB
Diff
99 lines
2.0 KiB
Diff
2015-02-10 Jakub Jelinek <jakub@redhat.com>
|
|
|
|
PR sanitizer/64984
|
|
* except.c (check_noexcept_r): Return NULL for internal
|
|
calls.
|
|
|
|
* g++.dg/ubsan/pr64984.C: New test.
|
|
|
|
--- gcc/cp/except.c.jj 2015-01-31 10:07:36.000000000 +0100
|
|
+++ gcc/cp/except.c 2015-02-10 09:06:44.712226554 +0100
|
|
@@ -1148,7 +1148,7 @@ check_noexcept_r (tree *tp, int * /*walk
|
|
{
|
|
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
|
|
--- gcc/testsuite/g++.dg/ubsan/pr64984.C.jj 2015-02-10 09:52:43.720720833 +0100
|
|
+++ gcc/testsuite/g++.dg/ubsan/pr64984.C 2015-02-10 10:00:00.343370913 +0100
|
|
@@ -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 ()];
|
|
+}
|