Mordante created this revision.
Mordante added reviewers: rsmith, rjmccall.
Mordante added a project: clang.

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

This patch fixes bug 33162 which is marked as 'duplicate' of bug 19607. The 
original part of bug 19607 is fixed by D63975 <https://reviews.llvm.org/D63975>.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D64811

Files:
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/test/Parser/function_parameter_overflow.cpp
  clang/test/Parser/lambda_function_parameter_overflow.cpp
  clang/test/Parser/parameter_overflow.h

Index: clang/test/Parser/parameter_overflow.h
===================================================================
--- /dev/null
+++ clang/test/Parser/parameter_overflow.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#define I10 int, int, int, int, int, int, int, int, int, int
+#define I50 I10, I10, I10, I10, I10
+#define I500 I50, I50, I50, I50, I50, I50, I50, I50, I50, I50
+#define I5000 I500, I500, I500, I500, I500, I500, I500, I500, I500, I500
+#define I60000 I5000, I5000, I5000, I5000, I5000, I5000, I5000, I5000, I5000, I5000, I5000, I5000
+
+#define  I65535 I60000, I5000, I500, I10, I10, I10, int, int, int, int, int
Index: clang/test/Parser/lambda_function_parameter_overflow.cpp
===================================================================
--- /dev/null
+++ clang/test/Parser/lambda_function_parameter_overflow.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only
+// RUN: not %clang_cc1 %s -fsyntax-only -DFAIL 2>&1 | FileCheck %s
+
+#include "parameter_overflow.h"
+
+auto foo = [](I65535
+#ifdef FAIL
+, int
+#endif
+){};
+// CHECK: fatal error: number of function parameters exceeded maximum of 65535
Index: clang/test/Parser/function_parameter_overflow.cpp
===================================================================
--- /dev/null
+++ clang/test/Parser/function_parameter_overflow.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only
+// RUN: not %clang_cc1 %s -fsyntax-only -DFAIL 2>&1 | FileCheck %s
+
+#include "parameter_overflow.h"
+
+void foo(I65535
+#ifdef FAIL
+, int
+#endif
+);
+// CHECK: fatal error: number of function parameters exceeded maximum of 65535
Index: clang/lib/Parse/ParseExprCXX.cpp
===================================================================
--- clang/lib/Parse/ParseExprCXX.cpp
+++ clang/lib/Parse/ParseExprCXX.cpp
@@ -1265,6 +1265,14 @@
 
       ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc);
 
+      // If the parameters could not be parsed stop processing. Proceeding is
+      // not an issue when the maximum scope depth is exceeded. But when the
+      // maximum number of parameters is exceeded the processing will still hit
+      // the assertion in FunctionProtoType's constructor.
+      // See https://bugs.llvm.org/show_bug.cgi?id=19607
+      if (Tok.is(tok::eof))
+        return ExprError();
+
       // For a generic lambda, each 'auto' within the parameter declaration
       // clause creates a template type parameter, so increment the depth.
       // If we've parsed any explicit template parameters, then the depth will
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6668,6 +6668,15 @@
 
     // If the next token is a comma, consume it and keep reading arguments.
   } while (TryConsumeToken(tok::comma));
+
+  // Avoid exceeding the maximum function parameters
+  // See https://bugs.llvm.org/show_bug.cgi?id=19607
+  if (ParamInfo.size() > Type::getMaxNumParams()) {
+    Diag(ParamInfo[Type::getMaxNumParams() - 1].IdentLoc,
+         diag::err_number_of_function_parameters_exceeded)
+        << Type::getMaxNumParams();
+    cutOffParsing();
+  }
 }
 
 /// [C90]   direct-declarator '[' constant-expression[opt] ']'
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_number_of_function_parameters_exceeded : Error<
+  "number of function parameters 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/Type.h
===================================================================
--- clang/include/clang/AST/Type.h
+++ clang/include/clang/AST/Type.h
@@ -1520,6 +1520,8 @@
     unsigned Kind : 8;
   };
 
+  enum { NumParamsBits = 16 };
+
   /// FunctionTypeBitfields store various bits belonging to FunctionProtoType.
   /// Only common bits are stored here. Additional uncommon bits are stored
   /// in a trailing object after FunctionProtoType.
@@ -1552,7 +1554,7 @@
     /// According to [implimits] 8 bits should be enough here but this is
     /// somewhat easy to exceed with metaprogramming and so we would like to
     /// keep NumParams as wide as reasonably possible.
-    unsigned NumParams : 16;
+    unsigned NumParams : NumParamsBits;
 
     /// The type of exception specification this function has.
     unsigned ExceptionSpecType : 4;
@@ -2360,6 +2362,11 @@
   ///        this type can have nullability because it is dependent.
   bool canHaveNullability(bool ResultIfUnknown = true) const;
 
+  /// @returns The maximum number of parameters for a function.
+  static constexpr unsigned getMaxNumParams() {
+    return (1u << NumParamsBits) - 1;
+  }
+
   /// Retrieve the set of substitutions required when accessing a member
   /// of the Objective-C receiver type that is declared in the given context.
   ///
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to