From: Richard Smith Date: Sun, 26 Feb 2012 07:51:39 +0000 (+0000) Subject: Make sure we don't try to produce a definition of an implicitly-deleted function X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=03f68788036803c0bad3fe6ea9a4ea31ba195a2b;p=clang Make sure we don't try to produce a definition of an implicitly-deleted function git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151478 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 9a31dd8ef8..ea678688bb 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -7227,7 +7227,8 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) { void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, CXXDestructorDecl *Destructor) { assert((Destructor->isDefaulted() && - !Destructor->doesThisDeclarationHaveABody()) && + !Destructor->doesThisDeclarationHaveABody() && + !Destructor->isDeleted()) && "DefineImplicitDestructor - call it for implicit default dtor"); CXXRecordDecl *ClassDecl = Destructor->getParent(); assert(ClassDecl && "DefineImplicitDestructor - invalid destructor"); @@ -7677,7 +7678,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, assert((CopyAssignOperator->isDefaulted() && CopyAssignOperator->isOverloadedOperator() && CopyAssignOperator->getOverloadedOperator() == OO_Equal && - !CopyAssignOperator->doesThisDeclarationHaveABody()) && + !CopyAssignOperator->doesThisDeclarationHaveABody() && + !CopyAssignOperator->isDeleted()) && "DefineImplicitCopyAssignment called for wrong function"); CXXRecordDecl *ClassDecl = CopyAssignOperator->getParent(); @@ -8105,7 +8107,8 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation, assert((MoveAssignOperator->isDefaulted() && MoveAssignOperator->isOverloadedOperator() && MoveAssignOperator->getOverloadedOperator() == OO_Equal && - !MoveAssignOperator->doesThisDeclarationHaveABody()) && + !MoveAssignOperator->doesThisDeclarationHaveABody() && + !MoveAssignOperator->isDeleted()) && "DefineImplicitMoveAssignment called for wrong function"); CXXRecordDecl *ClassDecl = MoveAssignOperator->getParent(); @@ -8592,7 +8595,8 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *CopyConstructor) { assert((CopyConstructor->isDefaulted() && CopyConstructor->isCopyConstructor() && - !CopyConstructor->doesThisDeclarationHaveABody()) && + !CopyConstructor->doesThisDeclarationHaveABody() && + !CopyConstructor->isDeleted()) && "DefineImplicitCopyConstructor - call it for implicit copy ctor"); CXXRecordDecl *ClassDecl = CopyConstructor->getParent(); @@ -8747,7 +8751,8 @@ void Sema::DefineImplicitMoveConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *MoveConstructor) { assert((MoveConstructor->isDefaulted() && MoveConstructor->isMoveConstructor() && - !MoveConstructor->doesThisDeclarationHaveABody()) && + !MoveConstructor->doesThisDeclarationHaveABody() && + !MoveConstructor->isDeleted()) && "DefineImplicitMoveConstructor - call it for implicit move ctor"); CXXRecordDecl *ClassDecl = MoveConstructor->getParent(); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5d6f5ef7f4..10ae8f4bad 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9420,7 +9420,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { // Note that this declaration has been used. if (CXXConstructorDecl *Constructor = dyn_cast(Func)) { - if (Constructor->isDefaulted()) { + if (Constructor->isDefaulted() && !Constructor->isDeleted()) { if (Constructor->isDefaultConstructor()) { if (Constructor->isTrivial()) return; @@ -9438,12 +9438,14 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { MarkVTableUsed(Loc, Constructor->getParent()); } else if (CXXDestructorDecl *Destructor = dyn_cast(Func)) { - if (Destructor->isDefaulted() && !Destructor->isUsed(false)) + if (Destructor->isDefaulted() && !Destructor->isDeleted() && + !Destructor->isUsed(false)) DefineImplicitDestructor(Loc, Destructor); if (Destructor->isVirtual()) MarkVTableUsed(Loc, Destructor->getParent()); } else if (CXXMethodDecl *MethodDecl = dyn_cast(Func)) { - if (MethodDecl->isDefaulted() && MethodDecl->isOverloadedOperator() && + if (MethodDecl->isDefaulted() && !MethodDecl->isDeleted() && + MethodDecl->isOverloadedOperator() && MethodDecl->getOverloadedOperator() == OO_Equal) { if (!MethodDecl->isUsed(false)) { if (MethodDecl->isCopyAssignmentOperator()) diff --git a/test/SemaCXX/defaulted-private-dtor.cpp b/test/SemaCXX/defaulted-private-dtor.cpp index a4b868c0ad..600dc3ca61 100644 --- a/test/SemaCXX/defaulted-private-dtor.cpp +++ b/test/SemaCXX/defaulted-private-dtor.cpp @@ -2,7 +2,7 @@ class BadDtor { // A private, but nonetheless trivial, destructor. - ~BadDtor() = default; // expected-note 11{{here}} + ~BadDtor() = default; // expected-note 9{{here}} friend class K; }; void f() { @@ -14,13 +14,13 @@ void f() { } struct V { // expected-note {{here}} V(); - BadDtor bd; // expected-error {{private destructor}} + BadDtor bd; }; -V v; // expected-error {{deleted function}} expected-note {{required here}} -struct W : BadDtor { // expected-note {{here}} expected-error {{private destructor}} +V v; // expected-error {{deleted function}} +struct W : BadDtor { // expected-note {{here}} W(); }; -W w; // expected-error {{deleted function}} expected-note {{required here}} +W w; // expected-error {{deleted function}} struct X : BadDtor { // expected-error {{private destructor}} ~X() {} };