diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-14 02:33:50 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-14 02:33:50 +0000 |
commit | e7f5de485e98ee1ad38bbe77b24cfe058746a0de (patch) | |
tree | afceb24ec23e59f5414042b4eef25c00cd3ad4ea /clang | |
parent | 5f1a04ffd16ed189920dde2f196a2e14f50099d5 (diff) | |
download | bcm5719-llvm-e7f5de485e98ee1ad38bbe77b24cfe058746a0de.tar.gz bcm5719-llvm-e7f5de485e98ee1ad38bbe77b24cfe058746a0de.zip |
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.
llvm-svn: 150453
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 15 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx0x-defaulted-functions.cpp | 10 |
2 files changed, 21 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 66f045ea8e2..4c3c538b614 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp b/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp index d01f63bedb6..2e4107c13e2 100644 --- a/clang/test/SemaCXX/cxx0x-defaulted-functions.cpp +++ b/clang/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<typename T> struct S : T { + constexpr S() = default; + constexpr S(const S&) = default; + constexpr S(S&&) = default; +}; +struct lit { constexpr lit() {} }; +S<lit> s_lit; // ok +S<bar> s_bar; // ok |