]> granicus.if.org Git - clang/commitdiff
Only look up an 'operator delete' on the definition of a destructor, not on
authorJohn McCall <rjmccall@apple.com>
Wed, 4 Aug 2010 01:04:25 +0000 (01:04 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 4 Aug 2010 01:04:25 +0000 (01:04 +0000)
a declaration.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110175 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
test/CXX/special/class.dtor/p9.cpp
test/SemaCXX/destructor.cpp

index 5252188635ff3b8db93b21d345593e1bc92e8c5f..e166e9cc2dc6c9be2942fb0a8bc51318d1787fde 100644 (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
index 5677b5c99333d3f6aa33afd52cf581f10d68fb12..204949d11eb91312971f0d592c54a0bfc2d88e75 100644 (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();
   
index 80acc2499d07aeaceca58ff834d18b78664c2617..13243f510f3e8cb7d6e391d09a0149882d799500 100644 (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}}
+  }
 }
index 4f6c76bc90edaf2be3d40fa461d21d36343aa392..1502f7347128121396a39408d6d355bbf89492e5 100644 (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}}
 }