Introduce a new diagnostic, and respect the bracket-depth (256) by default.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
5095 | I think this should be NoSFINAE, similar to err_template_recursion_depth_exceeded. Maybe DefaultFatal too? | |
5096 | The diagnostic test could be clearer: what's a "fold expression expansion level"? what about "instantiating fold expression with %0 arguments exceeds expression nesting limit of %1"? | |
clang/lib/Sema/TreeTransform.h | ||
13196 | The brackets here are not obvious. Also we're not actually tracking bracket *depth*! So this definitely needs a comment. Something like: // Formally a fold expression expands to nested parenthesized expressions. // Enforce this limit to avoid creating trees so deep we can't safely traverse them | |
13197 | you might also want to emit note_bracket_depth (I don't think you need to clone it if we get the wording right) | |
clang/test/SemaCXX/fold_expr_expansion_limit.cpp | ||
9 | this diagnostic is bogus :-( |
address review comments.
clang/lib/Sema/TreeTransform.h | ||
---|---|---|
13197 | note_bracket_depth is from parse diagnostic, introducing it in Sema feels like a slight layer violation, but the compile should be fine, because all diagnostic headers in the support library. | |
clang/test/SemaCXX/fold_expr_expansion_limit.cpp | ||
9 | oh, yeah, if a fatal error is emitted, all subsequent diagnostics will be silenced. |
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
5096 | arguements -> arguments |
Why did we select the 'bracket-depth' for this? The documentation on that doesn't seem to be anything close to what this should be based on:
Sets the limit for nested parentheses, brackets, and braces to N in blocks, declarators, expressions, and struct or union declarations.
The 256 default limit is REALLY small for a fold expression, particularly since the instantiation depth limit is 1024 by default. I think this patch needs to be changed to use the InstantiationDepth instead. @rjmccall, thoughts?
Even that limit (1024) seems like it is perhaps a little conservative. Apparently, this comes up in Boost Numerics, where they use a pack of size 1089 at one point that they use a '+' fold expression that this causes us to no longer be able to build.
Based on a discussion with @rsmith - the formal definition of pack expansion is that it expands to nested parenthesized expressions expressions.
Sets the limit for nested parentheses, brackets, and braces to N in blocks, declarators, expressions, and struct or union declarations.The 256 default limit is REALLY small for a fold expression, particularly since the instantiation depth limit is 1024 by default. I think this patch needs to be changed to use the InstantiationDepth instead. @rjmccall, thoughts?
One motivation here is to limit exposure of tools to stack overflows. A modest increase in the stack size of DynTypedNode triggered stack overflows in various traversals on real code.
While it's possible in principle to write traversals that use only data recursion (and I've also fixed the ones in clang itself that I can find), in practice a lot of code and tools rely on recursive traversals, so trivially creating arbitrarily deep ASTs without any limit is certain to break things with unclear responsibility. (Whereas this change places responsibility with boost numerics).
FWIW, somewhere between 1024 and 2048 was the critical depth on the systems we looked at, so 1024 seems... plausible, but large.
I think this should be NoSFINAE, similar to err_template_recursion_depth_exceeded.
Maybe DefaultFatal too?