Title
Unintentionally ill-formed constexpr function template instances
Status
cd3
Section
9.2.6 [dcl.constexpr]
Submitter
Richard Smith

Created on 2011-08-16.00:00:00 last changed 90 months ago

Messages

Date: 2013-04-15.00:00:00

[Moved to DR status at the April, 2013 meeting.]

Date: 2013-01-15.00:00:00

Additional note (January, 2013):

Questions arose in the discussion of issue 1581 as to whether this approach — making the specialization of a constexpr function template or member function of a class template still constexpr but unable to be invoked in a constant context — is correct. The implication is that class types might be categorized as literal but not be able to be instantiated at compile time. This issue is therefore returned to "review" status to allow further consideration of this question.

Date: 2012-10-15.00:00:00

Proposed resolution (October, 2012):

Change 9.2.6 [dcl.constexpr] paragraphs 5-6 as follows:

...For a non-template, non-defaulted constexpr function, if no function argument values exist such that the function invocation substitution would produce a constant expression (7.7 [expr.const]), the program is ill-formed; no diagnostic required. For a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that after function invocation substitution, every constructor call and full-expression in the mem-initializers would be a constant expression (including conversions), the program is ill-formed; no diagnostic required. [Example: ... —end example]

If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is not still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression. [Note: If the function is a member function it will still be const as described below. —end note] If no specialization of the template would yield satisfy the requirements for a constexpr function or constexpr constructor when considered as a non-template function or constructor, the program template is ill-formed; no diagnostic required.

Date: 2012-09-24.00:00:00

Additional notes, February, 2012:

The proposed resolution inadvertently removes the provision allowing specializations of constexpr templates to violate the requirements of 9.2.6 [dcl.constexpr]. It is being retained in "drafting" status pending additional work.

Date: 2012-02-15.00:00:00

Proposed resolution (February, 2012):

  1. Change 9.2.6 [dcl.constexpr] paragraph 5 as follows:

  2. ... —end example]

    For a non-template, non-defaulted constexpr function, if no function argument values exist such that the function invocation substitution would produce a constant expression (7.7 [expr.const]), the program is ill-formed; no diagnostic required. For a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that after function invocation substitution, every constructor call and full-expression in the mem-initializers would be a constant expression (including conversions), the program is ill-formed; no diagnostic required. For a constexpr function template or member function of a class template, if no instantiation would be well-formed when considered as a non-template constexpr function, the program is ill-formed; no diagnostic required. [Example:...

  3. Delete 9.2.6 [dcl.constexpr] paragraph 6:

  4. If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is not a constexpr function or constexpr constructor. [Note: If the function is a member function it will still be const as described below. —end note] If no specialization of the template would yield a constexpr function or constexpr constructor, the program is ill-formed; no diagnostic required.
Date: 2011-08-15.00:00:00

Notes from the August, 2011 meeting:

The CWG also decided to treat the following example under this issue, although it does not involve a function template:
    int f();   // not constexpr
    struct A {
      int m;
      constexpr A(int i = f()) : m(i) { }
    };
    struct B {
      A a;
    } b;

This is ill-formed, no diagnostic required, because the defaulted default constructor of B will be declared constexpr but can never be invoked in a constant expression. See issue 1360.

Date: 2011-08-16.00:00:00

The permission granted implementations in 9.2.6 [dcl.constexpr] paragraph 5 to diagnose definitions of constexpr functions that can never be used in a constant expression should not apply to an instantiated constexpr function template.

History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: drwp -> cd3
2013-10-14 00:00:00adminsetstatus: dr -> drwp
2013-05-03 00:00:00adminsetmessages: + msg4400
2013-05-03 00:00:00adminsetstatus: review -> dr
2013-01-14 00:00:00adminsetmessages: + msg4200
2013-01-14 00:00:00adminsetstatus: ready -> review
2012-11-03 00:00:00adminsetmessages: + msg4060
2012-11-03 00:00:00adminsetstatus: drafting -> ready
2012-09-24 00:00:00adminsetstatus: ready -> drafting
2012-02-27 00:00:00adminsetmessages: + msg3715
2012-02-27 00:00:00adminsetmessages: + msg3714
2012-02-27 00:00:00adminsetstatus: drafting -> ready
2011-09-06 00:00:00adminsetmessages: + msg3527
2011-08-16 00:00:00admincreate