[cfe-commits] r83212 - in /cfe/trunk: lib/CodeGen/CodeGenFunction.cpp test/CodeGenCXX/destructors.cpp

Douglas Gregor dgregor at apple.com
Thu Oct 1 13:44:19 PDT 2009


Author: dgregor
Date: Thu Oct  1 15:44:19 2009
New Revision: 83212

URL: http://llvm.org/viewvc/llvm-project?rev=83212&view=rev
Log:
CodeGen may see out-of-line declarations of the various special member
functions when they are explicitly declared, e.g., via a function
template specialization or explicit template instantiation
declaration. Don't try to synthesize bodies for the special member
functions in this case; rather, check whether we have an implicit
declaration and, if so, synthesize the appropriate function
body. Fixes PR5084.

Modified:
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/test/CodeGenCXX/destructors.cpp

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=83212&r1=83211&r2=83212&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Thu Oct  1 15:44:19 2009
@@ -239,28 +239,37 @@
     if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD))
       EmitDtorEpilogue(DD, GD.getDtorType());
     FinishFunction(S->getRBracLoc());
-  }
-  else
+  } else if (FD->isImplicit()) {
+    const CXXRecordDecl *ClassDecl =
+      cast<CXXRecordDecl>(FD->getDeclContext());
+    (void) ClassDecl;
     if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
-      const CXXRecordDecl *ClassDecl =
-        cast<CXXRecordDecl>(CD->getDeclContext());
-      (void) ClassDecl;
+      // FIXME: For C++0x, we want to look for implicit *definitions* of
+      // these special member functions, rather than implicit *declarations*.
       if (CD->isCopyConstructor(getContext())) {
         assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
-               "bogus constructor is being synthesize");
+               "Cannot synthesize a non-implicit copy constructor");
         SynthesizeCXXCopyConstructor(CD, GD.getCtorType(), Fn, Args);
-      }
-      else {
+      } else if (CD->isDefaultConstructor()) {
         assert(!ClassDecl->hasUserDeclaredConstructor() &&
-               "bogus constructor is being synthesize");
+               "Cannot synthesize a non-implicit default constructor.");
         SynthesizeDefaultConstructor(CD, GD.getCtorType(), Fn, Args);
+      } else {
+        assert(false && "Implicit constructor cannot be synthesized");
       }
-    }
-  else if (const CXXDestructorDecl *CD = dyn_cast<CXXDestructorDecl>(FD))
-    SynthesizeDefaultDestructor(CD, GD.getDtorType(), Fn, Args);
-  else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
-    if (MD->isCopyAssignment())
+    } else if (const CXXDestructorDecl *CD = dyn_cast<CXXDestructorDecl>(FD)) {
+      assert(!ClassDecl->hasUserDeclaredDestructor() &&
+             "Cannot synthesize a non-implicit destructor");
+      SynthesizeDefaultDestructor(CD, GD.getDtorType(), Fn, Args);
+    } else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+      assert(MD->isCopyAssignment() && 
+             !ClassDecl->hasUserDeclaredCopyAssignment() &&
+             "Cannot synthesize a method that is not an implicit-defined "
+             "copy constructor");
       SynthesizeCXXCopyAssignment(MD, Fn, Args);
+    } else {
+      assert(false && "Cannot synthesize unknown implicit function");
+    }
   }
 
   // Destroy the 'this' declaration.

Modified: cfe/trunk/test/CodeGenCXX/destructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/destructors.cpp?rev=83212&r1=83211&r2=83212&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/destructors.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/destructors.cpp Thu Oct  1 15:44:19 2009
@@ -19,4 +19,12 @@
   ~C();
 };
 
-C::~C() { }
\ No newline at end of file
+C::~C() { }
+
+// PR5084
+template<typename T>
+class A1 {
+  ~A1();
+};
+
+template<> A1<char>::~A1();





More information about the cfe-commits mailing list