diff options
author | Jason Merrill <jason@redhat.com> | 2016-07-25 14:32:13 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-07-25 14:32:13 -0400 |
commit | 5ec2cd9f666a8d26ce62ee7ef6383948fafb1b35 (patch) | |
tree | 4aaebb6731b4983f7f2b22d47f9f80c7612eae01 /gcc | |
parent | fd2bfee51ee9b63869652ed0812df1d34aaca093 (diff) | |
download | gcc-5ec2cd9f666a8d26ce62ee7ef6383948fafb1b35.zip gcc-5ec2cd9f666a8d26ce62ee7ef6383948fafb1b35.tar.gz gcc-5ec2cd9f666a8d26ce62ee7ef6383948fafb1b35.tar.bz2 |
PR c++/65970 - constexpr infinite loop
gcc/c-family/
* c.opt (fconstexpr-loop-limit): New.
gcc/cp/
* constexpr.c (cxx_eval_loop_expr): Count iterations.
* cp-gimplify.c (genericize_cp_loop): Use start_locus even for
infinite loops.
From-SVN: r238730
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c-family/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c-family/c.opt | 4 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 11 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 9 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-loop6.C | 11 |
7 files changed, 45 insertions, 9 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 5c19305..72ccd03 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2016-07-25 Jason Merrill <jason@redhat.com> + + PR c++/65970 + * c.opt (fconstexpr-loop-limit): New. + 2016-07-22 Martin Sebor <msebor@redhat.com> PR c++/71675 diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 8c70152..a5358ed 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1174,6 +1174,10 @@ fconstexpr-depth= C++ ObjC++ Joined RejectNegative UInteger Var(max_constexpr_depth) Init(512) -fconstexpr-depth=<number> Specify maximum constexpr recursion depth. +fconstexpr-loop-limit= +C++ ObjC++ Joined RejectNegative UInteger Var(constexpr_loop_limit) Init(262144) +-fconstexpr-loop-limit=<number> Specify maximum constexpr loop iteration count. + fdebug-cpp C ObjC C++ ObjC++ Emit debug annotations during preprocessing. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a540d31..5854205 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2016-07-25 Jason Merrill <jason@redhat.com> + PR c++/65970 + * constexpr.c (cxx_eval_loop_expr): Count iterations. + * cp-gimplify.c (genericize_cp_loop): Use start_locus even for + infinite loops. + PR c++/71972 * constexpr.c (cxx_eval_array_reference): Handle looking for the value of an element we're currently modifying. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 47fb39b..6bcb41a 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -3468,6 +3468,7 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t, constexpr_ctx new_ctx = *ctx; tree body = TREE_OPERAND (t, 0); + int count = 0; do { hash_set<tree> save_exprs; @@ -3480,6 +3481,16 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t, for (hash_set<tree>::iterator iter = save_exprs.begin(); iter != save_exprs.end(); ++iter) new_ctx.values->remove (*iter); + if (++count >= constexpr_loop_limit) + { + if (!ctx->quiet) + error_at (EXPR_LOC_OR_LOC (t, input_location), + "constexpr loop iteration count exceeds limit of %d " + "(use -fconstexpr-loop-limit= to increase the limit)", + constexpr_loop_limit); + *non_constant_p = true; + break; + } } while (!returns (jump_target) && !breaks (jump_target) && !*non_constant_p); diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 59953a6..d9f7cea 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -264,14 +264,7 @@ genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body, loop = stmt_list; } else - { - location_t loc = start_locus; - if (!cond || integer_nonzerop (cond)) - loc = EXPR_LOCATION (expr_first (body)); - if (loc == UNKNOWN_LOCATION) - loc = start_locus; - loop = build1_loc (loc, LOOP_EXPR, void_type_node, stmt_list); - } + loop = build1_loc (start_locus, LOOP_EXPR, void_type_node, stmt_list); stmt_list = NULL; append_to_statement_list (loop, &stmt_list); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 9e0f07e..79c842d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -191,7 +191,8 @@ in the following sections. @xref{C++ Dialect Options,,Options Controlling C++ Dialect}. @gccoptlist{-fabi-version=@var{n} -fno-access-control @gol -fargs-in-order=@var{n} -fcheck-new @gol --fconstexpr-depth=@var{n} -ffriend-injection @gol +-fconstexpr-depth=@var{n} -fconstexpr-loop-limit=@var{n} @gol +-ffriend-injection @gol -fno-elide-constructors @gol -fno-enforce-eh-specs @gol -ffor-scope -fno-for-scope -fno-gnu-keywords @gol @@ -2265,6 +2266,12 @@ to @var{n}. A limit is needed to detect endless recursion during constant expression evaluation. The minimum specified by the standard is 512. +@item -fconstexpr-loop-limit=@var{n} +@opindex fconstexpr-loop-limit +Set the maximum number of iterations for a loop in C++14 constexpr functions +to @var{n}. A limit is needed to detect infinite loops during +constant expression evaluation. The default is 262144 (1<<18). + @item -fdeduce-init-list @opindex fdeduce-init-list Enable deduction of a template type parameter as diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-loop6.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-loop6.C new file mode 100644 index 0000000..e49e531 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-loop6.C @@ -0,0 +1,11 @@ +// PR c++/65970 +// { dg-do compile { target c++14 } } +// { dg-options -fconstexpr-loop-limit=5 } + +constexpr int foo() { + while (true) // { dg-error "-fconstexpr-loop-limit" } + ; + return 0; +} + +constexpr int i = foo(); // { dg-message "" } |