This code: ``` class X { public: virtual ~X(); }; class Y { private: class Z: public X { private: Y const * p_; public: constexpr explicit Z( Y const * p ): p_( p ) {} }; Z z_; public: constexpr Y() noexcept: z_( this ) {} }; int main() { } ``` is accepted in C++14 mode, and in C++1z mode by g++ 5 or 6, but fails in C++17 mode under g++ 7 or 8 with ``` error: temporary of non-literal type 'Y::Z' in a constant expression ```
Confirmed with the slightly simplified test case below. Other compilers accept the code, as does GCC 6.4.0. The regression was introduced in GCC 7.0 by r240889. $ cat pr83835.C && gcc -S -Wall -std=c++17 pr83835.C struct Y { struct Z { virtual ~Z (); constexpr explicit Z (const Y*) { } }; Z z; constexpr Y (): z (this) { } }; pr83835.C: In constructor ‘constexpr Y::Y()’: pr83835.C:9:32: error: temporary of non-literal type ‘Y::Z’ in a constant expression constexpr Y (): z (this) { } ^ pr83835.C:2:12: note: ‘Y::Z’ is not literal because: struct Z { ^ pr83835.C:2:12: note: ‘Y::Z’ has a non-trivial destructor
Very similar to PR82461.
Perhaps we also want to set TARGET_EXPR_DIRECT_INIT_P here: 6785 /* If this is a constructor or a function returning an aggr type, 6786 we need to build up a TARGET_EXPR. */ 6787 if (DECL_CONSTRUCTOR_P (convfn)) 6788 { 6789 expr = build_cplus_new (totype, expr, complain); 6790 6791 /* Remember that this was list-initialization. */ 6792 if (convs->check_narrowing && expr != error_mark_node) 6793 TARGET_EXPR_LIST_INIT_P (expr) = true; 6794 }
Author: jason Date: Fri Feb 16 20:05:28 2018 New Revision: 257757 URL: https://gcc.gnu.org/viewcvs?rev=257757&root=gcc&view=rev Log: PR c++/83835 - C++17 error with constructor ctors. * call.c (build_special_member_call): Set TARGET_EXPR_DIRECT_INIT_P. Added: trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor21.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c
Author: jason Date: Fri Feb 16 21:06:39 2018 New Revision: 257764 URL: https://gcc.gnu.org/viewcvs?rev=257764&root=gcc&view=rev Log: PR c++/83835 - C++17 error with constructor ctors. * call.c (build_special_member_call): Set TARGET_EXPR_DIRECT_INIT_P. Added: branches/gcc-7-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor21.C Modified: branches/gcc-7-branch/gcc/cp/ChangeLog branches/gcc-7-branch/gcc/cp/call.c
Fixed.