2015-02-10 Jakub Jelinek 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 struct K +{ + static constexpr X v = 0; + typedef K t; +}; +template struct A; +template +struct A : Y +{ +}; +template X M (); +template struct B; +template +struct B : K(M()))> +{ +}; +template +struct G : A>::t +{ +}; +template struct J : G +{ +}; +template X&& foo (X&); +template X&& bar (X&&); +template struct P +{ + P (X& x) : q (x) {} + X q; +}; +template struct Q; +template +struct Q : P +{ + typedef P r; + X& s (Q&); + Q (X& x) : r (x) {} + Q (Q&& x) noexcept (J::v) : r (foo(s (x))) + { + } +}; +template struct I : Q +{ + I (); + I (X&... x) : Q(x...) + { + } +}; +template +I baz (X&&... x) +{ + return I (foo(x)...); +} +template struct F +{ + int p; + void operator[] (X&& x) + { + baz (bar (x)); + } +}; +struct U +{ + virtual ~U (); +}; + +int +main () +{ + F m; + m[U ()]; +}