[clang] b9be5ce - [Parser] Warn when ScopeDepthOrObjCQuals overflows

Mark de Wever via cfe-commits cfe-commits at lists.llvm.org
Sat Nov 9 06:33:26 PST 2019


Author: Mark de Wever
Date: 2019-11-09T15:33:01+01:00
New Revision: b9be5ce8f3e0e697a61ad16e2c669de6ea8f8739

URL: https://github.com/llvm/llvm-project/commit/b9be5ce8f3e0e697a61ad16e2c669de6ea8f8739
DIFF: https://github.com/llvm/llvm-project/commit/b9be5ce8f3e0e697a61ad16e2c669de6ea8f8739.diff

LOG: [Parser] Warn when ScopeDepthOrObjCQuals overflows

Before when the overflow occured an assertion was triggered. Now check
whether the maximum has been reached and warn properly.

This patch fixes the original submission of PR19607.

Differential Revision: https://reviews.llvm.org/D63975

Added: 
    clang/test/Parser/nested_blocks_overflow.cpp
    clang/test/Parser/nested_function_prototype_overflow.cpp
    clang/test/Parser/nested_lambda_overflow.cpp

Modified: 
    clang/include/clang/AST/Decl.h
    clang/include/clang/Basic/DiagnosticParseKinds.td
    clang/lib/Parse/ParseDecl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 16094c0988fa..31adfc5c368a 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -921,11 +921,13 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
     /// 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 @@ class ParmVarDecl : public VarDecl {
     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 7c9f4da778a6..dc9f677ec5b6 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 c41eb74a9cf3..e5c17a3131ab 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 000000000000..e8366a8d56a2
--- /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 000000000000..29b382d8c3b2
--- /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 000000000000..afaa9dca635c
--- /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


        


More information about the cfe-commits mailing list