From ca46d131aa40ae953d719b096cb951b385787445 Mon Sep 17 00:00:00 2001 From: Sean Hunt Date: Thu, 12 May 2011 03:51:48 +0000 Subject: [PATCH] Implement deletion of explicitly defaulted default constructors. We still don't parse out-of-line defaults correctly, which is needed to get the full effect out of this patch. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131223 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 4 +++ lib/Sema/SemaDecl.cpp | 38 ++++------------------ lib/Sema/SemaDeclCXX.cpp | 8 +++++ 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index c8ab2392bf..2ab02d60e1 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -3632,6 +3632,10 @@ def err_defaulted_default_ctor_params : Error< "an explicitly-defaulted default constructor must have no parameters">; def err_incorrect_defaulted_exception_spec : Error< "exception specification of explicitly defaulted function is incorrect">; +def err_out_of_line_default_deletes : Error< + "defaulting this %select{default constructor|copy constructor|copy " + "assignment operator|destructor}0 would delete it after its first " + "declaration">; def warn_array_index_precedes_bounds : Warning< "array index of '%0' indexes before the beginning of the array">, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9a4afde057..972d080fc9 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1518,7 +1518,6 @@ Sema::CXXSpecialMember Sema::getSpecialMember(const CXXMethodDecl *MD) { if (MD->isCopyAssignmentOperator()) return Sema::CXXCopyAssignment; - llvm_unreachable("getSpecialMember on non-special member"); return Sema::CXXInvalid; } @@ -4220,9 +4219,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, isVirtualOkay = !isStatic; } else { - if (DefaultLoc.isValid()) - Diag(DefaultLoc, diag::err_default_special_members); - // Determine whether the function was written with a // prototype. This true when: // - we're in C++ (where every function has a prototype), @@ -4778,33 +4774,13 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, } } - // Check explicitly defaulted methods - // FIXME: This could be made better through CXXSpecialMember if it did - // default constructors (which it should rather than any constructor). - if (NewFD && DefaultLoc.isValid() && getLangOptions().CPlusPlus) { - if (CXXMethodDecl *MD = dyn_cast(NewFD)) { - if (CXXConstructorDecl *CD = dyn_cast(MD)) { - if (CD->isDefaultConstructor() || CD->isCopyOrMoveConstructor()) { - CD->setDefaulted(); - CD->setExplicitlyDefaulted(); - if (CD != CD->getCanonicalDecl() && CD->isDefaultConstructor()) - CheckExplicitlyDefaultedDefaultConstructor(CD); - // FIXME: Do copy/move ctors here. - } else { - Diag(DefaultLoc, diag::err_default_special_members); - } - } else if (CXXDestructorDecl *DD = dyn_cast(MD)) { - DD->setDefaulted(); - DD->setExplicitlyDefaulted(); - // FIXME: Add a checking method - } else if (MD->isCopyAssignmentOperator() /* || - MD->isMoveAssignmentOperator() */) { - MD->setDefaulted(); - MD->setExplicitlyDefaulted(); - // FIXME: Add a checking method - } else { - Diag(DefaultLoc, diag::err_default_special_members); - } + if (DefaultLoc.isValid()) { + CXXMethodDecl *MD = dyn_cast(NewFD); + if (MD && getSpecialMember(MD) != CXXInvalid) { + MD->setExplicitlyDefaulted(); + MD->setDefaulted(); + } else { + Diag(DefaultLoc, diag::err_default_special_members); } } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index b00d73d93c..8ef3463f42 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -3057,6 +3057,14 @@ void Sema::CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *CD) { // We know there are no parameters. CD->setType(Context.getFunctionType(Context.VoidTy, 0, 0, EPI)); } + + if (ShouldDeleteDefaultConstructor(CD)) { + if (First) + CD->setDeletedAsWritten(); + else + Diag(CD->getLocation(), diag::err_out_of_line_default_deletes) + << getSpecialMember(CD); + } } bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) { -- 2.40.0