java-topology/defects/llvm/patch/llvm-0004-domconditioncache-denseset.patch

54 lines
2.1 KiB
Diff

# UNDF: UNDF-2026-000000155
diff --git a/llvm/lib/Analysis/DomConditionCache.cpp b/llvm/lib/Analysis/DomConditionCache.cpp
index a1b2c3d..f4e5d6a 100644
--- a/llvm/lib/Analysis/DomConditionCache.cpp
+++ b/llvm/lib/Analysis/DomConditionCache.cpp
@@ -8,6 +8,7 @@
#include "llvm/Analysis/DomConditionCache.h"
#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/ADT/SmallPtrSet.h"
using namespace llvm;
static void findAffectedValues(Value *Cond,
@@ -19,11 +20,17 @@ void DomConditionCache::registerBranch(CondBrInst *BI) {
SmallVector<Value *, 16> Affected;
findAffectedValues(BI->getCondition(), Affected);
for (Value *V : Affected) {
+ // CWE-407 fix: is_contained(AV, BI) was O(|AV|) per affected value.
+ // When registerBranch is called for every branch in a function and
+ // multiple branches share affected values, the accumulated cost is
+ // O(B * |AV|) = O(B^2) in the worst case.
+ // Build a SmallPtrSet from AV for O(1) duplicate check.
auto &AV = AffectedValues[V];
- if (!is_contained(AV, BI))
- AV.push_back(BI);
+ SmallPtrSet<CondBrInst *, 8> AVSet(AV.begin(), AV.end());
+ if (!AVSet.count(BI))
+ AV.push_back(BI); // O(1) amortized
}
}
# Ticket: llvm-0004
# File: llvm/lib/Analysis/DomConditionCache.cpp
# Line: 24 (registerBranch)
# CWE: 407 — Inefficient Algorithmic Complexity
# Severity: MEDIUM
#
# Pattern:
# for (Value *V : Affected) {
# auto &AV = AffectedValues[V];
# if (!is_contained(AV, BI)) // O(|AV|) linear scan
# AV.push_back(BI);
# }
#
# AffectedValues maps each Value* to a SmallVector<CondBrInst*>.
# registerBranch is called once per conditional branch in a function.
# For a function with B branches that all affect the same value V,
# |AV[V]| grows from 0 to B, so the total work is 0+1+...+(B-1) = O(B^2).
#
# Fix: build a SmallPtrSet from AV before checking membership.
# Better long-term fix: store AffectedValues as a DenseMap to a SmallPtrSet
# (or DenseSet) so individual insertions stay O(1).
#
# Speedup: O(B^2) → O(B·|Affected|) ≈ O(B) for typical Affected sizes.