Only look up an 'operator delete' on the definition of a destructor, not on

a declaration.

llvm-svn: 110175
This commit is contained in:
John McCall 2010-08-04 01:04:25 +00:00
parent 5666b674f3
commit deb646ebb5
4 changed files with 34 additions and 11 deletions

View File

@ -3731,12 +3731,6 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
AddOverriddenMethods(Method->getParent(), Method);
}
// Additional checks for the destructor; make sure we do this after we
// figure out whether the destructor is virtual.
if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(NewFD))
if (!Destructor->getParent()->isDependentType())
CheckDestructor(Destructor);
// Extra checking for C++ overloaded operators (C++ [over.oper]).
if (NewFD->isOverloadedOperator() &&
CheckOverloadedOperatorDeclaration(NewFD))
@ -4793,9 +4787,13 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
!hasAnyErrorsInThisFunction())
DiagnoseInvalidJumps(Body);
if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl))
if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl)) {
if (!Destructor->getParent()->isDependentType())
CheckDestructor(Destructor);
MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
Destructor->getParent());
}
// If any errors have occurred, clear out any temporaries that may have
// been leftover. This ensures that these temporaries won't be picked up for

View File

@ -2877,8 +2877,9 @@ void Sema::CheckConstructor(CXXConstructorDecl *Constructor) {
ClassDecl->addedConstructor(Context, Constructor);
}
/// CheckDestructor - Checks a fully-formed destructor for well-formedness,
/// issuing any diagnostics required. Returns true on error.
/// CheckDestructor - Checks a fully-formed destructor definition for
/// well-formedness, issuing any diagnostics required. Returns true
/// on error.
bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
CXXRecordDecl *RD = Destructor->getParent();

View File

@ -43,6 +43,30 @@ namespace test1 {
using A::operator delete;
using B::operator delete;
~C(); // expected-error {{multiple suitable 'operator delete' functions in 'C'}}
~C();
};
C::~C() {} // expected-error {{multiple suitable 'operator delete' functions in 'C'}}
}
// ...at the point of definition of a virtual destructor...
namespace test2 {
struct A {
virtual ~A();
static void operator delete(void*, const int &);
};
struct B {
virtual ~B();
static void operator delete(void*, const int &); // expected-note {{declared here}}
};
B::~B() {} // expected-error {{no suitable member 'operator delete' in 'B'}}
struct CBase { virtual ~CBase(); };
struct C : CBase { // expected-error {{no suitable member 'operator delete' in 'C'}}
static void operator delete(void*, const int &); // expected-note {{declared here}}
};
void test() {
C c; // expected-note {{first required here}}
}
}

View File

@ -103,5 +103,5 @@ namespace test6 {
};
class B : A<int> { B(); };
B::B() {}
B::B() {} // expected-note {{in instantiation of member function 'test6::A<int>::~A' requested here}}
}