[gcc(refs/users/aoliva/heads/testme)] detect infinite loops earlier in returning_call_p
Alexandre Oliva
aoliva@gcc.gnu.org
Fri Jun 9 06:17:23 GMT 2023
https://gcc.gnu.org/g:6269d7a415f9fad7a49f03c8b4a2387d21a9ccc9
commit 6269d7a415f9fad7a49f03c8b4a2387d21a9ccc9
Author: Alexandre Oliva <oliva@adacore.com>
Date: Thu Jun 8 05:55:04 2023 -0300
detect infinite loops earlier in returning_call_p
An infinite loop could create a path as long as the block count in
returning_call_p, and then fail the backwards check if a call is found
before emptying the path.
Return as soon as the path exceeds the block count, and search for
duplicate blocks before allocating more memory for the path, so as to
cut the looping short.
for gcc/ChangeLog
* gimple-harden-control-flow.cc (returning_call_p): Detect
infinite loops sooner.
Diff:
---
gcc/gimple-harden-control-flow.cc | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/gcc/gimple-harden-control-flow.cc b/gcc/gimple-harden-control-flow.cc
index 3998fd0d293..044671cab79 100644
--- a/gcc/gimple-harden-control-flow.cc
+++ b/gcc/gimple-harden-control-flow.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_ALGORITHM /* find */
#include "system.h"
#include "coretypes.h"
#include "backend.h"
@@ -211,14 +212,19 @@ returning_call_p (gcall *call)
return false;
/* Quickly check that there's a path to exit compatible with a
- returning call. Detect infinite loops through the counter. */
- basic_block bb = gimple_bb (call);
+ returning call. Detect infinite loops by limiting the path
+ length to the basic block count, and by looking for duplicate
+ blocks before allocating more memory for the path, for amortized
+ O(n). */
auto_vec<basic_block, 10> path;
- for (int i = n_basic_blocks_for_fn (cfun);
- bb != EXIT_BLOCK_PTR_FOR_FN (cfun) && i--;
+ for (basic_block bb = gimple_bb (call);
+ bb != EXIT_BLOCK_PTR_FOR_FN (cfun);
bb = single_succ (bb))
if (!single_succ_p (bb)
- || (single_succ_edge (bb)->flags & EDGE_EH) != 0)
+ || (single_succ_edge (bb)->flags & EDGE_EH) != 0
+ || n_basic_blocks_for_fn (cfun) - path.length () <= NUM_FIXED_BLOCKS
+ || (path.length () == path.allocated ()
+ && std::find (path.begin (), path.end (), bb) != path.end ()))
return false;
else
path.safe_push (bb);
More information about the Gcc-cvs
mailing list