Bug 83835 - [7/8 Regression] constexpr constructor rejected in c++17 mode (regression WRT c++14)
Summary: [7/8 Regression] constexpr constructor rejected in c++17 mode (regression WRT...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: 7.4
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2018-01-14 13:24 UTC by Peter Dimov
Modified: 2018-02-16 21:07 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 6.4.0
Known to fail: 7.2.0, 8.0
Last reconfirmed: 2018-01-27 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Dimov 2018-01-14 13:24:28 UTC
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
```
Comment 1 Martin Sebor 2018-01-27 00:40:23 UTC
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
Comment 2 Marek Polacek 2018-01-29 13:18:28 UTC
Very similar to PR82461.
Comment 3 Marek Polacek 2018-01-29 21:05:11 UTC
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           }
Comment 4 Jason Merrill 2018-02-16 20:05:59 UTC
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
Comment 5 Jason Merrill 2018-02-16 21:07:11 UTC
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
Comment 6 Jason Merrill 2018-02-16 21:07:34 UTC
Fixed.