]> granicus.if.org Git - clang/commitdiff
Fix another issue introduced by the proposed wording for core issue 1358: since
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 14 Feb 2012 02:33:50 +0000 (02:33 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 14 Feb 2012 02:33:50 +0000 (02:33 +0000)
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

lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/cxx0x-defaulted-functions.cpp

index 66f045ea8e242b2d7f26652ae16e90331a9b632a..4c3c538b614378b1394c7f121e047777cc80b4de 100644 (file)
@@ -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;
index d01f63bedb6b7cb8c6e6a8b0a55235ae6d2ccae2..2e4107c13e2dac9ef7cb5f1dc0179063e92f3ac2 100644 (file)
@@ -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