forked from OSchip/llvm-project
[clang] Limit the maximum level of fold-expr expansion.
Introduce a new diagnostic, and respect the bracket-depth (256) by default. Differential Revision: https://reviews.llvm.org/D86936
This commit is contained in:
parent
156b127945
commit
9c9974c3cc
|
@ -5092,6 +5092,9 @@ def err_fold_expression_empty : Error<
|
|||
"with no fallback value">;
|
||||
def err_fold_expression_bad_operand : Error<
|
||||
"expression not permitted as operand of fold expression">;
|
||||
def err_fold_expression_limit_exceeded: Error<
|
||||
"instantiating fold expression with %0 arguments exceeded expression nesting "
|
||||
"limit of %1">, DefaultFatal, NoSFINAE;
|
||||
|
||||
def err_unexpected_typedef : Error<
|
||||
"unexpected type name %0: expected expression">;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "clang/AST/StmtCXX.h"
|
||||
#include "clang/AST/StmtObjC.h"
|
||||
#include "clang/AST/StmtOpenMP.h"
|
||||
#include "clang/Basic/DiagnosticParse.h"
|
||||
#include "clang/Basic/OpenMPKinds.h"
|
||||
#include "clang/Sema/Designator.h"
|
||||
#include "clang/Sema/Lookup.h"
|
||||
|
@ -13193,6 +13194,18 @@ TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
|
|||
E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
|
||||
}
|
||||
|
||||
// Formally a fold expression expands to nested parenthesized expressions.
|
||||
// Enforce this limit to avoid creating trees so deep we can't safely traverse
|
||||
// them.
|
||||
if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
|
||||
SemaRef.Diag(E->getEllipsisLoc(),
|
||||
clang::diag::err_fold_expression_limit_exceeded)
|
||||
<< *NumExpansions << SemaRef.getLangOpts().BracketDepth
|
||||
<< E->getSourceRange();
|
||||
SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
// The transform has determined that we should perform an elementwise
|
||||
// expansion of the pattern. Do so.
|
||||
ExprResult Result = getDerived().TransformExpr(E->getInit());
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -fbracket-depth 2 -verify -std=c++17 %s
|
||||
|
||||
template <class T, T... V> struct seq {
|
||||
constexpr bool zero() { return (true && ... && (V == 0)); }; // expected-error {{instantiating fold expression with 3 arguments exceeded expression nesting limit of 2}} \
|
||||
expected-note {{use -fbracket-depth}}
|
||||
};
|
||||
constexpr unsigned N = 3;
|
||||
auto x = __make_integer_seq<seq, int, N>{};
|
||||
static_assert(!x.zero(), ""); // expected-note {{in instantiation of member function}}
|
Loading…
Reference in New Issue