[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
This revision was automatically updated to reflect the committed changes. Closed by commit rGb9be5ce8f3e0: [Parser] Warn when ScopeDepthOrObjCQuals overflows (authored by Mordante). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ 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_blocks_overflow.cpp clang/test/Parser/nested_function_prototype_overflow.cpp clang/test/Parser/nested_lambda_overflow.cpp Index: clang/test/Parser/nested_lambda_overflow.cpp === --- /dev/null +++ clang/test/Parser/nested_lambda_overflow.cpp @@ -0,0 +1,55 @@ +// RUN: %clang %s -fsyntax-only -fbracket-depth=512 +// RUN: not %clang %s -fsyntax-only -fbracket-depth=512 -DFAIL 2>&1 | FileCheck %s + +template int foo(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 Index: clang/test/Parser/nested_function_prototype_overflow.cpp === --- /dev/null +++ clang/test/Parser/nested_function_prototype_overflow.cpp @@ -0,0 +1,9 @@ +// 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
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
Mordante added a comment. Thanks for the review. I don't have SVN access, can you commit these changes? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ https://reviews.llvm.org/D63975 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
rjmccall accepted this revision. rjmccall added a comment. This revision is now accepted and ready to land. Thanks, LGTM! CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ https://reviews.llvm.org/D63975 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
Mordante updated this revision to Diff 209703. Mordante added a comment. Addresses @rjmccall's remarks. Fixes the tests for the nested lambda's. As suspected the blocks also have the same nesting limit, thus added a test for them. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ 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_blocks_overflow.cpp clang/test/Parser/nested_function_prototype_overflow.cpp clang/test/Parser/nested_lambda_overflow.cpp Index: clang/test/Parser/nested_lambda_overflow.cpp === --- /dev/null +++ clang/test/Parser/nested_lambda_overflow.cpp @@ -0,0 +1,55 @@ +// RUN: %clang %s -fsyntax-only -fbracket-depth=512 +// RUN: not %clang %s -fsyntax-only -fbracket-depth=512 -DFAIL 2>&1 | FileCheck %s + +template int foo(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 Index: clang/test/Parser/nested_function_prototype_overflow.cpp === --- /dev/null +++ clang/test/Parser/nested_function_prototype_overflow.cpp @@ -0,0 +1,9 @@ +// 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
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
rjmccall added a comment. (Blocks don't actually allow default arguments, but apparently we still parse them, so we should test that path.) CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ https://reviews.llvm.org/D63975 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
rjmccall added a comment. Thanks. It's good to have a lambda test, but that one isn't actually testing the lambda path — the place the diagnostic will trigger is just the normal function-prototype path, just originally within a lambda. You can do something like this: template int foo(T &); void bar(int x = foo( [](int x = foo( [](int x = foo( [](int x = foo( ... It looks like you'll have to bump `-fbracket-level` to get a crash, but since that's configurable and this limit isn't, we should still be testing that. Also I think the same problem can happen with the "blocks" extension — could you test that, too? That would be something like (with `-fblocks`): void bar(int x = foo( ^(int x = foo( ^(int x = foo( ^(int x = foo( ... CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ https://reviews.llvm.org/D63975 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
Mordante updated this revision to Diff 209513. Mordante added a comment. Moved the test out of the loop as suggested by rjmccall. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ 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 clang/test/Parser/nested_lambda_overflow.cpp Index: clang/test/Parser/nested_lambda_overflow.cpp === --- /dev/null +++ clang/test/Parser/nested_lambda_overflow.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -fsyntax-only +// RUN: not %clang_cc1 %s -fsyntax-only -DFAIL 2>&1 | FileCheck %s + +auto 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 Index: clang/test/Parser/nested_function_prototype_overflow.cpp === --- /dev/null +++ clang/test/Parser/nested_function_prototype_overflow.cpp @@ -0,0 +1,9 @@ +// 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 Index: clang/lib/Parse/ParseDecl.cpp === --- clang/lib/Parse/ParseDecl.cpp +++ clang/lib/Parse/ParseDecl.cpp @@ -6510,6 +6510,19 @@ ParsedAttributes , SmallVectorImpl , SourceLocation ) { + + // 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
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
Mordante marked an inline comment as done. Mordante added inline comments. Comment at: clang/lib/Parse/ParseDecl.cpp:6587 +return; + } + rjmccall wrote: > Mordante wrote: > > rjmccall wrote: > > > Comment indentation. > > > > > > Should we do this when starting to parse a function prototype instead of > > > when parsing a parameter? > > Thanks I noticed I forgot to change the tabs to spaces. > > > > I looked at your suggestion to move the code, but I think this is the > > proper place. Now it also validates whether lambdas exceed the limit, else > > we need to check at two places. > > I'll also add a unit test to test for the lambda. > I don't understand. I'm just saying to put the check at the top of the > function instead of inside the loop. I now understand what you mean. I'll upload a new patch. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ https://reviews.llvm.org/D63975 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
rjmccall added inline comments. Comment at: clang/lib/Parse/ParseDecl.cpp:6587 +return; + } + Mordante wrote: > rjmccall wrote: > > Comment indentation. > > > > Should we do this when starting to parse a function prototype instead of > > when parsing a parameter? > Thanks I noticed I forgot to change the tabs to spaces. > > I looked at your suggestion to move the code, but I think this is the proper > place. Now it also validates whether lambdas exceed the limit, else we need > to check at two places. > I'll also add a unit test to test for the lambda. I don't understand. I'm just saying to put the check at the top of the function instead of inside the loop. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ https://reviews.llvm.org/D63975 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
Mordante updated this revision to Diff 209348. Mordante added a comment. tab -> space adds an extra unit test for lambdas fixes an off by one error found while testing the lambdas CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ 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 clang/test/Parser/nested_lambda_overflow.cpp Index: clang/test/Parser/nested_lambda_overflow.cpp === --- /dev/null +++ clang/test/Parser/nested_lambda_overflow.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -fsyntax-only +// RUN: not %clang_cc1 %s -fsyntax-only -DFAIL 2>&1 | FileCheck %s + +auto 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 Index: clang/test/Parser/nested_function_prototype_overflow.cpp === --- /dev/null +++ clang/test/Parser/nested_function_prototype_overflow.cpp @@ -0,0 +1,9 @@ +// 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 Index: clang/lib/Parse/ParseDecl.cpp === --- clang/lib/Parse/ParseDecl.cpp +++ clang/lib/Parse/ParseDecl.cpp @@ -6576,6 +6576,18 @@ Actions.containsUnexpandedParameterPacks(ParmDeclarator)) DiagnoseMisplacedEllipsisInDeclarator(ConsumeToken(), ParmDeclarator); + // 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(DSStart,
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
Mordante marked an inline comment as done. Mordante added inline comments. Comment at: clang/lib/Parse/ParseDecl.cpp:6587 +return; + } + rjmccall wrote: > Comment indentation. > > Should we do this when starting to parse a function prototype instead of when > parsing a parameter? Thanks I noticed I forgot to change the tabs to spaces. I looked at your suggestion to move the code, but I think this is the proper place. Now it also validates whether lambdas exceed the limit, else we need to check at two places. I'll also add a unit test to test for the lambda. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ https://reviews.llvm.org/D63975 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
rjmccall added inline comments. Comment at: clang/lib/Parse/ParseDecl.cpp:6587 +return; + } + Comment indentation. Should we do this when starting to parse a function prototype instead of when parsing a parameter? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63975/new/ https://reviews.llvm.org/D63975 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D63975: Warn when ScopeDepthOrObjCQuals overflows
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