LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 19607 - Undiagnosed implementation limit of 127 nested function prototypes
Summary: Undiagnosed implementation limit of 127 nested function prototypes
Status: NEW
Alias: None
Product: clang
Classification: Unclassified
Component: Frontend (show other bugs)
Version: unspecified
Hardware: PC Windows NT
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
: 10750 31968 33162 (view as bug list)
Depends on:
Blocks:
 
Reported: 2014-04-29 12:38 PDT by Reid Kleckner
Modified: 2019-07-25 12:14 PDT (History)
9 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Reid Kleckner 2014-04-29 12:38:07 PDT
ParmVarDecl::setScopeInfo() is defined like so:

  void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex) {
    assert(!ParmVarDeclBits.IsObjCMethodParam);
    ParmVarDeclBits.ScopeDepthOrObjCQuals = scopeDepth;
    assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth
           && "truncation!");
    setParameterIndex(parameterIndex);
  }

It's possible to construct a program that trips this assertion by creating a deeply nested function prototype:

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)(void (*f)(void (*f)()))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));

Assertion failed: ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth && "truncation!", file ..\tools\clang\include\clang/AST/Decl.h, line 1276

I wanted one more bit in VarDeclBits.TSCSpec, so I considered taking it from here.  However, I discovered we don't enforce an upper bound on this quantity.
Comment 1 Reid Kleckner 2014-04-29 12:56:53 PDT
Relatedly, we cap out at 2**15 function parameters:

$ cat t.py
print 'void foo(',
for i in range(0, 2**15):
  print 'int a%d,' % i,
print 'int a%d);' % (i + 1)

$ python t.py | clang -c -x c -
Assertion failed: NumParams == params.size() && "function has too many parameters", file ..\tools\clang\lib\AST\Type.cpp, line 1604
Comment 2 Reid Kleckner 2017-05-25 10:38:02 PDT
*** Bug 33162 has been marked as a duplicate of this bug. ***
Comment 3 Mark de Wever 2019-06-29 11:09:34 PDT
I created a patch [1] for the original submission, will look at the second part later.

[1] https://reviews.llvm.org/D63975
Comment 4 Bruno Ricci 2019-06-30 15:15:43 PDT
Looking at FunctionTypeBitfields, It looks like the limits now for the number of function parameters is 2^16-1. It would be possible to bump this a little bit since there is some space left in FunctionTypeBitfields (but [implimits] only ask for 8 bits...)

I wonder if it would be worth spending some time going through the various limits and :

1. Add a check and an error message instead of just ignoring the situation (would help with fuzzing too).
2. Test these limits.
3. Document these limits like MSVC does (eg: https://docs.microsoft.com/en-us/cpp/cpp/compiler-limits?view=vs-2019).
Comment 5 Mark de Wever 2019-07-01 09:26:21 PDT
(In reply to Bruno Ricci from comment #4)
> I wonder if it would be worth spending some time going through the various
> limits and :
> 
> 1. Add a check and an error message instead of just ignoring the situation
> (would help with fuzzing too).

I think that would be better, also avoids confusing error messages like in bug 33162, where the error referred to an existing identifier.

> 2. Test these limits.

I assume that should be part of the patch introducing the error message.

> 3. Document these limits like MSVC does (eg:
> https://docs.microsoft.com/en-us/cpp/cpp/compiler-limits?view=vs-2019).

According to [implimits] "Every implementation shall document those limitations where known." so I think that should be done.
Comment 6 John McCall 2019-07-01 10:19:45 PDT
I would definitely support both documenting and enforcing these limits.  I don't think we should bump them unless we actually think they're currently unacceptable.
Comment 7 Mark de Wever 2019-07-18 11:50:56 PDT
*** Bug 31968 has been marked as a duplicate of this bug. ***
Comment 8 Mark de Wever 2019-07-25 12:14:59 PDT
*** Bug 10750 has been marked as a duplicate of this bug. ***