diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/except.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/pr64984.C | 76 |
4 files changed, 88 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 73d1b93..b66231d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 6aff7b5..3ff1ce6 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 51e65ca..276d6e1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..34f8926 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr64984.C @@ -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 ()]; +} |