Followup patch for D128083
Previously, using a non-consteval constructor from an consteval constructor would code generates the consteval constructor.
Example
template <typename T> struct S { T i; consteval S() = default; }; struct Foo { Foo() {} }; void func() { S<Foo> three; // incorrectly accepted by clang. }
This happened because clang erroneously disregards consteval specifier for a consteval explicitly defaulted special member functions in a class template if it has dependent data members without a consteval default constructor.
According to
C++14 [dcl.constexpr]p6 (CWG DR647/CWG DR1358): 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 still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression.
Therefore the consteval defaulted constructor of a class template should be considered consteval even if the data members' default constructors are not consteval.
Keeping this constructor consteval allows complaining while processing the call to data member constructors.
(Same applies for other special member functions).
This works fine even when we have more than one default constructors since we process the constructors after the templates are instantiated.
This does not address initialization issues raised in
2602 and compiler divergence seen in https://godbolt.org/z/va9EMvvMe
The function attempts to check whether the implicitly defined member would be constexpr, which should not depend on what is written in the expliclitly defaulted declaration.
So the check should definitely be performed somewhere outside this function.