88 lines
3 KiB
Diff
88 lines
3 KiB
Diff
# UNDF: UNDF-2026-000000077
|
|
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
|
|
index d3e4f5a..c6b7d8e 100644
|
|
--- a/gcc/gimple-range-path.cc
|
|
+++ b/gcc/gimple-range-path.cc
|
|
@@ -15,6 +15,7 @@ along with GCC; see the file COPYING3. If not see
|
|
#include "coretypes.h"
|
|
#include "backend.h"
|
|
#include "tree.h"
|
|
+#include "hash-set.h"
|
|
#include "gimple.h"
|
|
#include "cfganal.h"
|
|
|
|
@@ -487,6 +487,12 @@ path_range_query::compute_exit_dependencies (bitmap dependencies)
|
|
basic_block exit = m_path[0];
|
|
bitmap_copy (dependencies, gori_ssa ()->imports (exit));
|
|
|
|
+ // CWE-407 fix: m_path.contains(bb) was O(|m_path|) per SSA name in the
|
|
+ // worklist. The worklist can hold O(|m_path| * SSA_names) items, making
|
|
+ // the total cost O(|m_path|^2 * SSA_names).
|
|
+ // Pre-build a hash_set<basic_block> from m_path for O(1) membership.
|
|
+ hash_set<basic_block> path_set;
|
|
+ for (basic_block bb : m_path)
|
|
+ path_set.add (bb);
|
|
+
|
|
auto_vec<tree> worklist (bitmap_count_bits (dependencies));
|
|
bitmap_iterator bi;
|
|
unsigned i;
|
|
@@ -503,14 +510,14 @@ path_range_query::compute_exit_dependencies (bitmap dependencies)
|
|
tree name = worklist.pop ();
|
|
gimple *def_stmt = SSA_NAME_DEF_STMT (name);
|
|
if (SSA_NAME_IS_DEFAULT_DEF (name)
|
|
- || !m_path.contains (gimple_bb (def_stmt)))
|
|
+ || !path_set.contains (gimple_bb (def_stmt)))
|
|
continue;
|
|
|
|
if (gphi *phi = dyn_cast <gphi *> (def_stmt))
|
|
{
|
|
for (size_t i = 0; i < gimple_phi_num_args (phi); ++i)
|
|
{
|
|
edge e = gimple_phi_arg_edge (phi, i);
|
|
tree arg = gimple_phi_arg (phi, i)->def;
|
|
|
|
if (TREE_CODE (arg) == SSA_NAME
|
|
- && m_path.contains (e->src)
|
|
+ && path_set.contains (e->src)
|
|
&& bitmap_set_bit (dependencies, SSA_NAME_VERSION (arg)))
|
|
worklist.safe_push (arg);
|
|
}
|
|
@@ -528,5 +535,5 @@ path_range_query::compute_exit_dependencies (bitmap dependencies)
|
|
for (i = 0; i < m_path.length (); ++i)
|
|
{
|
|
basic_block bb = m_path[i];
|
|
tree name;
|
|
FOR_EACH_GORI_EXPORT_NAME (gori_ssa (), bb, name)
|
|
if (TREE_CODE (TREE_TYPE (name)) == BOOLEAN_TYPE)
|
|
bitmap_set_bit (dependencies, SSA_NAME_VERSION (name));
|
|
}
|
|
}
|
|
|
|
# Ticket: gcc-0002
|
|
# File: gcc/gimple-range-path.cc
|
|
# Line: 510, 521 (compute_exit_dependencies)
|
|
# CWE: 407 — Inefficient Algorithmic Complexity
|
|
# Severity: HIGH
|
|
#
|
|
# Pattern:
|
|
# while (!worklist.is_empty ())
|
|
# {
|
|
# ...
|
|
# if (!m_path.contains (gimple_bb (def_stmt))) // O(|m_path|)
|
|
# continue;
|
|
# for (phi args) {
|
|
# if (m_path.contains (e->src) ...) // O(|m_path|)
|
|
# worklist.safe_push (arg);
|
|
# }
|
|
# }
|
|
#
|
|
# m_path is an auto_vec<basic_block>. auto_vec::contains() is a linear
|
|
# scan. The worklist grows with each phi arg that is on the path, so
|
|
# worst-case |worklist| = O(P * N) where P = path length, N = SSA names.
|
|
# Each worklist item does O(P) work → total O(P^2 * N).
|
|
#
|
|
# Fix: pre-build hash_set<basic_block> from m_path; O(1) per lookup.
|
|
# Total cost drops to O(P + P*N) = O(P*N).
|
|
#
|
|
# Speedup: O(P^2*N) → O(P*N). At P=100 BBs, N=500 SSA names: 5M ops → 50K.
|
|
# Speedup factor: ~100x (= P).
|