[cfe-commits] r123244 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateDeduction.cpp test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp

Douglas Gregor dgregor at apple.com
Tue Jan 11 09:34:58 PST 2011


Author: dgregor
Date: Tue Jan 11 11:34:58 2011
New Revision: 123244

URL: http://llvm.org/viewvc/llvm-project?rev=123244&view=rev
Log:
Implement C++ [temp.func.order]p5 more directly, by passing down the
number of explicit call arguments. This actually fixes an erroneous
test for [temp.deduct.partial]p11, where we were considering
parameters corresponding to arguments beyond those that were
explicitly provided.

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=123244&r1=123243&r2=123244&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jan 11 11:34:58 2011
@@ -3510,10 +3510,12 @@
   FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
                                                    FunctionTemplateDecl *FT2,
                                                    SourceLocation Loc,
-                                           TemplatePartialOrderingContext TPOC);
+                                           TemplatePartialOrderingContext TPOC,
+                                                   unsigned NumCallArguments);
   UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin,
                                            UnresolvedSetIterator SEnd,
                                            TemplatePartialOrderingContext TPOC,
+                                           unsigned NumCallArguments,
                                            SourceLocation Loc,
                                            const PartialDiagnostic &NoneDiag,
                                            const PartialDiagnostic &AmbigDiag,

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=123244&r1=123243&r2=123244&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Jan 11 11:34:58 2011
@@ -5897,7 +5897,8 @@
                                          Cand2.Function->getPrimaryTemplate(),
                                          Loc,
                        isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion 
-                                                             : TPOC_Call))
+                                                             : TPOC_Call,
+                                         NumArgs))
       return BetterTemplate == Cand1.Function->getPrimaryTemplate();
 
   //   -- the context is an initialization by user-defined conversion
@@ -6926,7 +6927,7 @@
     
     UnresolvedSetIterator Result =
         getMostSpecialized(MatchesCopy.begin(), MatchesCopy.end(),
-                           TPOC_Other, From->getLocStart(),
+                           TPOC_Other, 0, From->getLocStart(),
                            PDiag(),
                            PDiag(diag::err_addr_ovl_ambiguous)
                                << Matches[0].second->getDeclName(),

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=123244&r1=123243&r2=123244&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Jan 11 11:34:58 2011
@@ -4846,7 +4846,7 @@
   // Find the most specialized function template.
   UnresolvedSetIterator Result
     = getMostSpecialized(Candidates.begin(), Candidates.end(),
-                         TPOC_Other, FD->getLocation(),
+                         TPOC_Other, 0, FD->getLocation(),
                   PDiag(diag::err_function_template_spec_no_match) 
                     << FD->getDeclName(),
                   PDiag(diag::err_function_template_spec_ambiguous)
@@ -5668,7 +5668,7 @@
   
   // Find the most specialized function template specialization.
   UnresolvedSetIterator Result
-    = getMostSpecialized(Matches.begin(), Matches.end(), TPOC_Other, 
+    = getMostSpecialized(Matches.begin(), Matches.end(), TPOC_Other, 0,
                          D.getIdentifierLoc(), 
                      PDiag(diag::err_explicit_instantiation_not_known) << Name,
                      PDiag(diag::err_explicit_instantiation_ambiguous) << Name,

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=123244&r1=123243&r2=123244&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Tue Jan 11 11:34:58 2011
@@ -84,6 +84,15 @@
                         TemplateDeductionInfo &Info,
                       llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced);
 
+/// \brief Stores the result of comparing the qualifiers of two types, used
+/// when 
+enum DeductionQualifierComparison { 
+  NeitherMoreQualified = 0, 
+  ParamMoreQualified, 
+  ArgMoreQualified 
+};
+
+
 static Sema::TemplateDeductionResult
 DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
@@ -91,7 +100,10 @@
                         QualType Arg,
                         TemplateDeductionInfo &Info,
                         llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                        unsigned TDF);
+                        unsigned TDF,
+                        bool PartialOrdering = false,
+                        llvm::SmallVectorImpl<DeductionQualifierComparison> *
+                                                      QualifierComparisons = 0);
 
 static Sema::TemplateDeductionResult
 DeduceTemplateArguments(Sema &S,
@@ -621,6 +633,13 @@
 /// \param TDF bitwise OR of the TemplateDeductionFlags bits that describe
 /// how template argument deduction is performed.
 ///
+/// \param PartialOrdering If true, we are performing template argument
+/// deduction for during partial ordering for a call 
+/// (C++0x [temp.deduct.partial]).
+///
+/// \param QualifierComparisons If we're performing template argument deduction
+/// in the context of partial ordering, the set of qualifier comparisons.
+///
 /// \returns the result of template argument deduction so far. Note that a
 /// "success" result means that template argument deduction has not yet failed,
 /// but it may still fail, later, for other reasons.
@@ -631,7 +650,10 @@
                         const QualType *Args, unsigned NumArgs,
                         TemplateDeductionInfo &Info,
                       llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                        unsigned TDF) {
+                        unsigned TDF,
+                        bool PartialOrdering = false,
+                        llvm::SmallVectorImpl<DeductionQualifierComparison> *
+                                                     QualifierComparisons = 0) {
   // Fast-path check to see if we have too many/too few arguments.
   if (NumParams != NumArgs &&
       !(NumParams && isa<PackExpansionType>(Params[NumParams - 1])) &&
@@ -655,11 +677,14 @@
       if (ArgIdx >= NumArgs)
         return Sema::TDK_NonDeducedMismatch;
           
+      
       if (Sema::TemplateDeductionResult Result
-          = DeduceTemplateArguments(S, TemplateParams,
-                                    Params[ParamIdx],
-                                    Args[ArgIdx],
-                                    Info, Deduced, TDF))
+            = DeduceTemplateArguments(S, TemplateParams,
+                                      Params[ParamIdx],
+                                      Args[ArgIdx],
+                                      Info, Deduced, TDF,
+                                      PartialOrdering,
+                                      QualifierComparisons))
         return Result;
       
       ++ArgIdx;
@@ -716,7 +741,8 @@
       // Deduce template arguments from the pattern.
       if (Sema::TemplateDeductionResult Result 
           = DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx],
-                                    Info, Deduced))
+                                    Info, Deduced, PartialOrdering,
+                                    QualifierComparisons))
         return Result;
       
       // Capture the deduced template arguments for each parameter pack expanded
@@ -765,6 +791,12 @@
 /// \param TDF bitwise OR of the TemplateDeductionFlags bits that describe
 /// how template argument deduction is performed.
 ///
+/// \param PartialOrdering Whether we're performing template argument deduction
+/// in the context of partial ordering (C++0x [temp.deduct.partial]).
+///
+/// \param QualifierComparisons If we're performing template argument deduction
+/// in the context of partial ordering, the set of qualifier comparisons.
+///
 /// \returns the result of template argument deduction so far. Note that a
 /// "success" result means that template argument deduction has not yet failed,
 /// but it may still fail, later, for other reasons.
@@ -774,24 +806,68 @@
                         QualType ParamIn, QualType ArgIn,
                         TemplateDeductionInfo &Info,
                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                        unsigned TDF) {
+                        unsigned TDF,
+                        bool PartialOrdering,
+    llvm::SmallVectorImpl<DeductionQualifierComparison> *QualifierComparisons) {
   // We only want to look at the canonical types, since typedefs and
   // sugar are not part of template argument deduction.
   QualType Param = S.Context.getCanonicalType(ParamIn);
   QualType Arg = S.Context.getCanonicalType(ArgIn);
 
-  // C++0x [temp.deduct.call]p4 bullet 1:
-  //   - If the original P is a reference type, the deduced A (i.e., the type
-  //     referred to by the reference) can be more cv-qualified than the
-  //     transformed A.
-  if (TDF & TDF_ParamWithReferenceType) {
-    Qualifiers Quals;
-    QualType UnqualParam = S.Context.getUnqualifiedArrayType(Param, Quals);
-    Quals.setCVRQualifiers(Quals.getCVRQualifiers() &
-                           Arg.getCVRQualifiersThroughArrayTypes());
-    Param = S.Context.getQualifiedType(UnqualParam, Quals);
+  if (PartialOrdering) {
+    // C++0x [temp.deduct.partial]p5:
+    //   Before the partial ordering is done, certain transformations are 
+    //   performed on the types used for partial ordering: 
+    //     - If P is a reference type, P is replaced by the type referred to. 
+    const ReferenceType *ParamRef = Param->getAs<ReferenceType>();
+    if (ParamRef)
+      Param = ParamRef->getPointeeType();
+    
+    //     - If A is a reference type, A is replaced by the type referred to.
+    const ReferenceType *ArgRef = Arg->getAs<ReferenceType>();
+    if (ArgRef)
+      Arg = ArgRef->getPointeeType();
+    
+    if (QualifierComparisons && ParamRef && ArgRef) {
+      // C++0x [temp.deduct.partial]p6:
+      //   If both P and A were reference types (before being replaced with the 
+      //   type referred to above), determine which of the two types (if any) is 
+      //   more cv-qualified than the other; otherwise the types are considered
+      //   to be equally cv-qualified for partial ordering purposes. The result 
+      //   of this determination will be used below.
+      //
+      // We save this information for later, using it only when deduction 
+      // succeeds in both directions.
+      DeductionQualifierComparison QualifierResult = NeitherMoreQualified;
+      if (Param.isMoreQualifiedThan(Arg))
+        QualifierResult = ParamMoreQualified;
+      else if (Arg.isMoreQualifiedThan(Param))
+        QualifierResult = ArgMoreQualified;
+      QualifierComparisons->push_back(QualifierResult);
+    }
+    
+    // C++0x [temp.deduct.partial]p7:
+    //   Remove any top-level cv-qualifiers:
+    //     - If P is a cv-qualified type, P is replaced by the cv-unqualified 
+    //       version of P.
+    Param = Param.getUnqualifiedType();
+    //     - If A is a cv-qualified type, A is replaced by the cv-unqualified 
+    //       version of A.
+    Arg = Arg.getUnqualifiedType();
+  } else {
+    // C++0x [temp.deduct.call]p4 bullet 1:
+    //   - If the original P is a reference type, the deduced A (i.e., the type
+    //     referred to by the reference) can be more cv-qualified than the
+    //     transformed A.
+    if (TDF & TDF_ParamWithReferenceType) {
+      Qualifiers Quals;
+      QualType UnqualParam = S.Context.getUnqualifiedArrayType(Param, Quals);
+      Quals.setCVRQualifiers(Quals.getCVRQualifiers() &
+                             Arg.getCVRQualifiersThroughArrayTypes());
+      Param = S.Context.getQualifiedType(UnqualParam, Quals);
+    }
   }
-
+  
   // If the parameter type is not dependent, there is nothing to deduce.
   if (!Param->isDependentType()) {
     if (!(TDF & TDF_SkipNonDependent) && Param != Arg)
@@ -2300,7 +2376,7 @@
     //   for type deduction.
     ParamType = ParamRefType->getPointeeType();
   }
-  
+    
   // Overload sets usually make this parameter an undeduced
   // context, but there are sometimes special circumstances.
   if (ArgType == S.Context.OverloadTy) {
@@ -2786,90 +2862,6 @@
                                  QualType(), Specialization, Info);
 }
 
-/// \brief Stores the result of comparing the qualifiers of two types.
-enum DeductionQualifierComparison { 
-  NeitherMoreQualified = 0, 
-  ParamMoreQualified, 
-  ArgMoreQualified 
-};
-
-/// \brief Deduce the template arguments during partial ordering by comparing 
-/// the parameter type and the argument type (C++0x [temp.deduct.partial]).
-///
-/// \param S the semantic analysis object within which we are deducing
-///
-/// \param TemplateParams the template parameters that we are deducing
-///
-/// \param ParamIn the parameter type
-///
-/// \param ArgIn the argument type
-///
-/// \param Info information about the template argument deduction itself
-///
-/// \param Deduced the deduced template arguments
-///
-/// \returns the result of template argument deduction so far. Note that a
-/// "success" result means that template argument deduction has not yet failed,
-/// but it may still fail, later, for other reasons.
-static Sema::TemplateDeductionResult
-DeduceTemplateArgumentsDuringPartialOrdering(Sema &S,
-                                        TemplateParameterList *TemplateParams,
-                                             QualType ParamIn, QualType ArgIn,
-                                             TemplateDeductionInfo &Info,
-                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-   llvm::SmallVectorImpl<DeductionQualifierComparison> *QualifierComparisons) {
-  CanQualType Param = S.Context.getCanonicalType(ParamIn);
-  CanQualType Arg = S.Context.getCanonicalType(ArgIn);
-
-  // C++0x [temp.deduct.partial]p5:
-  //   Before the partial ordering is done, certain transformations are 
-  //   performed on the types used for partial ordering: 
-  //     - If P is a reference type, P is replaced by the type referred to. 
-  CanQual<ReferenceType> ParamRef = Param->getAs<ReferenceType>();
-  if (!ParamRef.isNull())
-    Param = ParamRef->getPointeeType();
-  
-  //     - If A is a reference type, A is replaced by the type referred to.
-  CanQual<ReferenceType> ArgRef = Arg->getAs<ReferenceType>();
-  if (!ArgRef.isNull())
-    Arg = ArgRef->getPointeeType();
-  
-  if (QualifierComparisons && !ParamRef.isNull() && !ArgRef.isNull()) {
-    // C++0x [temp.deduct.partial]p6:
-    //   If both P and A were reference types (before being replaced with the 
-    //   type referred to above), determine which of the two types (if any) is 
-    //   more cv-qualified than the other; otherwise the types are considered to 
-    //   be equally cv-qualified for partial ordering purposes. The result of this
-    //   determination will be used below.
-    //
-    // We save this information for later, using it only when deduction 
-    // succeeds in both directions.
-    DeductionQualifierComparison QualifierResult = NeitherMoreQualified;
-    if (Param.isMoreQualifiedThan(Arg))
-      QualifierResult = ParamMoreQualified;
-    else if (Arg.isMoreQualifiedThan(Param))
-      QualifierResult = ArgMoreQualified;
-    QualifierComparisons->push_back(QualifierResult);
-  }
-  
-  // C++0x [temp.deduct.partial]p7:
-  //   Remove any top-level cv-qualifiers:
-  //     - If P is a cv-qualified type, P is replaced by the cv-unqualified 
-  //       version of P.
-  Param = Param.getUnqualifiedType();
-  //     - If A is a cv-qualified type, A is replaced by the cv-unqualified 
-  //       version of A.
-  Arg = Arg.getUnqualifiedType();
-  
-  // C++0x [temp.deduct.partial]p8:
-  //   Using the resulting types P and A the deduction is then done as 
-  //   described in 14.9.2.5. If deduction succeeds for a given type, the type
-  //   from the argument template is considered to be at least as specialized
-  //   as the type from the parameter template.
-  return DeduceTemplateArguments(S, TemplateParams, Param, Arg, Info,
-                                 Deduced, TDF_None);
-}
-
 static void
 MarkUsedTemplateParameters(Sema &SemaRef, QualType T,
                            bool OnlyDeduced,
@@ -2907,6 +2899,7 @@
                                      FunctionTemplateDecl *FT1,
                                      FunctionTemplateDecl *FT2,
                                      TemplatePartialOrderingContext TPOC,
+                                     unsigned NumCallArguments,
     llvm::SmallVectorImpl<DeductionQualifierComparison> *QualifierComparisons) {
   FunctionDecl *FD1 = FT1->getTemplatedDecl();
   FunctionDecl *FD2 = FT2->getTemplatedDecl();  
@@ -2951,7 +2944,7 @@
     unsigned Skip1 = !S.getLangOptions().CPlusPlus0x && 
       IsNonStatic2 && !IsNonStatic1;
     if (S.getLangOptions().CPlusPlus0x && IsNonStatic1 && !IsNonStatic2)
-      MaybeAddImplicitObjectParameterType(S.Context, Method1, Args1);
+      MaybeAddImplicitObjectParameterType(S.Context, Method1, Args1);    
     Args1.insert(Args1.end(), 
                  Proto1->arg_type_begin() + Skip1, Proto1->arg_type_end());
 
@@ -2962,16 +2955,18 @@
       MaybeAddImplicitObjectParameterType(S.Context, Method2, Args2);
     Args2.insert(Args2.end(), 
                  Proto2->arg_type_begin() + Skip2, Proto2->arg_type_end());
-
-    unsigned NumParams = std::min(Args1.size(), Args2.size());
-    for (unsigned I = 0; I != NumParams; ++I)
-      if (DeduceTemplateArgumentsDuringPartialOrdering(S,
-                                                       TemplateParams,
-                                                       Args2[I],
-                                                       Args1[I],
-                                                       Info,
-                                                       Deduced,
-                                                       QualifierComparisons))
+    
+    // C++ [temp.func.order]p5:
+    //   The presence of unused ellipsis and default arguments has no effect on
+    //   the partial ordering of function templates.
+    if (Args1.size() > NumCallArguments)
+      Args1.resize(NumCallArguments);
+    if (Args2.size() > NumCallArguments)
+      Args2.resize(NumCallArguments);
+    if (DeduceTemplateArguments(S, TemplateParams, Args2.data(), Args2.size(),
+                                Args1.data(), Args1.size(), Info, Deduced,
+                                TDF_None, /*PartialOrdering=*/true,
+                                QualifierComparisons))
         return false;
     
     break;
@@ -2980,26 +2975,21 @@
   case TPOC_Conversion:
     //   - In the context of a call to a conversion operator, the return types
     //     of the conversion function templates are used.
-    if (DeduceTemplateArgumentsDuringPartialOrdering(S,
-                                                     TemplateParams,
-                                                     Proto2->getResultType(),
-                                                     Proto1->getResultType(),
-                                                     Info,
-                                                     Deduced,
-                                                     QualifierComparisons))
+    if (DeduceTemplateArguments(S, TemplateParams, Proto2->getResultType(),
+                                Proto1->getResultType(), Info, Deduced,
+                                TDF_None, /*PartialOrdering=*/true,
+                                QualifierComparisons))
       return false;
     break;
     
   case TPOC_Other:
     //   - In other contexts (14.6.6.2) the function template’s function type 
     //     is used.
-    if (DeduceTemplateArgumentsDuringPartialOrdering(S,
-                                                     TemplateParams,
-                                                     FD2->getType(),
-                                                     FD1->getType(),
-                                                     Info,
-                                                     Deduced,
-                                                     QualifierComparisons))
+    // FIXME: Don't we actually want to perform the adjustments on the parameter
+    // types?
+    if (DeduceTemplateArguments(S, TemplateParams, FD2->getType(), 
+                                FD1->getType(), Info, Deduced, TDF_None,
+                                /*PartialOrdering=*/true, QualifierComparisons))
       return false;
     break;
   }
@@ -3026,7 +3016,9 @@
   UsedParameters.resize(TemplateParams->size());
   switch (TPOC) {
   case TPOC_Call: {
-    unsigned NumParams = std::min(Proto1->getNumArgs(), Proto2->getNumArgs());
+    unsigned NumParams = std::min(NumCallArguments, 
+                                  std::min(Proto1->getNumArgs(), 
+                                           Proto2->getNumArgs()));
     if (S.getLangOptions().CPlusPlus0x && IsNonStatic2 && !IsNonStatic1)
       ::MarkUsedTemplateParameters(S, Method2->getThisType(S.Context), false, 
                                    TemplateParams->getDepth(), UsedParameters);
@@ -3070,16 +3062,22 @@
 /// \param TPOC the context in which we are performing partial ordering of
 /// function templates.
 ///
+/// \param NumCallArguments The number of arguments in a call, used only
+/// when \c TPOC is \c TPOC_Call.
+///
 /// \returns the more specialized function template. If neither
 /// template is more specialized, returns NULL.
 FunctionTemplateDecl *
 Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
                                  FunctionTemplateDecl *FT2,
                                  SourceLocation Loc,
-                                 TemplatePartialOrderingContext TPOC) {
+                                 TemplatePartialOrderingContext TPOC,
+                                 unsigned NumCallArguments) {
   llvm::SmallVector<DeductionQualifierComparison, 4> QualifierComparisons;
-  bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC, 0);
+  bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC, 
+                                          NumCallArguments, 0);
   bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC, 
+                                          NumCallArguments,
                                           &QualifierComparisons);
   
   if (Better1 != Better2) // We have a clear winner
@@ -3156,6 +3154,9 @@
 /// \param TPOC the partial ordering context to use to compare the function
 /// template specializations.
 ///
+/// \param NumCallArguments The number of arguments in a call, used only
+/// when \c TPOC is \c TPOC_Call.
+///
 /// \param Loc the location where the ambiguity or no-specializations 
 /// diagnostic should occur.
 ///
@@ -3181,8 +3182,9 @@
 /// template argument deduction.
 UnresolvedSetIterator
 Sema::getMostSpecialized(UnresolvedSetIterator SpecBegin,
-                         UnresolvedSetIterator SpecEnd,
+                        UnresolvedSetIterator SpecEnd,
                          TemplatePartialOrderingContext TPOC,
+                         unsigned NumCallArguments,
                          SourceLocation Loc,
                          const PartialDiagnostic &NoneDiag,
                          const PartialDiagnostic &AmbigDiag,
@@ -3206,7 +3208,7 @@
       = cast<FunctionDecl>(*I)->getPrimaryTemplate();
     assert(Challenger && "Not a function template specialization?");
     if (isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger,
-                                                  Loc, TPOC),
+                                                  Loc, TPOC, NumCallArguments),
                        Challenger)) {
       Best = I;
       BestTemplate = Challenger;
@@ -3221,7 +3223,7 @@
       = cast<FunctionDecl>(*I)->getPrimaryTemplate();
     if (I != Best &&
         !isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger, 
-                                                   Loc, TPOC),
+                                                   Loc, TPOC, NumCallArguments),
                         BestTemplate)) {
       Ambiguous = true;
       break;
@@ -3293,13 +3295,10 @@
   
   // Determine whether PS1 is at least as specialized as PS2
   Deduced.resize(PS2->getTemplateParameters()->size());
-  bool Better1 = !DeduceTemplateArgumentsDuringPartialOrdering(*this,
-                                                  PS2->getTemplateParameters(),
-                                                               PT2,
-                                                               PT1,
-                                                               Info,
-                                                               Deduced,
-                                                               0);
+  bool Better1 = !::DeduceTemplateArguments(*this, PS2->getTemplateParameters(),
+                                            PT2, PT1, Info, Deduced, TDF_None,
+                                            /*PartialOrdering=*/true, 
+                                            /*QualifierComparisons=*/0);
   if (Better1) {
     InstantiatingTemplate Inst(*this, PS2->getLocation(), PS2,
                                Deduced.data(), Deduced.size(), Info);
@@ -3311,13 +3310,10 @@
   // Determine whether PS2 is at least as specialized as PS1
   Deduced.clear();
   Deduced.resize(PS1->getTemplateParameters()->size());
-  bool Better2 = !DeduceTemplateArgumentsDuringPartialOrdering(*this,
-                                                  PS1->getTemplateParameters(),
-                                                               PT1,
-                                                               PT2,
-                                                               Info,
-                                                               Deduced,
-                                                               0);
+  bool Better2 = !::DeduceTemplateArguments(*this, PS1->getTemplateParameters(),
+                                            PT1, PT2, Info, Deduced, TDF_None,
+                                            /*PartialOrdering=*/true,
+                                            /*QualifierComparisons=*/0);
   if (Better2) {
     InstantiatingTemplate Inst(*this, PS1->getLocation(), PS1,
                                Deduced.data(), Deduced.size(), Info);

Modified: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp?rev=123244&r1=123243&r2=123244&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp Tue Jan 11 11:34:58 2011
@@ -13,10 +13,10 @@
 };
 
 template <class T> 
-  T* f2(int, typename identity<T>::type = 0); // expected-note{{candidate}}
+  T* f2(int, typename identity<T>::type = 0);
 template <class T, class U> 
-  T& f2(U, typename identity<T>::type = 0); // expected-note{{candidate}}
+  T& f2(U, typename identity<T>::type = 0);
 
 void g2() {
-  f2<int>(1); // expected-error{{ambiguous}}
+  int* ip = f2<int>(1);
 }





More information about the cfe-commits mailing list