The C++17 path in build_special_member_call converts to the desired type and then builds an INIT_EXPR to initialize the object. Since this does not involve actually creating a temporary, we should set TARGET_EXPR_DIRECT_INIT_P.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit f2cf58eab564e32201c403f292da3ff99385d48e Author: Jason Merrill <ja...@redhat.com> Date: Fri Feb 16 14:47:34 2018 -0500 PR c++/83835 - C++17 error with constructor ctors. * call.c (build_special_member_call): Set TARGET_EXPR_DIRECT_INIT_P. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 5698ff60a4d..d3d0966f65c 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -8834,6 +8834,9 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args, { if (is_dummy_object (instance)) return arg; + else if (TREE_CODE (arg) == TARGET_EXPR) + TARGET_EXPR_DIRECT_INIT_P (arg) = true; + if ((complain & tf_error) && (flags & LOOKUP_DELEGATING_CONS)) check_self_delegation (arg); diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor21.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor21.C new file mode 100644 index 00000000000..4bf57b9e897 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor21.C @@ -0,0 +1,15 @@ +// PR c++/83835 +// { dg-do compile { target c++11 } } + +struct Z +{ + void const * p_; + constexpr Z( void const * p ): p_( p ) {} + ~Z(); +}; + +struct Y +{ + Z z_; + constexpr Y() noexcept: z_( this ) {} +};