[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows

Mark de Wever via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sat Jun 29 11:09:32 PDT 2019


Mordante created this revision.
Mordante added a reviewer: rsmith.
Mordante added a project: clang.
Herald added a subscriber: cfe-commits.

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

This patch fixes the original submission of bug 19607. The part mentioned
in its 'duplicate' bug 33162 has not been fixed. I want to look at that
after this patch has been accepted.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D63975

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/test/Parser/nested_function_prototype_overflow.cpp


Index: clang/test/Parser/nested_function_prototype_overflow.cpp
===================================================================
--- /dev/null
+++ clang/test/Parser/nested_function_prototype_overflow.cpp
@@ -0,0 +1,10 @@
+// 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)(
+#ifdef FAIL
+void (*f)()
+#endif
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
+
+// CHECK: fatal error: function scope depth exceeded maximum of 127
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6576,6 +6576,16 @@
           Actions.containsUnexpandedParameterPacks(ParmDeclarator))
         DiagnoseMisplacedEllipsisInDeclarator(ConsumeToken(), ParmDeclarator);
 
+	  // Avoid exceeding the maximum function scope depth.
+	  // https://bugs.llvm.org/show_bug.cgi?id=19607
+      if (getCurScope()->getFunctionPrototypeDepth() - 1 >=
+          ParmVarDecl::getMaxFunctionScopeDepth()) {
+        Diag(DSStart, diag::err_function_scope_depth_exceeded)
+            << ParmVarDecl::getMaxFunctionScopeDepth();
+        cutOffParsing();
+        return;
+      }
+
       // Inform the actions module about the parameter declarator, so it gets
       // added to the current scope.
       Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator);
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -326,6 +326,8 @@
 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<
Index: clang/include/clang/AST/Decl.h
===================================================================
--- clang/include/clang/AST/Decl.h
+++ clang/include/clang/AST/Decl.h
@@ -905,11 +905,13 @@
     /// 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.
@@ -1613,6 +1615,10 @@
     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();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63975.207204.patch
Type: text/x-patch
Size: 4661 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190629/dfeddbb2/attachment-0001.bin>


More information about the cfe-commits mailing list