[clang] 9c9974c - [clang] Limit the maximum level of fold-expr expansion.
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 8 06:40:41 PDT 2020
Author: Haojian Wu
Date: 2020-09-08T15:40:09+02:00
New Revision: 9c9974c3ccb6468cc83f759240293538cf123fcd
URL: https://github.com/llvm/llvm-project/commit/9c9974c3ccb6468cc83f759240293538cf123fcd
DIFF: https://github.com/llvm/llvm-project/commit/9c9974c3ccb6468cc83f759240293538cf123fcd.diff
LOG: [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
Added:
clang/test/SemaCXX/fold_expr_expansion_limit.cpp
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/TreeTransform.h
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e1601da74b73..ec0c0fd9fa8c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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">;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 4c8293f3bf4c..6457b192477e 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -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());
diff --git a/clang/test/SemaCXX/fold_expr_expansion_limit.cpp b/clang/test/SemaCXX/fold_expr_expansion_limit.cpp
new file mode 100644
index 000000000000..600278da7828
--- /dev/null
+++ b/clang/test/SemaCXX/fold_expr_expansion_limit.cpp
@@ -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}}
More information about the cfe-commits
mailing list