diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-27 06:14:37 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-27 06:14:37 +0000 |
commit | d92eddf02d02c7b16d4f909c88bc730663155aed (patch) | |
tree | 6500b8d03c2110b4924024f62a7236fb0678c015 /clang/lib | |
parent | ce044895150be24f6238bbf85146948c2d802d60 (diff) | |
download | bcm5719-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.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 19 |
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 |