Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -1284,10 +1284,6 @@ return Sema::TDK_Success; } - // Set up the template argument deduction information for a failure. - Info.FirstArg = TemplateArgument(ParamIn); - Info.SecondArg = TemplateArgument(ArgIn); - // If the parameter is an already-substituted template parameter // pack, do nothing: we don't know which of its arguments to look // at, so we have to wait until all of the parameter packs in this @@ -1295,6 +1291,13 @@ if (isa(Param)) return Sema::TDK_Success; + // Set up the template argument deduction information for a failure. + // Save the original values in case deduction succeeds. + TemplateArgument OriginalFirstArg = Info.FirstArg; + TemplateArgument OriginalSecondArg = Info.SecondArg; + Info.FirstArg = TemplateArgument(ParamIn); + Info.SecondArg = TemplateArgument(ArgIn); + // Check the cv-qualifiers on the parameter and argument types. CanQualType CanParam = S.Context.getCanonicalType(Param); CanQualType CanArg = S.Context.getCanonicalType(Arg); @@ -1318,7 +1321,7 @@ return Sema::TDK_NonDeducedMismatch; } } - return Sema::TDK_Success; + goto Success; } } else if (!Param->isDependentType()) { CanQualType ParamUnqualType = CanParam.getUnqualifiedType(), @@ -1328,7 +1331,7 @@ ? S.isSameOrCompatibleFunctionType(ParamUnqualType, ArgUnqualType) : ParamUnqualType == ArgUnqualType; if (Success) - return Sema::TDK_Success; + goto Success; } switch (Param->getTypeClass()) { @@ -1354,14 +1357,17 @@ case Type::ObjCInterface: case Type::ObjCObjectPointer: { if (TDF & TDF_SkipNonDependent) - return Sema::TDK_Success; + goto Success; if (TDF & TDF_IgnoreQualifiers) { Param = Param.getUnqualifiedType(); Arg = Arg.getUnqualifiedType(); } - return Param == Arg? Sema::TDK_Success : Sema::TDK_NonDeducedMismatch; + if (Param == Arg) + goto Success; + + return Sema::TDK_NonDeducedMismatch; } // _Complex T [placeholder extension] @@ -1483,7 +1489,7 @@ NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, DependentArrayParm->getSizeExpr()); if (!NTTP) - return Sema::TDK_Success; + goto Success; // We can perform template argument deduction for the given non-type // template parameter. @@ -1543,7 +1549,7 @@ return Result; if (TDF & TDF_AllowCompatibleFunctionType) - return Sema::TDK_Success; + goto Success; // FIXME: Per core-2016/10/1019 (no corresponding core issue yet), permit // deducing through the noexcept-specifier if it's part of the canonical @@ -1578,7 +1584,7 @@ } // FIXME: Detect non-deduced exception specification mismatches? - return Sema::TDK_Success; + goto Success; } case Type::InjectedClassName: { @@ -1614,7 +1620,7 @@ S, TemplateParams, SpecParam, Arg, Info, Deduced); if (Result == Sema::TDK_Success) - return Result; + goto Success; // We cannot inspect base classes as part of deduction when the type // is incomplete, so either instantiate any templates necessary to @@ -1691,7 +1697,7 @@ if (Successful) { std::swap(SuccessfulDeduced, Deduced); - return Sema::TDK_Success; + goto Success; } return Result; @@ -1807,7 +1813,7 @@ NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr()); if (!NTTP) - return Sema::TDK_Success; + goto Success; llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false); ArgSize = VectorArg->getNumElements(); @@ -1833,7 +1839,7 @@ NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr()); if (!NTTP) - return Sema::TDK_Success; + goto Success; return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, VectorArg->getSizeExpr(), @@ -1863,7 +1869,7 @@ NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr( Info, AddressSpaceParam->getAddrSpaceExpr()); if (!NTTP) - return Sema::TDK_Success; + goto Success; return DeduceNonTypeTemplateArgument( S, TemplateParams, NTTP, AddressSpaceArg->getAddrSpaceExpr(), Info, @@ -1886,7 +1892,7 @@ NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr( Info, AddressSpaceParam->getAddrSpaceExpr()); if (!NTTP) - return Sema::TDK_Success; + goto Success; return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgAddressSpace, S.Context.IntTy, @@ -1908,10 +1914,15 @@ case Type::PackExpansion: case Type::Pipe: // No template argument deduction for these types - return Sema::TDK_Success; + goto Success; } llvm_unreachable("Invalid Type Class!"); + +Success: + Info.FirstArg = OriginalFirstArg; + Info.SecondArg = OriginalSecondArg; + return Sema::TDK_Success; } static Sema::TemplateDeductionResult Index: test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp =================================================================== --- test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp +++ test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp @@ -45,3 +45,11 @@ func(foo()); // expected-error {{no matching function}} } } + +namespace test4 { + // expected-note@+1 {{candidate template ignored: could not match 'int [N]' against 'int []'}} + template void f1(int (&arr)[N]); + template void f2(int (&arr)[]) { + f1(arr); // expected-error {{no matching function}} + } +}