When clearing a LookupResult structure, clear out the naming class,

too. Fixes PR7900.

While I'm in this area, improve the diagnostic when the type being
destroyed doesn't match either of the types we found.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127041 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2011-03-04 22:32:08 +00:00
Родитель e3eb83b937
Коммит 7ec1873d69
5 изменённых файлов: 37 добавлений и 9 удалений

Просмотреть файл

@ -791,8 +791,13 @@ def err_destructor_name : Error<
"expected the class name after '~' to name the enclosing class">;
def err_destructor_class_name : Error<
"expected the class name after '~' to name a destructor">;
def err_ident_in_pseudo_dtor_not_a_type : Error<
"identifier %0 in pseudo-destructor expression does not name a type">;
def err_ident_in_dtor_not_a_type : Error<
"identifier %0 in object destruction expression does not name a type">;
def err_destructor_expr_type_mismatch : Error<
"destructor type %0 in object destruction expression does not match the "
"type %1 of the object being destroyed">;
def note_destructor_type_here : Note<
"type %0 is declared here">;
// C++ initialization
def err_init_conversion_failed : Error<

Просмотреть файл

@ -439,6 +439,7 @@ public:
Decls.clear();
if (Paths) deletePaths(Paths);
Paths = NULL;
NamingClass = 0;
}
/// \brief Clears out any current state and re-initializes for a

Просмотреть файл

@ -138,10 +138,11 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
LookInScope = true;
}
TypeDecl *NonMatchingTypeDecl = 0;
LookupResult Found(*this, &II, NameLoc, LookupOrdinaryName);
for (unsigned Step = 0; Step != 2; ++Step) {
// Look for the name first in the computed lookup context (if we
// have one) and, if that fails to find a match, in the sope (if
// have one) and, if that fails to find a match, in the scope (if
// we're allowed to look there).
Found.clear();
if (Step == 0 && LookupCtx)
@ -164,6 +165,9 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
return ParsedType::make(T);
}
if (!SearchType.isNull())
NonMatchingTypeDecl = Type;
}
// If the name that we found is a class template name, and it is
@ -244,8 +248,14 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
return ParsedType::make(T);
}
if (ObjectTypePtr)
Diag(NameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
if (NonMatchingTypeDecl) {
QualType T = Context.getTypeDeclType(NonMatchingTypeDecl);
Diag(NameLoc, diag::err_destructor_expr_type_mismatch)
<< T << SearchType;
Diag(NonMatchingTypeDecl->getLocation(), diag::note_destructor_type_here)
<< T;
} else if (ObjectTypePtr)
Diag(NameLoc, diag::err_ident_in_dtor_not_a_type)
<< &II;
else
Diag(NameLoc, diag::err_destructor_class_name);

Просмотреть файл

@ -177,3 +177,16 @@ namespace PR9238 {
class B { public: ~B(); };
class C : virtual B { public: ~C() { } };
}
namespace PR7900 {
struct A { // expected-note 2{{type 'PR7900::A' is declared here}}
};
struct B : public A {
};
void foo() {
B b;
b.~B();
b.~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
(&b)->~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
}
}

Просмотреть файл

@ -2,7 +2,7 @@
struct A {};
enum Foo { F };
typedef Foo Bar;
typedef Foo Bar; // expected-note{{type 'Bar' (aka 'Foo') is declared here}}
typedef int Integer;
typedef double Double;
@ -23,10 +23,9 @@ void f(A* a, Foo *f, int *i, double *d) {
a->~A();
a->A::~A();
a->~foo(); // expected-error{{identifier 'foo' in pseudo-destructor expression does not name a type}}
a->~foo(); // expected-error{{identifier 'foo' in object destruction expression does not name a type}}
// FIXME: the diagnostic below isn't wonderful
a->~Bar(); // expected-error{{does not name a type}}
a->~Bar(); // expected-error{{destructor type 'Bar' (aka 'Foo') in object destruction expression does not match the type 'A' of the object being destroyed}}
f->~Bar();
f->~Foo();