summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/Decl.h8
-rw-r--r--clang/include/clang/Basic/DiagnosticParseKinds.td2
-rw-r--r--clang/lib/Parse/ParseDecl.cpp13
-rw-r--r--clang/test/Parser/nested_blocks_overflow.cpp54
-rw-r--r--clang/test/Parser/nested_function_prototype_overflow.cpp9
-rw-r--r--clang/test/Parser/nested_lambda_overflow.cpp55
6 files changed, 140 insertions, 1 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 16094c0988f..31adfc5c368 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -921,11 +921,13 @@ protected:
/// Whether this parameter is an ObjC method parameter or not.
unsigned IsObjCMethodParam : 1;
+ enum { NumScopeDepthOrObjCQualsBits = 7 };
+
/// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
/// Otherwise, the number of function parameter scopes enclosing
/// the function parameter scope in which this parameter was
/// declared.
- unsigned ScopeDepthOrObjCQuals : 7;
+ unsigned ScopeDepthOrObjCQuals : NumScopeDepthOrObjCQualsBits;
/// The number of parameters preceding this parameter in the
/// function parameter scope in which it was declared.
@@ -1650,6 +1652,10 @@ public:
return ParmVarDeclBits.ScopeDepthOrObjCQuals;
}
+ static constexpr unsigned getMaxFunctionScopeDepth() {
+ return (1u << ParmVarDeclBitfields::NumScopeDepthOrObjCQualsBits) - 1;
+ }
+
/// Returns the index of this parameter in its prototype or method scope.
unsigned getFunctionScopeIndex() const {
return getParameterIndex();
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 7c9f4da778a..dc9f677ec5b 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -325,6 +325,8 @@ def err_for_range_expected_decl : Error<
def err_argument_required_after_attribute : Error<
"argument required after attribute">;
def err_missing_param : Error<"expected parameter declarator">;
+def err_function_scope_depth_exceeded : Error<
+ "function scope depth exceeded maximum of %0">, DefaultFatal;
def err_missing_comma_before_ellipsis : Error<
"C requires a comma prior to the ellipsis in a variadic function type">;
def err_unexpected_typedef_ident : Error<
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index c41eb74a9cf..e5c17a3131a 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -6566,6 +6566,19 @@ void Parser::ParseParameterDeclarationClause(
ParsedAttributes &FirstArgAttrs,
SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
SourceLocation &EllipsisLoc) {
+
+ // Avoid exceeding the maximum function scope depth.
+ // See https://bugs.llvm.org/show_bug.cgi?id=19607
+ // Note Sema::ActOnParamDeclarator calls ParmVarDecl::setScopeInfo with
+ // getFunctionPrototypeDepth() - 1.
+ if (getCurScope()->getFunctionPrototypeDepth() - 1 >
+ ParmVarDecl::getMaxFunctionScopeDepth()) {
+ Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
+ << ParmVarDecl::getMaxFunctionScopeDepth();
+ cutOffParsing();
+ return;
+ }
+
do {
// FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
// before deciding this was a parameter-declaration-clause.
diff --git a/clang/test/Parser/nested_blocks_overflow.cpp b/clang/test/Parser/nested_blocks_overflow.cpp
new file mode 100644
index 00000000000..e8366a8d56a
--- /dev/null
+++ b/clang/test/Parser/nested_blocks_overflow.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang %s -fsyntax-only -fblocks -fbracket-depth=512
+// RUN: not %clang %s -fsyntax-only -fblocks -fbracket-depth=512 -DFAIL 2>&1 | FileCheck %s
+
+template <class T> int foo(T &&t);
+
+void bar(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+
+^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(^(int x = foo(
+
+#ifdef FAIL
+^(int x = foo(
+#endif
+
+^(int x = foo(1)){}
+
+#ifdef FAIL
+)){}
+#endif
+
+)){})){})){})){})){})){}
+
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+));
+
+// CHECK: fatal error: function scope depth exceeded maximum of 127
diff --git a/clang/test/Parser/nested_function_prototype_overflow.cpp b/clang/test/Parser/nested_function_prototype_overflow.cpp
new file mode 100644
index 00000000000..29b382d8c3b
--- /dev/null
+++ b/clang/test/Parser/nested_function_prototype_overflow.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only
+// RUN: not %clang_cc1 %s -fsyntax-only -DFAIL 2>&1 | FileCheck %s
+
+void foo(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(void (*f)(
+#ifdef FAIL
+void (*f)()
+#endif
+)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
+// CHECK: fatal error: function scope depth exceeded maximum of 127
diff --git a/clang/test/Parser/nested_lambda_overflow.cpp b/clang/test/Parser/nested_lambda_overflow.cpp
new file mode 100644
index 00000000000..afaa9dca635
--- /dev/null
+++ b/clang/test/Parser/nested_lambda_overflow.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang %s -fsyntax-only -fbracket-depth=512
+// RUN: not %clang %s -fsyntax-only -fbracket-depth=512 -DFAIL 2>&1 | FileCheck %s
+
+template <class T> int foo(T &&t);
+
+void bar(int x = foo(
+
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+
+[](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo([](int x = foo(
+
+#ifdef FAIL
+[](int x = foo(
+#endif
+
+[](int x = foo(1)){}
+
+#ifdef FAIL
+)){}
+#endif
+
+)){})){})){})){})){})){}
+
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+)){})){})){})){})){})){})){})){}
+));
+
+// CHECK: fatal error: function scope depth exceeded maximum of 127
OpenPOWER on IntegriCloud