# cmake-0003 — AddRuntimeDLL: O(n) std::find per DLL in hot loop

**Severity:** MEDIUM
**File:** `Source/cmComputeLinkInformation.cxx`
**Lines:** 1352–1355
**CWE:** CWE-407 (Algorithmic Complexity — Quadratic)

## Description

`AddRuntimeDLL()` guards insertion with a linear scan over `RuntimeDLLs`:

```cpp
// Source/cmComputeLinkInformation.cxx:1352-1355
if (std::find(this->RuntimeDLLs.begin(), this->RuntimeDLLs.end(), tgt) ==
    this->RuntimeDLLs.end()) {
  this->RuntimeDLLs.emplace_back(tgt);
}
```

`AddRuntimeDLL` is called from `AddItem()` and `AddSharedDepItem()`, both of
which are invoked for every link entry in the `Compute()` main loop over
`linkEntries`. On a Windows/DLL project with D shared-library dependencies,
the total cost is O(D²) pointer comparisons.

## Fix

Add a parallel `std::unordered_set<cmGeneratorTarget const*> RuntimeDLLsSet`
member. Replace the `std::find` guard with a set insertion check.

**Patch:** `patch/cmake-0003-addruntimedll-unordered-set.patch`
**Unit test:** `unit/RuntimeDllAlgorithm.java`

## Complexity

| | Time |
|---|---|
| Before | O(D²) |
| After | O(D) amortised |
