aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDeclCXX.cpp15
-rw-r--r--test/SemaCXX/cxx0x-defaulted-functions.cpp10
2 files changed, 21 insertions, 4 deletions
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<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