# 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 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 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. # 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.