[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