@@ -56,8 +56,12 @@ namespace clang {
56
56
TDF_TopLevelParameterTypeList = 0x10 ,
57
57
// / \brief Within template argument deduction from overload resolution per
58
58
// / C++ [over.over] allow matching function types that are compatible in
59
- // / terms of noreturn and default calling convention adjustments.
60
- TDF_InOverloadResolution = 0x20
59
+ // / terms of noreturn and default calling convention adjustments, or
60
+ // / similarly matching a declared template specialization against a
61
+ // / possible template, per C++ [temp.deduct.decl]. In either case, permit
62
+ // / deduction where the parameter is a function type that can be converted
63
+ // / to the argument type.
64
+ TDF_AllowCompatibleFunctionType = 0x20 ,
61
65
};
62
66
}
63
67
@@ -1306,9 +1310,10 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
1306
1310
// If the parameter type is not dependent, there is nothing to deduce.
1307
1311
if (!Param->isDependentType ()) {
1308
1312
if (!(TDF & TDF_SkipNonDependent)) {
1309
- bool NonDeduced = (TDF & TDF_InOverloadResolution)?
1310
- !S.isSameOrCompatibleFunctionType (CanParam, CanArg) :
1311
- Param != Arg;
1313
+ bool NonDeduced =
1314
+ (TDF & TDF_AllowCompatibleFunctionType)
1315
+ ? !S.isSameOrCompatibleFunctionType (CanParam, CanArg)
1316
+ : Param != Arg;
1312
1317
if (NonDeduced) {
1313
1318
return Sema::TDK_NonDeducedMismatch;
1314
1319
}
@@ -1318,10 +1323,10 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
1318
1323
} else if (!Param->isDependentType ()) {
1319
1324
CanQualType ParamUnqualType = CanParam.getUnqualifiedType (),
1320
1325
ArgUnqualType = CanArg.getUnqualifiedType ();
1321
- bool Success = (TDF & TDF_InOverloadResolution)?
1322
- S. isSameOrCompatibleFunctionType (ParamUnqualType,
1323
- ArgUnqualType) :
1324
- ParamUnqualType == ArgUnqualType;
1326
+ bool Success =
1327
+ (TDF & TDF_AllowCompatibleFunctionType)
1328
+ ? S. isSameOrCompatibleFunctionType (ParamUnqualType, ArgUnqualType)
1329
+ : ParamUnqualType == ArgUnqualType;
1325
1330
if (Success)
1326
1331
return Sema::TDK_Success;
1327
1332
}
@@ -1524,17 +1529,56 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
1524
1529
return Sema::TDK_NonDeducedMismatch;
1525
1530
1526
1531
// Check return types.
1527
- if (Sema::TemplateDeductionResult Result =
1528
- DeduceTemplateArgumentsByTypeMatch (
1529
- S, TemplateParams, FunctionProtoParam->getReturnType (),
1530
- FunctionProtoArg->getReturnType (), Info, Deduced, 0 ))
1532
+ if (auto Result = DeduceTemplateArgumentsByTypeMatch (
1533
+ S, TemplateParams, FunctionProtoParam->getReturnType (),
1534
+ FunctionProtoArg->getReturnType (), Info, Deduced, 0 ))
1531
1535
return Result;
1532
1536
1533
- return DeduceTemplateArguments (
1534
- S, TemplateParams, FunctionProtoParam->param_type_begin (),
1535
- FunctionProtoParam->getNumParams (),
1536
- FunctionProtoArg->param_type_begin (),
1537
- FunctionProtoArg->getNumParams (), Info, Deduced, SubTDF);
1537
+ // Check parameter types.
1538
+ if (auto Result = DeduceTemplateArguments (
1539
+ S, TemplateParams, FunctionProtoParam->param_type_begin (),
1540
+ FunctionProtoParam->getNumParams (),
1541
+ FunctionProtoArg->param_type_begin (),
1542
+ FunctionProtoArg->getNumParams (), Info, Deduced, SubTDF))
1543
+ return Result;
1544
+
1545
+ if (TDF & TDF_AllowCompatibleFunctionType)
1546
+ return Sema::TDK_Success;
1547
+
1548
+ // FIXME: Per core-2016/10/1019 (no corresponding core issue yet), permit
1549
+ // deducing through the noexcept-specifier if it's part of the canonical
1550
+ // type. libstdc++ relies on this.
1551
+ Expr *NoexceptExpr = FunctionProtoParam->getNoexceptExpr ();
1552
+ if (NonTypeTemplateParmDecl *NTTP =
1553
+ NoexceptExpr ? getDeducedParameterFromExpr (Info, NoexceptExpr)
1554
+ : nullptr ) {
1555
+ assert (NTTP->getDepth () == Info.getDeducedDepth () &&
1556
+ " saw non-type template parameter with wrong depth" );
1557
+
1558
+ llvm::APSInt Noexcept (1 );
1559
+ switch (FunctionProtoArg->canThrow (S.Context )) {
1560
+ case CT_Cannot:
1561
+ Noexcept = 1 ;
1562
+ LLVM_FALLTHROUGH;
1563
+
1564
+ case CT_Can:
1565
+ // We give E in noexcept(E) the "deduced from array bound" treatment.
1566
+ // FIXME: Should we?
1567
+ return DeduceNonTypeTemplateArgument (
1568
+ S, TemplateParams, NTTP, Noexcept, S.Context .BoolTy ,
1569
+ /* ArrayBound*/ true , Info, Deduced);
1570
+
1571
+ case CT_Dependent:
1572
+ if (Expr *ArgNoexceptExpr = FunctionProtoArg->getNoexceptExpr ())
1573
+ return DeduceNonTypeTemplateArgument (
1574
+ S, TemplateParams, NTTP, ArgNoexceptExpr, Info, Deduced);
1575
+ // Can't deduce anything from throw(T...).
1576
+ break ;
1577
+ }
1578
+ }
1579
+ // FIXME: Detect non-deduced exception specification mismatches?
1580
+
1581
+ return Sema::TDK_Success;
1538
1582
}
1539
1583
1540
1584
case Type::InjectedClassName: {
@@ -1544,7 +1588,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
1544
1588
->getInjectedSpecializationType ();
1545
1589
assert (isa<TemplateSpecializationType>(Param) &&
1546
1590
" injected class name is not a template specialization type" );
1547
- // fall through
1591
+ LLVM_FALLTHROUGH;
1548
1592
}
1549
1593
1550
1594
// template-name<T> (where template-name refers to a class template)
@@ -2820,6 +2864,17 @@ Sema::SubstituteExplicitTemplateArguments(
2820
2864
if (FunctionType) {
2821
2865
auto EPI = Proto->getExtProtoInfo ();
2822
2866
EPI.ExtParameterInfos = ExtParamInfos.getPointerOrNull (ParamTypes.size ());
2867
+
2868
+ // In C++1z onwards, exception specifications are part of the function type,
2869
+ // so substitution into the type must also substitute into the exception
2870
+ // specification.
2871
+ SmallVector<QualType, 4 > ExceptionStorage;
2872
+ if (getLangOpts ().CPlusPlus1z &&
2873
+ SubstExceptionSpec (
2874
+ Function->getLocation (), EPI.ExceptionSpec , ExceptionStorage,
2875
+ MultiLevelTemplateArgumentList (*ExplicitArgumentList)))
2876
+ return TDK_SubstitutionFailure;
2877
+
2823
2878
*FunctionType = BuildFunctionType (ResultType, ParamTypes,
2824
2879
Function->getLocation (),
2825
2880
Function->getDeclName (),
@@ -3714,13 +3769,6 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
3714
3769
= FunctionTemplate->getTemplateParameters ();
3715
3770
QualType FunctionType = Function->getType ();
3716
3771
3717
- // When taking the address of a function, we require convertibility of
3718
- // the resulting function type. Otherwise, we allow arbitrary mismatches
3719
- // of calling convention, noreturn, and noexcept.
3720
- if (!IsAddressOfFunction)
3721
- ArgFunctionType = adjustCCAndNoReturn (ArgFunctionType, FunctionType,
3722
- /* AdjustExceptionSpec*/ true );
3723
-
3724
3772
// Substitute any explicit template arguments.
3725
3773
LocalInstantiationScope InstScope (*this );
3726
3774
SmallVector<DeducedTemplateArgument, 4 > Deduced;
@@ -3737,6 +3785,13 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
3737
3785
NumExplicitlySpecified = Deduced.size ();
3738
3786
}
3739
3787
3788
+ // When taking the address of a function, we require convertibility of
3789
+ // the resulting function type. Otherwise, we allow arbitrary mismatches
3790
+ // of calling convention and noreturn.
3791
+ if (!IsAddressOfFunction)
3792
+ ArgFunctionType = adjustCCAndNoReturn (ArgFunctionType, FunctionType,
3793
+ /* AdjustExceptionSpec*/ false );
3794
+
3740
3795
// Unevaluated SFINAE context.
3741
3796
EnterExpressionEvaluationContext Unevaluated (
3742
3797
*this , Sema::ExpressionEvaluationContext::Unevaluated);
@@ -3756,9 +3811,8 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
3756
3811
}
3757
3812
3758
3813
if (!ArgFunctionType.isNull ()) {
3759
- unsigned TDF = TDF_TopLevelParameterTypeList;
3760
- if (IsAddressOfFunction)
3761
- TDF |= TDF_InOverloadResolution;
3814
+ unsigned TDF =
3815
+ TDF_TopLevelParameterTypeList | TDF_AllowCompatibleFunctionType;
3762
3816
// Deduce template arguments from the function type.
3763
3817
if (TemplateDeductionResult Result
3764
3818
= DeduceTemplateArgumentsByTypeMatch (*this , TemplateParams,
@@ -3789,7 +3843,7 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(
3789
3843
!ResolveExceptionSpec (Info.getLocation (), SpecializationFPT))
3790
3844
return TDK_MiscellaneousDeductionFailure;
3791
3845
3792
- // Adjust the exception specification of the argument again to match the
3846
+ // Adjust the exception specification of the argument to match the
3793
3847
// substituted and resolved type we just formed. (Calling convention and
3794
3848
// noreturn can't be dependent, so we don't actually need this for them
3795
3849
// right now.)
@@ -5127,6 +5181,8 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
5127
5181
for (unsigned I = 0 , N = Proto->getNumParams (); I != N; ++I)
5128
5182
MarkUsedTemplateParameters (Ctx, Proto->getParamType (I), OnlyDeduced,
5129
5183
Depth, Used);
5184
+ if (auto *E = Proto->getNoexceptExpr ())
5185
+ MarkUsedTemplateParameters (Ctx, E, OnlyDeduced, Depth, Used);
5130
5186
break ;
5131
5187
}
5132
5188
0 commit comments