Commit b9be5ce8 authored by Mark de Wever's avatar Mark de Wever
Browse files

[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
parent 56b5eab1
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -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();
+2 −0
Original line number Diff line number Diff line
@@ -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<
+13 −0
Original line number Diff line number Diff line
@@ -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.
+54 −0
Original line number Diff line number Diff line
// 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
+9 −0
Original line number Diff line number Diff line
// 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
Loading