[cfe-commits] r127041 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Lookup.h lib/Sema/SemaExprCXX.cpp test/SemaCXX/destructor.cpp test/SemaCXX/pseudo-destructors.cpp

Douglas Gregor dgregor at apple.com
Fri Mar 4 14:32:08 PST 2011


Author: dgregor
Date: Fri Mar  4 16:32:08 2011
New Revision: 127041

URL: http://llvm.org/viewvc/llvm-project?rev=127041&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Lookup.h
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/SemaCXX/destructor.cpp
    cfe/trunk/test/SemaCXX/pseudo-destructors.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=127041&r1=127040&r2=127041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Mar  4 16:32:08 2011
@@ -791,8 +791,13 @@
   "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<

Modified: cfe/trunk/include/clang/Sema/Lookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Lookup.h?rev=127041&r1=127040&r2=127041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Lookup.h (original)
+++ cfe/trunk/include/clang/Sema/Lookup.h Fri Mar  4 16:32:08 2011
@@ -439,6 +439,7 @@
     Decls.clear();
     if (Paths) deletePaths(Paths);
     Paths = NULL;
+    NamingClass = 0;
   }
 
   /// \brief Clears out any current state and re-initializes for a

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=127041&r1=127040&r2=127041&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Mar  4 16:32:08 2011
@@ -138,10 +138,11 @@
     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 @@
 
         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 @@
     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);

Modified: cfe/trunk/test/SemaCXX/destructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/destructor.cpp?rev=127041&r1=127040&r2=127041&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/destructor.cpp (original)
+++ cfe/trunk/test/SemaCXX/destructor.cpp Fri Mar  4 16:32:08 2011
@@ -177,3 +177,16 @@
   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}}
+  }
+}

Modified: cfe/trunk/test/SemaCXX/pseudo-destructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pseudo-destructors.cpp?rev=127041&r1=127040&r2=127041&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/pseudo-destructors.cpp (original)
+++ cfe/trunk/test/SemaCXX/pseudo-destructors.cpp Fri Mar  4 16:32:08 2011
@@ -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 @@
   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();





More information about the cfe-commits mailing list