summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-12-27 06:14:37 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-12-27 06:14:37 +0000
commitd92eddf02d02c7b16d4f909c88bc730663155aed (patch)
tree6500b8d03c2110b4924024f62a7236fb0678c015 /clang/lib
parentce044895150be24f6238bbf85146948c2d802d60 (diff)
downloadbcm5719-llvm-d92eddf02d02c7b16d4f909c88bc730663155aed.tar.gz
bcm5719-llvm-d92eddf02d02c7b16d4f909c88bc730663155aed.zip
Work around a standard defect: template argument deduction for non-type
template parameters of reference type basically doesn't work, because we're always deducing from an argument expression of non-reference type, so the type of the deduced expression never matches. Instead, compare the type of an expression naming the parameter to the type of the argument. llvm-svn: 290586
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp8
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp19
2 files changed, 19 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 83146afd022..8b8ab4a6e16 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5040,7 +5040,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
"non-type template parameter type cannot be qualified");
if (CTAK == CTAK_Deduced &&
- !Context.hasSameUnqualifiedType(ParamType, Arg->getType())) {
+ !Context.hasSameType(ParamType.getNonLValueExprType(Context),
+ Arg->getType().getNonLValueExprType(Context))) {
// C++ [temp.deduct.type]p17: (DR1770)
// If P has a form that contains <i>, and if the type of i differs from
// the type of the corresponding template parameter of the template named
@@ -5048,6 +5049,11 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
//
// Note that CTAK will be CTAK_DeducedFromArrayBound if the form was [i]
// rather than <i>.
+ //
+ // FIXME: We interpret the 'i' here as referring to the expression
+ // denoting the non-type template parameter rather than the parameter
+ // itself, and so strip off references before comparing types. It's
+ // not clear how this is supposed to work for references.
Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch)
<< Arg->getType().getUnqualifiedType()
<< ParamType.getUnqualifiedType();
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 2aad3bc249a..0e20ef2441d 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -327,13 +327,18 @@ static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(
}
Deduced[NTTP->getIndex()] = Result;
- return S.getLangOpts().CPlusPlus1z
- ? DeduceTemplateArgumentsByTypeMatch(
- S, TemplateParams, NTTP->getType(), ValueType, Info, Deduced,
- TDF_ParamWithReferenceType | TDF_SkipNonDependent,
- /*PartialOrdering=*/false,
- /*ArrayBound=*/NewDeduced.wasDeducedFromArrayBound())
- : Sema::TDK_Success;
+ if (!S.getLangOpts().CPlusPlus1z)
+ return Sema::TDK_Success;
+
+ // FIXME: It's not clear how deduction of a parameter of reference
+ // type from an argument (of non-reference type) should be performed.
+ // For now, we just remove reference types from both sides and let
+ // the final check for matching types sort out the mess.
+ return DeduceTemplateArgumentsByTypeMatch(
+ S, TemplateParams, NTTP->getType().getNonReferenceType(),
+ ValueType.getNonReferenceType(), Info, Deduced, TDF_SkipNonDependent,
+ /*PartialOrdering=*/false,
+ /*ArrayBound=*/NewDeduced.wasDeducedFromArrayBound());
}
/// \brief Deduce the value of the given non-type template parameter
OpenPOWER on IntegriCloud