]> granicus.if.org Git - clang/commitdiff
Revert r88718, which does NOT solve the constructor-template-as-copy-constructor...
authorDouglas Gregor <dgregor@apple.com>
Fri, 13 Nov 2009 23:59:09 +0000 (23:59 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 13 Nov 2009 23:59:09 +0000 (23:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88724 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/AST/DeclCXX.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaOverload.cpp
lib/Sema/SemaTemplateDeduction.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaCXX/constructor-recovery.cpp
test/SemaCXX/copy-constructor-error.cpp
test/SemaTemplate/constructor-template.cpp
test/SemaTemplate/operator-template.cpp

index 7f44d53411cf69e1bc235c707865bb177dc89ee5..2cc29caa0173b40c61af696cbded0265315b682f 100644 (file)
@@ -487,8 +487,6 @@ def err_constructor_return_type : Error<
 def err_constructor_redeclared : Error<"constructor cannot be redeclared">;
 def err_constructor_byvalue_arg : Error<
   "copy constructor must pass its first argument by reference">;
-def err_constructor_template_is_copy_constructor : Error<
-  "constructor template %0 instantiates to a copy constructor">;
 
 // C++ destructors
 def err_destructor_not_member : Error<
index 69a577f1e70308f0bc3d61a03ba2b05e74f62ce2..e325a25c76278e7114309483951b4fd4bd3262c4 100644 (file)
@@ -707,23 +707,23 @@ CXXConstructorDecl::isCopyConstructor(ASTContext &Context,
   //   if its first parameter is of type X&, const X&, volatile X& or
   //   const volatile X&, and either there are no other parameters
   //   or else all other parameters have default arguments (8.3.6).
-  //
-  // Note that we also test cv 'X' as a copy constructor, even though it is
-  // ill-formed, because this helps enforce C++ [class.copy]p3.
   if ((getNumParams() < 1) ||
       (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
+      (getPrimaryTemplate() != 0) ||
       (getDescribedFunctionTemplate() != 0))
     return false;
 
   const ParmVarDecl *Param = getParamDecl(0);
 
   // Do we have a reference type? Rvalue references don't count.
-  CanQualType PointeeType = Context.getCanonicalType(Param->getType());
-  if (CanQual<LValueReferenceType> ParamRefType =
-                                     PointeeType->getAs<LValueReferenceType>())
-    PointeeType = ParamRefType->getPointeeType();
+  const LValueReferenceType *ParamRefType =
+    Param->getType()->getAs<LValueReferenceType>();
+  if (!ParamRefType)
+    return false;
 
-  // Do we have our class type?
+  // Is it a reference to our class type?
+  CanQualType PointeeType
+    = Context.getCanonicalType(ParamRefType->getPointeeType());
   CanQualType ClassTy 
     = Context.getCanonicalType(Context.getTagDeclType(getParent()));
   if (PointeeType.getUnqualifiedType() != ClassTy)
index 30d046f3b96ef33d69ccb6e428c8344949d57235..fa31cc5ddb0b7adc9710e07c63d8fee29916f5d3 100644 (file)
@@ -3909,9 +3909,6 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
         << FD->getNameAsCString() << "dllimport";
     }
   }
-  
-  assert(ExprTemporaries.empty() && "Leftover temporaries before starting");
-
   return DeclPtrTy::make(FD);
 }
 
index 70b080e678d118c678024f849421624f74f4bc41..3948b22f7b6ebfebac97ec8e3d0d556481fcb130 100644 (file)
@@ -2237,9 +2237,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
     // argument doesn't participate in overload resolution.
   }
 
-  // FIXME: It would be nice if it were safe to keep invalid methods in the
-  // overload set (but it isn't due to broken copy constructors).
-  if (!CandidateSet.isNewCandidate(Function) || Function->isInvalidDecl())
+  if (!CandidateSet.isNewCandidate(Function))
     return;
     
   // Add this candidate
index fcec654334e698635ee957184d30c349471e6ad6..244bb37c37e19eace4f072c796e70f310b924e40 100644 (file)
@@ -1286,7 +1286,7 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
   for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
     if (Deduced[I].isNull()) {
       Info.Param = makeTemplateParameter(
-                          const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+                            const_cast<NamedDecl *>(TemplateParams->getParam(I)));
       return TDK_Incomplete;
     }
 
index 0e42bd65db22eeb4b976b2572ab457b46803149e..47d2701bcd3613440ed5ac429a5148f0c50a2cf6 100644 (file)
@@ -658,12 +658,6 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
                                                     TemplateParams, Function);
     Function->setDescribedFunctionTemplate(FunctionTemplate);
     FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext());
-  } else if (FunctionTemplate) {
-    // Record this function template specialization.
-    Function->setFunctionTemplateSpecialization(SemaRef.Context,
-                                                FunctionTemplate,
-                                                &TemplateArgs.getInnermost(),
-                                                InsertPos);
   }
     
   if (InitFunctionInstantiation(Function, D))
@@ -715,6 +709,14 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
       Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
   }
 
+  if (FunctionTemplate && !TemplateParams) {
+    // Record this function template specialization.
+    Function->setFunctionTemplateSpecialization(SemaRef.Context,
+                                                FunctionTemplate,
+                                                &TemplateArgs.getInnermost(),
+                                                InsertPos);
+  }
+
   return Function;
 }
 
@@ -809,17 +811,9 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
     if (D->isOutOfLine())
       FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext());
     Method->setDescribedFunctionTemplate(FunctionTemplate);
-  } else if (FunctionTemplate) {
-    // Record this function template specialization.
-    Method->setFunctionTemplateSpecialization(SemaRef.Context,
-                                              FunctionTemplate,
-                                              &TemplateArgs.getInnermost(),
-                                              InsertPos);
-  } else {
-    // Record this instantiation of a member function.
+  } else if (!FunctionTemplate)
     Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
-  }
-  
+
   // If we are instantiating a member function defined
   // out-of-line, the instantiation will have the same lexical
   // context (which will be a namespace scope) as the template.
@@ -831,20 +825,6 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
     Params[P]->setOwningFunction(Method);
   Method->setParams(SemaRef.Context, Params.data(), Params.size());
 
-  if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Method)) {
-    // C++ [class.copy]p3:
-    //   [...] A member function template is never instantiated to perform the
-    //   copy of a class object to an object of its class type.
-    if (FunctionTemplate && !TemplateParams &&
-        Constructor->isCopyConstructor(SemaRef.Context)) {
-      SemaRef.Diag(Constructor->getLocation(), 
-                   diag::err_constructor_template_is_copy_constructor)
-        << Constructor;
-      Method->setInvalidDecl();
-      return Method;
-    }
-  }
-    
   if (InitMethodInstantiation(Method, D))
     Method->setInvalidDecl();
 
@@ -863,6 +843,13 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
       PrevDecl = 0;
   }
 
+  if (FunctionTemplate && !TemplateParams)
+    // Record this function template specialization.
+    Method->setFunctionTemplateSpecialization(SemaRef.Context,
+                                              FunctionTemplate,
+                                              &TemplateArgs.getInnermost(),
+                                              InsertPos);
+
   bool Redeclaration = false;
   bool OverloadableAttrRequired = false;
   SemaRef.CheckFunctionDeclaration(Method, PrevDecl, false, Redeclaration,
index f2f9f43a10d4aeb4f9341f5233df4304b2afdef0..50fdc9622e4c7ecde2869e0278f4f7c5f2515218 100644 (file)
@@ -1,9 +1,10 @@
 // RUN: clang-cc -fsyntax-only -verify %s
 
-struct C {
-  virtual C() = 0; // expected-error{{constructor cannot be declared 'virtual'}}
+struct C {  // expected-note {{candidate function}}
+  virtual C() = 0; // expected-error{{constructor cannot be declared 'virtual'}} \
+                      expected-note {{candidate function}}
 };
 
 void f() {
- C c;
+ C c;  // expected-error {{call to constructor of 'c' is ambiguous}}
 }
index c50a1579bbdb44950b0c540d2e90ada87bb7179a..2e42fcc3b1cd82a849efcde9678a4c23883b8b34 100644 (file)
@@ -1,11 +1,13 @@
 // RUN: clang-cc -fsyntax-only -verify %s 
 
-struct S {
-   S (S);  // expected-error {{copy constructor must pass its first argument by reference}}
+struct S { // expected-note {{candidate function}} 
+   S (S);  // expected-error {{copy constructor must pass its first argument by reference}} \\
+           // expected-note {{candidate function}}
 };
 
 S f();
 
 void g() { 
-  S a( f() );  // expected-error {{no matching constructor}}
+  S a( f() );  // expected-error {{call to constructor of 'a' is ambiguous}}
 }
+
index f05976635670cd8bba040fa6afe812b4d70c9199..79bf7c585e349aaf9e59e51c39592b3edd493694 100644 (file)
@@ -1,4 +1,5 @@
 // RUN: clang-cc -fsyntax-only -verify %s
+
 struct X0 { // expected-note{{candidate}}
   X0(int); // expected-note{{candidate}}
   template<typename T> X0(T);
@@ -51,22 +52,3 @@ template<class C> struct A {};
 template <> struct A<int>{A(const A<int>&);};
 struct B { A<int> x; B(B& a) : x(a.x) {} };
 
-struct X2 {
-  X2();
-  X2(X2&);
-  template<typename T> X2(T, int = 17);
-};
-
-X2 test(bool Cond, X2 x2) {
-  if (Cond)
-    return x2; // okay, uses copy constructor
-  
-  return X2(); // expected-error{{incompatible type}}
-}
-
-struct X3 {
-  template<typename T> X3(T);
-};
-
-template<> X3::X3(X3); // expected-error{{no function template matches}}
-
index af01a10042dd8b1ed70e6290db4f606dd6c00132..7039e0ec83de4072794eef9b241b55f3da342449 100644 (file)
@@ -11,8 +11,6 @@ int a0(A<int> x) { return x == 1; }
 template<class X>struct B{typedef X Y;};
 template<class X>bool operator==(B<X>*,typename B<X>::Y); // \
 expected-error{{overloaded 'operator==' must have at least one parameter of class or enumeration type}} \
-expected-note{{in instantiation of function template specialization}}
-int a(B<int> x) { 
-  return operator==(&x,1);  // expected-error{{no matching function}}
-}
+expected-note{{in instantiation of member function}}
+int a(B<int> x) { return operator==(&x,1); }