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