summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-02-14 02:33:50 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-02-14 02:33:50 +0000
commite7f5de485e98ee1ad38bbe77b24cfe058746a0de (patch)
treeafceb24ec23e59f5414042b4eef25c00cd3ad4ea /clang
parent5f1a04ffd16ed189920dde2f196a2e14f50099d5 (diff)
downloadbcm5719-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.cpp15
-rw-r--r--clang/test/SemaCXX/cxx0x-defaulted-functions.cpp10
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
OpenPOWER on IntegriCloud