This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 109b. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2022-09-25


1358. Unintentionally ill-formed constexpr function template instances

Section: 9.2.6  [dcl.constexpr]     Status: CD3     Submitter: Richard Smith     Date: 2011-08-16

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

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.

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.

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.

    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.

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.

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.