From: Richard Smith Date: Tue, 14 Feb 2012 02:33:50 +0000 (+0000) Subject: Fix another issue introduced by the proposed wording for core issue 1358: since X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=eb273b798760ed960edb0a619092da314e21f4ea;p=clang Fix another issue introduced by the proposed wording for core issue 1358: since the instantiation of a constexpr function temploid is now always constexpr, a defaulted constexpr function temploid is often ill-formed by the rule in [dcl.fct.def.default]p2 that an explicitly-defaulted constexpr function must have a constexpr implicit definition. To avoid making loads of completely reasonable code ill-formed, do not apply that rule to templates. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150453 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 66f045ea8e..4c3c538b61 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -3832,7 +3832,10 @@ void Sema::CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *CD) { // C++11 [dcl.fct.def.default]p2: // An explicitly-defaulted function may be declared constexpr only if it // would have been implicitly declared as constexpr, - if (CD->isConstexpr()) { + // Do not apply this rule to templates, since core issue 1358 makes such + // functions always instantiate to constexpr functions. + if (CD->isConstexpr() && + CD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) { if (!CD->getParent()->defaultedDefaultConstructorIsConstexpr()) { Diag(CD->getLocStart(), diag::err_incorrect_defaulted_constexpr) << CXXDefaultConstructor; @@ -3920,7 +3923,10 @@ void Sema::CheckExplicitlyDefaultedCopyConstructor(CXXConstructorDecl *CD) { // C++11 [dcl.fct.def.default]p2: // An explicitly-defaulted function may be declared constexpr only if it // would have been implicitly declared as constexpr, - if (CD->isConstexpr()) { + // Do not apply this rule to templates, since core issue 1358 makes such + // functions always instantiate to constexpr functions. + if (CD->isConstexpr() && + CD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) { if (!CD->getParent()->defaultedCopyConstructorIsConstexpr()) { Diag(CD->getLocStart(), diag::err_incorrect_defaulted_constexpr) << CXXCopyConstructor; @@ -4097,7 +4103,10 @@ void Sema::CheckExplicitlyDefaultedMoveConstructor(CXXConstructorDecl *CD) { // C++11 [dcl.fct.def.default]p2: // An explicitly-defaulted function may be declared constexpr only if it // would have been implicitly declared as constexpr, - if (CD->isConstexpr()) { + // Do not apply this rule to templates, since core issue 1358 makes such + // functions always instantiate to constexpr functions. + if (CD->isConstexpr() && + CD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) { if (!CD->getParent()->defaultedMoveConstructorIsConstexpr()) { Diag(CD->getLocStart(), diag::err_incorrect_defaulted_constexpr) << CXXMoveConstructor; diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp index d01f63bedb..2e4107c13e 100644 --- a/test/SemaCXX/cxx0x-defaulted-functions.cpp +++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp @@ -28,7 +28,7 @@ bar& bar::operator = (const bar&) = default; bar& bar::operator = (bar&) = default; bar::~bar() = default; -// FIXME: static_assert(__is_trivial(foo), "foo should be trivial"); +static_assert(__is_trivial(foo), "foo should be trivial"); static_assert(!__has_trivial_destructor(bar), "bar's destructor isn't trivial"); static_assert(!__has_trivial_constructor(bar), @@ -43,3 +43,11 @@ void tester() { b = c; } +template struct S : T { + constexpr S() = default; + constexpr S(const S&) = default; + constexpr S(S&&) = default; +}; +struct lit { constexpr lit() {} }; +S s_lit; // ok +S s_bar; // ok