https://github.com/daniel-petrovic updated https://github.com/llvm/llvm-project/pull/224393
>From 69c059ef8c75952e0c3aa6895c0917d0b78a046d Mon Sep 17 00:00:00 2001 From: Daniel Petrovic <[email protected]> Date: Thu, 17 Sep 2026 21:44:57 +0200 Subject: [PATCH 1/2] [clang] Prevent stack overflow on deeply nested template arguments Limit template argument nesting and diagnose before exhausting the parser stack. Fixes #224114 --- clang/docs/ReleaseNotes.md | 4 ++ clang/docs/UsersManual.md | 5 +++ .../clang/Basic/DiagnosticParseKinds.td | 6 +++ clang/include/clang/Parse/Parser.h | 8 ++++ clang/lib/Parse/ParseTemplate.cpp | 39 +++++++++++++++++++ clang/test/Parser/template-argument-depth.cpp | 27 +++++++++++++ 6 files changed, 89 insertions(+) create mode 100644 clang/test/Parser/template-argument-depth.cpp diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index f4a34a37aff52..09fbd65fbdab3 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -608,6 +608,10 @@ features cannot lower the translation-unit ABI level; - Fixed a crash when a using-declaration naming an unresolvable member of a dependent base was shadowed by an invalid using-declaration. (#GH209427) +- Fixed a stack overflow (segfault) when parsing deeply nested template + arguments such as ``S<S<S<...>>>``. The parser now rejects nesting deeper + than ``-ftemplate-depth`` with a diagnostic. (#GH224114) + - Fixed a CTAD bug when combining with concepts. (#GH124715) - Fixed a regression where an internal-linkage function (e.g. a `static` or diff --git a/clang/docs/UsersManual.md b/clang/docs/UsersManual.md index 3bec20612c048..4b21d1137c83b 100644 --- a/clang/docs/UsersManual.md +++ b/clang/docs/UsersManual.md @@ -4446,6 +4446,11 @@ The default is 1048576, and the limit can be disabled with `-fconstexpr-steps=0` Sets the limit for recursively nested template instantiations to N. The default is 1024. + +This option also limits how deeply template arguments may be nested in the +source (e.g. the number of levels in ``S<S<S<...>>>``). Nesting deeper than +the limit is rejected with a diagnostic instead of overflowing the parser's +stack. ::: :::{option} -foperator-arrow-depth=N diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 594d158d25e92..bc5c58363a36a 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -675,6 +675,12 @@ def err_bracket_depth_exceeded : Error< "bracket nesting level exceeded maximum of %0">, DefaultFatal; def note_bracket_depth : Note< "use -fbracket-depth=N to increase maximum nesting level">; +def err_template_argument_depth_exceeded : Error< + "template argument nesting depth exceeded maximum of %0">, DefaultFatal; +def err_template_argument_stack_exhausted : Error< + "stack nearly exhausted while parsing nested template arguments">, DefaultFatal; +def note_template_argument_depth : Note< + "use -ftemplate-depth=N to increase maximum template argument nesting depth">; def err_misplaced_ellipsis_in_declaration : Error< "'...' must %select{immediately precede declared identifier|" "be innermost component of anonymous pack declaration}0">; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index e9bab81b095fd..f4f05b56e5d82 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -7930,6 +7930,14 @@ class Parser : public CodeCompletionHandler { /// The "depth" of the template parameters currently being parsed. unsigned TemplateParameterDepth; + /// The current nesting depth of template argument lists being parsed. Each + /// level of nested template-ids (e.g. `A<B<C<...>>>`) recurses through the + /// parser's type/template disambiguation machinery, so without a limit the + /// parser's stack would overflow on deeply nested template arguments. This + /// is used to enforce a maximum nesting depth analogous to -ftemplate-depth + /// (see https://github.com/llvm/llvm-project/issues/224114). + unsigned TemplateArgumentDepth = 0; + /// RAII class that manages the template parameter depth. class TemplateParameterDepthRAII { unsigned &Depth; diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 1e5aa55338309..5d0949128eb63 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -14,6 +14,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" #include "clang/Basic/DiagnosticParse.h" +#include "clang/Basic/Stack.h" #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/DeclSpec.h" @@ -22,6 +23,23 @@ #include "clang/Sema/Scope.h" using namespace clang; +namespace { +/// RAII class that manages the template argument nesting depth. Recursing into +/// a nested template-id (e.g. the inner `S<...>` of `S<S<...>>`) dips through +/// the parser's type/template disambiguation machinery, so deeply nested +/// template arguments could overflow the parser's stack. The depth is tracked +/// so that `Parser::ParseTemplateArgumentList` can enforce a maximum. +class TemplateArgumentDepthRAII { + unsigned &Depth; + +public: + explicit TemplateArgumentDepthRAII(unsigned &Depth) : Depth(Depth) { + ++Depth; + } + ~TemplateArgumentDepthRAII() { --Depth; } +}; +} // namespace + unsigned Parser::ReenterTemplateScopes(MultiParseScope &S, Decl *D) { return Actions.ActOnReenterTemplateScope(D, [&] { S.Enter(Scope::TemplateParamScope); @@ -1384,6 +1402,27 @@ bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs, ColonProtectionRAIIObject ColonProtection(*this, false); + // Nested template-ids (e.g. `S<S<S<...>>>`) recurse through the parser's + // type/template disambiguation machinery, which is deeply recursive. Bound + // the nesting depth to avoid overflowing the parser's stack (see + // https://github.com/llvm/llvm-project/issues/224114). The bounds follow + // -ftemplate-depth when available, and additionally bail out if we're + // genuinely low on stack space (which keeps even huge -ftemplate-depth + // overrides from overflowing the stack). + TemplateArgumentDepthRAII Depth(TemplateArgumentDepth); + bool DepthLimitExceeded = + TemplateArgumentDepth > getLangOpts().InstantiationDepth; + if (DepthLimitExceeded || isStackNearlyExhausted()) { + if (DepthLimitExceeded) { + Diag(OpenLoc, diag::err_template_argument_depth_exceeded) + << getLangOpts().InstantiationDepth; + Diag(OpenLoc, diag::note_template_argument_depth); + } else { + Diag(OpenLoc, diag::err_template_argument_stack_exhausted); + } + return true; + } + auto RunSignatureHelp = [&] { if (!Template) return QualType(); diff --git a/clang/test/Parser/template-argument-depth.cpp b/clang/test/Parser/template-argument-depth.cpp new file mode 100644 index 0000000000000..a8eabf15dcde6 --- /dev/null +++ b/clang/test/Parser/template-argument-depth.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++20 -ftemplate-depth=64 -DRAISED %s +// RUN: not %clang_cc1 -fsyntax-only -std=c++20 -ftemplate-depth=16 -DFAIL %s 2>&1 | FileCheck %s +// +// Parsing deeply nested template argument lists such as S<S<S<...>>> used to +// overflow the parser's stack and crash (see +// https://github.com/llvm/llvm-project/issues/224114). The parser now enforces +// a maximum template argument nesting depth controlled by -ftemplate-depth. +// +// CHECK: fatal error: template argument nesting depth exceeded maximum of 16 +// CHECK-NOT: stack nearly exhausted +// expected-no-diagnostics + +template <typename T> struct S {}; + +// This nesting is well within the default -ftemplate-depth limit. +using NoError = S<S<S<S<S<int>>>>>; + +#ifdef FAIL +// Nesting deeper than -ftemplate-depth=16 must be rejected, not crash. +using Trigger = S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<int>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; +#endif + +#ifdef RAISED +// Raising -ftemplate-depth increases the parser's allowance. +using Raised = S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<int>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; +#endif >From da3cb487f129b7c91ea04ed0f48fa27b9f754959 Mon Sep 17 00:00:00 2001 From: Daniel Petrovic <[email protected]> Date: Fri, 18 Sep 2026 13:56:43 +0200 Subject: [PATCH 2/2] [clang] Fix stack exhaustion if parsing deeply nested template arguments Stack guard is missing on the path if parsing deeply nested template args. Run template argument list parser under stack guard. --- clang/docs/ReleaseNotes.md | 7 +- clang/docs/UsersManual.md | 5 -- .../clang/Basic/DiagnosticParseKinds.td | 6 -- clang/include/clang/Parse/Parser.h | 8 -- clang/lib/Parse/ParseTemplate.cpp | 84 ++++++------------- clang/test/Parser/template-argument-depth.cpp | 39 +++++---- 6 files changed, 50 insertions(+), 99 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 09fbd65fbdab3..d70dccd6e6e27 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -608,9 +608,10 @@ features cannot lower the translation-unit ABI level; - Fixed a crash when a using-declaration naming an unresolvable member of a dependent base was shadowed by an invalid using-declaration. (#GH209427) -- Fixed a stack overflow (segfault) when parsing deeply nested template - arguments such as ``S<S<S<...>>>``. The parser now rejects nesting deeper - than ``-ftemplate-depth`` with a diagnostic. (#GH224114) +- Fixed a stack overflow when parsing deeply nested template arguments such + as ``S<S<S<...>>>``. Parsing now goes through the existing stack guard, which + continues on a fresh stack instead of crashing when the parser's stack is + nearly exhausted. (#GH224114) - Fixed a CTAD bug when combining with concepts. (#GH124715) diff --git a/clang/docs/UsersManual.md b/clang/docs/UsersManual.md index 4b21d1137c83b..3bec20612c048 100644 --- a/clang/docs/UsersManual.md +++ b/clang/docs/UsersManual.md @@ -4446,11 +4446,6 @@ The default is 1048576, and the limit can be disabled with `-fconstexpr-steps=0` Sets the limit for recursively nested template instantiations to N. The default is 1024. - -This option also limits how deeply template arguments may be nested in the -source (e.g. the number of levels in ``S<S<S<...>>>``). Nesting deeper than -the limit is rejected with a diagnostic instead of overflowing the parser's -stack. ::: :::{option} -foperator-arrow-depth=N diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index bc5c58363a36a..594d158d25e92 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -675,12 +675,6 @@ def err_bracket_depth_exceeded : Error< "bracket nesting level exceeded maximum of %0">, DefaultFatal; def note_bracket_depth : Note< "use -fbracket-depth=N to increase maximum nesting level">; -def err_template_argument_depth_exceeded : Error< - "template argument nesting depth exceeded maximum of %0">, DefaultFatal; -def err_template_argument_stack_exhausted : Error< - "stack nearly exhausted while parsing nested template arguments">, DefaultFatal; -def note_template_argument_depth : Note< - "use -ftemplate-depth=N to increase maximum template argument nesting depth">; def err_misplaced_ellipsis_in_declaration : Error< "'...' must %select{immediately precede declared identifier|" "be innermost component of anonymous pack declaration}0">; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index f4f05b56e5d82..e9bab81b095fd 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -7930,14 +7930,6 @@ class Parser : public CodeCompletionHandler { /// The "depth" of the template parameters currently being parsed. unsigned TemplateParameterDepth; - /// The current nesting depth of template argument lists being parsed. Each - /// level of nested template-ids (e.g. `A<B<C<...>>>`) recurses through the - /// parser's type/template disambiguation machinery, so without a limit the - /// parser's stack would overflow on deeply nested template arguments. This - /// is used to enforce a maximum nesting depth analogous to -ftemplate-depth - /// (see https://github.com/llvm/llvm-project/issues/224114). - unsigned TemplateArgumentDepth = 0; - /// RAII class that manages the template parameter depth. class TemplateParameterDepthRAII { unsigned &Depth; diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 5d0949128eb63..53fd4416c6e46 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -14,7 +14,6 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" #include "clang/Basic/DiagnosticParse.h" -#include "clang/Basic/Stack.h" #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/DeclSpec.h" @@ -23,23 +22,6 @@ #include "clang/Sema/Scope.h" using namespace clang; -namespace { -/// RAII class that manages the template argument nesting depth. Recursing into -/// a nested template-id (e.g. the inner `S<...>` of `S<S<...>>`) dips through -/// the parser's type/template disambiguation machinery, so deeply nested -/// template arguments could overflow the parser's stack. The depth is tracked -/// so that `Parser::ParseTemplateArgumentList` can enforce a maximum. -class TemplateArgumentDepthRAII { - unsigned &Depth; - -public: - explicit TemplateArgumentDepthRAII(unsigned &Depth) : Depth(Depth) { - ++Depth; - } - ~TemplateArgumentDepthRAII() { --Depth; } -}; -} // namespace - unsigned Parser::ReenterTemplateScopes(MultiParseScope &S, Decl *D) { return Actions.ActOnReenterTemplateScope(D, [&] { S.Enter(Scope::TemplateParamScope); @@ -1402,27 +1384,6 @@ bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs, ColonProtectionRAIIObject ColonProtection(*this, false); - // Nested template-ids (e.g. `S<S<S<...>>>`) recurse through the parser's - // type/template disambiguation machinery, which is deeply recursive. Bound - // the nesting depth to avoid overflowing the parser's stack (see - // https://github.com/llvm/llvm-project/issues/224114). The bounds follow - // -ftemplate-depth when available, and additionally bail out if we're - // genuinely low on stack space (which keeps even huge -ftemplate-depth - // overrides from overflowing the stack). - TemplateArgumentDepthRAII Depth(TemplateArgumentDepth); - bool DepthLimitExceeded = - TemplateArgumentDepth > getLangOpts().InstantiationDepth; - if (DepthLimitExceeded || isStackNearlyExhausted()) { - if (DepthLimitExceeded) { - Diag(OpenLoc, diag::err_template_argument_depth_exceeded) - << getLangOpts().InstantiationDepth; - Diag(OpenLoc, diag::note_template_argument_depth); - } else { - Diag(OpenLoc, diag::err_template_argument_stack_exhausted); - } - return true; - } - auto RunSignatureHelp = [&] { if (!Template) return QualType(); @@ -1431,27 +1392,36 @@ bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs, Template, TemplateArgs, OpenLoc); }; - do { - PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp); - ParsedTemplateArgument Arg = ParseTemplateArgument(); - SourceLocation EllipsisLoc; - if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) - Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc); - - if (Arg.isInvalid()) { - if (PP.isCodeCompletionReached() && !CalledSignatureHelp) - RunSignatureHelp(); - return true; - } + // Nested template-ids (e.g. `S<S<S<...>>>`) recurse through the parser's + // type/template disambiguation machinery, which is deeply recursive. Run the + // parse with the stack guard so that a deeply nested argument list (see + // https://github.com/llvm/llvm-project/issues/224114) continues on a fresh + // stack instead of overflowing the parser's stack. + bool Invalid = false; + StackHandler.runWithSufficientStackSpace(OpenLoc, [&, this]() { + do { + PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp); + ParsedTemplateArgument Arg = ParseTemplateArgument(); + SourceLocation EllipsisLoc; + if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) + Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc); + + if (Arg.isInvalid()) { + if (PP.isCodeCompletionReached() && !CalledSignatureHelp) + RunSignatureHelp(); + Invalid = true; + return; + } - // Save this template argument. - TemplateArgs.push_back(Arg); + // Save this template argument. + TemplateArgs.push_back(Arg); - // If the next token is a comma, consume it and keep reading - // arguments. - } while (TryConsumeToken(tok::comma)); + // If the next token is a comma, consume it and keep reading + // arguments. + } while (TryConsumeToken(tok::comma)); + }); - return false; + return Invalid; } Parser::DeclGroupPtrTy Parser::ParseExplicitInstantiation( diff --git a/clang/test/Parser/template-argument-depth.cpp b/clang/test/Parser/template-argument-depth.cpp index a8eabf15dcde6..e60f1aa6d22b3 100644 --- a/clang/test/Parser/template-argument-depth.cpp +++ b/clang/test/Parser/template-argument-depth.cpp @@ -1,27 +1,26 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s -// RUN: %clang_cc1 -fsyntax-only -std=c++20 -ftemplate-depth=64 -DRAISED %s -// RUN: not %clang_cc1 -fsyntax-only -std=c++20 -ftemplate-depth=16 -DFAIL %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -fsyntax-only -verify %s // // Parsing deeply nested template argument lists such as S<S<S<...>>> used to // overflow the parser's stack and crash (see -// https://github.com/llvm/llvm-project/issues/224114). The parser now enforces -// a maximum template argument nesting depth controlled by -ftemplate-depth. +// https://github.com/llvm/llvm-project/issues/224114). The parser now runs +// this recursion through the existing stack guard, which continues parsing on +// a fresh stack when the parser's stack is nearly exhausted instead of +// crashing. // -// CHECK: fatal error: template argument nesting depth exceeded maximum of 16 -// CHECK-NOT: stack nearly exhausted -// expected-no-diagnostics +// REQUIRES: thread_support +// +// FIXME: Detection of, or recovery from, stack exhaustion does not work on +// NetBSD at the moment. Since this is a best-effort mitigation for exceeding +// implementation limits, just disable the test. +// UNSUPPORTED: system-netbsd +// +// asan has its own stack-overflow check. +// UNSUPPORTED: asan +// +// expected-warning@* 0-2{{stack nearly exhausted}} template <typename T> struct S {}; -// This nesting is well within the default -ftemplate-depth limit. -using NoError = S<S<S<S<S<int>>>>>; - -#ifdef FAIL -// Nesting deeper than -ftemplate-depth=16 must be rejected, not crash. -using Trigger = S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<int>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; -#endif - -#ifdef RAISED -// Raising -ftemplate-depth increases the parser's allowance. -using Raised = S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<int>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; -#endif +// This nesting (2000 levels) is deep enough to overflow the parser's stack +// without the stack guard on a typical 8 MiB stack. +using Trigger = S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<int>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
