54 lines
2.1 KiB
Diff
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.
|