diff options
author | Anders Carlsson <andersca@mac.com> | 2009-11-15 16:43:15 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-11-15 16:43:15 +0000 |
commit | 50724302e24d44a27e3bc45e7185a710d6eb3c2d (patch) | |
tree | d2b649dbc11eebe172d0937226db6593f52526aa | |
parent | 84423a8c8450a1f3ce82730fb35d5ee4e7980701 (diff) |
If we find a deallocation function in the class scope, but it is a placement function we should not look for a deallocation function in the global scope.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88851 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 17 | ||||
-rw-r--r-- | test/SemaCXX/new-delete.cpp | 10 |
3 files changed, 29 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 2cc29caa01..e3f2383798 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1739,6 +1739,10 @@ def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete " "expression of type %0 to a pointer">; def warn_delete_incomplete : Warning< "deleting pointer to incomplete type %0 may cause undefined behaviour">; +def err_no_suitable_delete_member_function_found : Error< + "no suitable member %0 in %1">; +def note_delete_member_function_declared_here : Note< + "%0 declared here">; def err_decrement_bool : Error<"cannot decrement expression of type bool">; def warn_increment_bool : Warning< "incrementing expression of type bool is deprecated">; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 3e07f3495e..f5ce44e106 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -844,12 +844,12 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName( ArrayForm ? OO_Array_Delete : OO_Delete); + LookupResult Found; if (Pointee->isRecordType() && !UseGlobal) { CXXRecordDecl *Record = cast<CXXRecordDecl>(Pointee->getAs<RecordType>()->getDecl()); // Try to find operator delete/operator delete[] in class scope. - LookupResult Found; LookupQualifiedName(Found, Record, DeleteName, LookupOrdinaryName); if (Found.isAmbiguous()) { @@ -867,6 +867,21 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, } } + if (!OperatorDelete && !Found.empty()) { + // We did find operator delete/operator delete[] declarations, but + // none of them were suitable. + Diag(StartLoc, diag::err_no_suitable_delete_member_function_found) + << DeleteName << Record; + + for (LookupResult::iterator F = Found.begin(), FEnd = Found.end(); + F != FEnd; ++F) { + Diag((*F)->getLocation(), + diag::note_delete_member_function_declared_here) + << DeleteName; + } + return ExprError(); + } + if (!Record->hasTrivialDestructor()) if (const CXXDestructorDecl *Dtor = Record->getDestructor(Context)) MarkDeclarationReferenced(StartLoc, diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp index 63a716338b..417ca8ff9e 100644 --- a/test/SemaCXX/new-delete.cpp +++ b/test/SemaCXX/new-delete.cpp @@ -178,7 +178,15 @@ public: class X8 : public X6, public X7 { }; -void f(X8* x8) { +void f(X8 *x8) { delete x8; // expected-error {{member 'operator delete' found in multiple base classes of different types}} } +class X9 { + static void operator delete(void*, int); // expected-note {{'operator delete' declared here}} + static void operator delete(void*, float); // expected-note {{'operator delete' declared here}} +}; + +void f(X9 *x9) { + delete x9; // expected-error {{no suitable member 'operator delete' in 'X9'}} +} |