if (Trap.hasErrorOccurred())
return Sema::TDK_SubstitutionFailure;
- return ::FinishTemplateArgumentDeduction(
- *this, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info);
+ TemplateDeductionResult Result;
+ runWithSufficientStackSpace(Info.getLocation(), [&] {
+ Result = ::FinishTemplateArgumentDeduction(*this, Partial,
+ /*IsPartialOrdering=*/false,
+ TemplateArgs, Deduced, Info);
+ });
+ return Result;
}
/// Perform template argument deduction to determine whether
if (Trap.hasErrorOccurred())
return Sema::TDK_SubstitutionFailure;
- return ::FinishTemplateArgumentDeduction(
- *this, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info);
+ TemplateDeductionResult Result;
+ runWithSufficientStackSpace(Info.getLocation(), [&] {
+ Result = ::FinishTemplateArgumentDeduction(*this, Partial,
+ /*IsPartialOrdering=*/false,
+ TemplateArgs, Deduced, Info);
+ });
+ return Result;
}
/// Determine whether the given type T is a simple-template-id type.
SmallVector<QualType, 8> ParamTypes;
unsigned NumExplicitlySpecified = 0;
if (ExplicitTemplateArgs) {
- TemplateDeductionResult Result =
- SubstituteExplicitTemplateArguments(FunctionTemplate,
- *ExplicitTemplateArgs,
- Deduced,
- ParamTypes,
- nullptr,
- Info);
+ TemplateDeductionResult Result;
+ runWithSufficientStackSpace(Info.getLocation(), [&] {
+ Result = SubstituteExplicitTemplateArguments(
+ FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr,
+ Info);
+ });
if (Result)
return Result;
// that is needed when the accessibility of template arguments is checked.
DeclContext *CallingCtx = CurContext;
- return FinishTemplateArgumentDeduction(
- FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
- &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() {
- ContextRAII SavedContext(*this, CallingCtx);
- return CheckNonDependent(ParamTypesForArgChecking);
- });
+ TemplateDeductionResult Result;
+ runWithSufficientStackSpace(Info.getLocation(), [&] {
+ Result = FinishTemplateArgumentDeduction(
+ FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info,
+ &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() {
+ ContextRAII SavedContext(*this, CallingCtx);
+ return CheckNonDependent(ParamTypesForArgChecking);
+ });
+ });
+ return Result;
}
QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType,
unsigned NumExplicitlySpecified = 0;
SmallVector<QualType, 4> ParamTypes;
if (ExplicitTemplateArgs) {
- if (TemplateDeductionResult Result
- = SubstituteExplicitTemplateArguments(FunctionTemplate,
- *ExplicitTemplateArgs,
- Deduced, ParamTypes,
- &FunctionType, Info))
+ TemplateDeductionResult Result;
+ runWithSufficientStackSpace(Info.getLocation(), [&] {
+ Result = SubstituteExplicitTemplateArguments(
+ FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes,
+ &FunctionType, Info);
+ });
+ if (Result)
return Result;
NumExplicitlySpecified = Deduced.size();
return Result;
}
- if (TemplateDeductionResult Result
- = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
- NumExplicitlySpecified,
- Specialization, Info))
+ TemplateDeductionResult Result;
+ runWithSufficientStackSpace(Info.getLocation(), [&] {
+ Result = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced,
+ NumExplicitlySpecified,
+ Specialization, Info);
+ });
+ if (Result)
return Result;
// If the function has a deduced return type, deduce it now, so we can check
LocalInstantiationScope InstScope(*this);
// Finish template argument deduction.
FunctionDecl *ConversionSpecialized = nullptr;
- TemplateDeductionResult Result
- = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0,
- ConversionSpecialized, Info);
+ TemplateDeductionResult Result;
+ runWithSufficientStackSpace(Info.getLocation(), [&] {
+ Result = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0,
+ ConversionSpecialized, Info);
+ });
Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized);
return Result;
}
Sema::InstantiatingTemplate Inst(S, Info.getLocation(), P2, DeducedArgs,
Info);
auto *TST1 = T1->castAs<TemplateSpecializationType>();
- if (FinishTemplateArgumentDeduction(
- S, P2, /*IsPartialOrdering=*/true,
- TemplateArgumentList(TemplateArgumentList::OnStack,
- TST1->template_arguments()),
- Deduced, Info))
- return false;
-
- return true;
+ bool AtLeastAsSpecialized;
+ S.runWithSufficientStackSpace(Info.getLocation(), [&] {
+ AtLeastAsSpecialized = !FinishTemplateArgumentDeduction(
+ S, P2, /*IsPartialOrdering=*/true,
+ TemplateArgumentList(TemplateArgumentList::OnStack,
+ TST1->template_arguments()),
+ Deduced, Info);
+ });
+ return AtLeastAsSpecialized;
}
/// Returns the more specialized class template partial specialization
-// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -verify %s -DTEST=1
+// RUN: %clang_cc1 -verify %s -DTEST=2
+// RUN: %clang_cc1 -verify %s -DTEST=3
// REQUIRES: thread_support
// FIXME: Detection of, or recovery from, stack exhaustion does not work on
// expected-warning@* 0-1{{stack nearly exhausted}}
// expected-note@* 0+{{}}
+#if TEST == 1
+
template<int N> struct X : X<N-1> {};
template<> struct X<0> {};
X<1000> x;
template<int N> auto f(X<N>) -> f(X<N-1>());
int k = f(X<1000>());
+
+#elif TEST == 2
+
+namespace template_argument_recursion {
+ struct ostream;
+ template<typename T> T &&declval();
+
+ namespace mlir {
+ template<typename T, typename = decltype(declval<ostream&>() << declval<T&>())>
+ ostream &operator<<(ostream& os, const T& obj); // expected-error {{exceeded maximum depth}}
+ struct Value;
+ }
+
+ void printFunctionalType(ostream &os, mlir::Value &v) { os << v; }
+}
+
+#elif TEST == 3
+
+namespace template_parameter_type_recursion {
+ struct ostream;
+ template<typename T> T &&declval();
+ template<bool B, typename T> struct enable_if { using type = T; };
+
+ namespace mlir {
+ template<typename T, typename enable_if<declval<ostream&>() << declval<T&>(), void*>::type = nullptr>
+ ostream &operator<<(ostream& os, const T& obj); // expected-error {{exceeded maximum depth}}
+ struct Value;
+ }
+
+ void printFunctionalType(ostream &os, mlir::Value &v) { os << v; }
+}
+
+#else
+#error unknown test
+#endif