зеркало из https://github.com/microsoft/clang-1.git
Look through using declarations when deciding whether to use an operator
delete for a virtual destructor. Diagnose ambiguities. Fixes PR7803. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110173 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
03b0df95cd
Коммит
046a7466f2
|
@ -2400,6 +2400,8 @@ def err_delete_incomplete_class_type : Warning<
|
|||
"deleting incomplete class type %0; no conversions to pointer type">;
|
||||
def err_no_suitable_delete_member_function_found : Error<
|
||||
"no suitable member %0 in %1">;
|
||||
def err_ambiguous_suitable_delete_member_function_found : Error<
|
||||
"multiple suitable %0 functions in %1">;
|
||||
def note_member_declared_here : Note<
|
||||
"member %0 declared here">;
|
||||
def err_decrement_bool : Error<"cannot decrement expression of type bool">;
|
||||
|
|
|
@ -1298,15 +1298,31 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
|||
|
||||
Found.suppressDiagnostics();
|
||||
|
||||
llvm::SmallVector<DeclAccessPair,4> Matches;
|
||||
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
|
||||
F != FEnd; ++F) {
|
||||
if (CXXMethodDecl *Delete = dyn_cast<CXXMethodDecl>(*F))
|
||||
if (Delete->isUsualDeallocationFunction()) {
|
||||
Operator = Delete;
|
||||
CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
|
||||
F.getPair());
|
||||
return false;
|
||||
}
|
||||
CXXMethodDecl *Delete = cast<CXXMethodDecl>((*F)->getUnderlyingDecl());
|
||||
if (Delete->isUsualDeallocationFunction())
|
||||
Matches.push_back(F.getPair());
|
||||
}
|
||||
|
||||
// There's exactly one suitable operator; pick it.
|
||||
if (Matches.size() == 1) {
|
||||
Operator = cast<CXXMethodDecl>(Matches[0]->getUnderlyingDecl());
|
||||
CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
|
||||
Matches[0]);
|
||||
return false;
|
||||
|
||||
// We found multiple suitable operators; complain about the ambiguity.
|
||||
} else if (!Matches.empty()) {
|
||||
Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
|
||||
<< Name << RD;
|
||||
|
||||
for (llvm::SmallVectorImpl<DeclAccessPair>::iterator
|
||||
F = Matches.begin(), FEnd = Matches.end(); F != FEnd; ++F)
|
||||
Diag((*F)->getUnderlyingDecl()->getLocation(),
|
||||
diag::note_member_declared_here) << Name;
|
||||
return true;
|
||||
}
|
||||
|
||||
// We did find operator delete/operator delete[] declarations, but
|
||||
|
@ -1316,10 +1332,9 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
|||
<< Name << RD;
|
||||
|
||||
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
|
||||
F != FEnd; ++F) {
|
||||
Diag((*F)->getLocation(), diag::note_member_declared_here)
|
||||
<< Name;
|
||||
}
|
||||
F != FEnd; ++F)
|
||||
Diag((*F)->getUnderlyingDecl()->getLocation(),
|
||||
diag::note_member_declared_here) << Name;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
typedef typeof(sizeof(int)) size_t;
|
||||
|
||||
// PR7803
|
||||
namespace test0 {
|
||||
class A {
|
||||
public:
|
||||
static void operator delete(void *p) {};
|
||||
virtual ~A();
|
||||
};
|
||||
|
||||
class B : protected A {
|
||||
public:
|
||||
~B();
|
||||
};
|
||||
|
||||
class C : protected B {
|
||||
public:
|
||||
using B::operator delete;
|
||||
~C();
|
||||
};
|
||||
|
||||
// Shouldn't have an error.
|
||||
C::~C() {}
|
||||
}
|
||||
|
||||
namespace test1 {
|
||||
class A {
|
||||
public:
|
||||
static void operator delete(void *p) {}; // expected-note {{member 'operator delete' declared here}}
|
||||
virtual ~A();
|
||||
};
|
||||
|
||||
class B : protected A {
|
||||
public:
|
||||
static void operator delete(void *, size_t) {}; // expected-note {{member 'operator delete' declared here}}
|
||||
~B();
|
||||
};
|
||||
|
||||
class C : protected B {
|
||||
public:
|
||||
using A::operator delete;
|
||||
using B::operator delete;
|
||||
|
||||
~C(); // expected-error {{multiple suitable 'operator delete' functions in 'C'}}
|
||||
};
|
||||
}
|
Загрузка…
Ссылка в новой задаче