CWE-407: is_contained(BlockList, Succ) inside nested for loops in computeOutliningColdRegionsInfo. Fix: SmallPtrSet for O(1) membership. GCC deep scan: CLEAN (bitmaps/hash_sets throughout).
77 lines
2.7 KiB
Java
77 lines
2.7 KiB
Java
import java.util.*;
|
||
|
||
/**
|
||
* CWE-407 unit tests for LLVM defects (new: llvm-0006).
|
||
*
|
||
* llvm-0006: PartialInlining IsSingleExit — is_contained(BlockList, ...) O(N²)
|
||
*
|
||
* (llvm-0001 through llvm-0005 have separate unit tests or are covered
|
||
* by LlvmAliasSetTest.java, LlvmDomConditionCacheTest.java, etc.)
|
||
*/
|
||
public class LlvmTest {
|
||
|
||
// ---------------------------------------------------------------
|
||
// llvm-0006: PartialInlining IsSingleExit BlockList membership
|
||
// is_contained(BlockList, Succ) inside nested for loops → O(N² × S)
|
||
// ---------------------------------------------------------------
|
||
|
||
/** Defective: linear scan for block list membership */
|
||
static int isSingleExitDefective(int blockCount) {
|
||
List<Integer> blockList = new ArrayList<>();
|
||
for (int i = 0; i < blockCount; i++) blockList.add(i);
|
||
int ops = 0;
|
||
|
||
for (int block : blockList) {
|
||
// Each block has ~2 successors
|
||
int[] successors = { block + 1, block + blockCount / 3 };
|
||
for (int succ : successors) {
|
||
// Linear scan: is_contained(BlockList, Succ)
|
||
for (int b : blockList) {
|
||
ops++;
|
||
if (b == succ) break;
|
||
}
|
||
}
|
||
}
|
||
return ops;
|
||
}
|
||
|
||
/** Fixed: SmallPtrSet for block list membership */
|
||
static int isSingleExitFixed(int blockCount) {
|
||
Set<Integer> blockSet = new HashSet<>();
|
||
for (int i = 0; i < blockCount; i++) blockSet.add(i);
|
||
int ops = 0;
|
||
|
||
for (int block = 0; block < blockCount; block++) {
|
||
int[] successors = { block + 1, block + blockCount / 3 };
|
||
for (int succ : successors) {
|
||
ops++; // O(1) hash lookup
|
||
blockSet.contains(succ);
|
||
}
|
||
}
|
||
return ops;
|
||
}
|
||
|
||
// ---------------------------------------------------------------
|
||
// Test runner
|
||
// ---------------------------------------------------------------
|
||
|
||
static void check(String name, boolean cond) {
|
||
System.out.println((cond ? "PASS" : "FAIL") + " " + name);
|
||
if (!cond) System.exit(1);
|
||
}
|
||
|
||
public static void main(String[] args) {
|
||
// llvm-0006: PartialInlining IsSingleExit
|
||
{
|
||
int N = 500;
|
||
int defectOps = isSingleExitDefective(N);
|
||
int fixedOps = isSingleExitFixed(N);
|
||
double ratio = (double) defectOps / fixedOps;
|
||
System.out.printf("llvm-0006: defect=%d fixed=%d ratio=%.1fx%n", defectOps, fixedOps, ratio);
|
||
check("llvm-0006-quadratic", defectOps > fixedOps * 10);
|
||
check("llvm-0006-fixed-linear", fixedOps <= N * 3);
|
||
}
|
||
|
||
System.out.println("ALL PASS");
|
||
}
|
||
}
|