In this testcase, the compiler is trying to evaluate a constant-expression which involves a trivial defaulted copy constructor. My patch for CWG 1581 had us instantiate any function that appears in a potential constant expression, but that's not what we want for a trivial constructor like this.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit b71b855538a05716e704d02f636b8820faec3e62 Author: Jason Merrill <ja...@redhat.com> Date: Wed Jun 13 17:51:44 2018 -0400 PR c++/86099 - ICE with trivial copy and non-trivial default ctor. * constexpr.c (instantiate_cx_fn_r): Don't synthesize trivial constructors. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 97a338535db..93de6162c04 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4841,6 +4841,7 @@ instantiate_cx_fn_r (tree *tp, int *walk_subtrees, void */*data*/) if (TREE_CODE (*tp) == FUNCTION_DECL && DECL_DECLARED_CONSTEXPR_P (*tp) && !DECL_INITIAL (*tp) + && !trivial_fn_p (*tp) && DECL_TEMPLOID_INSTANTIATION (*tp)) { ++function_depth; diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template18.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template18.C new file mode 100644 index 00000000000..e3520bc6b44 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template18.C @@ -0,0 +1,43 @@ +// PR c++/86099 +// { dg-do compile { target c++11 } } + +template <int a> struct e { static constexpr int c = a; }; +template <bool a> using d = e<a>; +template <bool, typename> struct aa; +template <typename...> struct j; +template <typename f, typename g> struct j<f, g> : aa<f::c, g>::h {}; +template <typename i> struct n : d<i::c> {}; +template <typename k, typename l = k> l m(int); +template <typename k> auto ab() -> decltype(m<k>(0)); +template <typename...> struct p; +template <typename k, typename o> struct p<k, o> : e<noexcept(k(ab<o>()))> {}; +template <typename> struct r; +class s; +template <typename, typename... q> +struct ac : j<d<true>, p<r<s>, q...>> {}; +template <typename k> struct ae : ac<k, k> {}; +template <bool, typename ad> struct aa { typedef ad h; }; +template <typename k> struct w : j<n<ae<k>>, d<true>> {}; +template <typename t> struct r { + t f; + int af; + r(r &&) = default; +}; +template <typename k, typename = typename aa<w<k>::c, k>::h> void v(k *); +template <typename ag, typename ah, typename ai> ah aj(ag x, ah, ai) { v(x); return 0; } +template <typename> struct y { typedef int ak; }; +template <typename, typename = int> class z { +public: + template <typename...> void al(); +}; +template <typename k, typename am> template <typename...> void z<k, am>::al() { + r<s> *u; + typename y<am>::ak a = aj(u, a, int()); +} +class s { + char *an = nullptr; +}; +void ao() { + z<int> b; + b.al(); +}