47 lines
2.2 KiB
C++
47 lines
2.2 KiB
C++
#include <algorithm>
|
|
#include <catch2/catch_test_macros.hpp>
|
|
#include <limits>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "fold/ir/call_graph.hpp"
|
|
|
|
TEST_CASE("project graph keeps overloads distinct by semantic identity", "[call-graph][identity]") {
|
|
fold::ir::ProjectCallGraph graph;
|
|
graph.addFunction("usr:f:int", "f", "a.cpp", true, "body-int");
|
|
graph.addFunction("usr:f:double", "f", "a.cpp", true, "body-double");
|
|
graph.addFunction("usr:caller", "caller", "a.cpp", true);
|
|
graph.addCallEdge("usr:caller", "usr:f:int");
|
|
|
|
CHECK(graph.nodeCount() == 3);
|
|
CHECK(graph.getNode("usr:f:int")->body_hash == "body-int");
|
|
CHECK(graph.getNode("usr:f:double")->body_hash == "body-double");
|
|
CHECK(graph.getNode("f") == nullptr); // ambiguous names fail closed
|
|
CHECK(graph.getSccId("f") == std::numeric_limits<unsigned>::max());
|
|
CHECK(graph.getCallees("caller") == std::vector<std::string>{"f"});
|
|
CHECK(graph.getCalleeIds("usr:caller") == std::vector<std::string>{"usr:f:int"});
|
|
}
|
|
|
|
TEST_CASE("project graph retains strongest typed edge and deterministic SCC identities",
|
|
"[call-graph][edge-kind]") {
|
|
fold::ir::ProjectCallGraph graph;
|
|
graph.addFunction("usr:a", "a", "a.cpp", true, {}, true);
|
|
graph.addFunction("usr:b", "b", "b.cpp", true);
|
|
graph.addFunction("unknown:usr:a", "<unknown-call>", {}, false);
|
|
graph.addCallEdge("usr:a", "usr:b", fold::ir::CallGraphEdgeKind::Conservative, 0.5);
|
|
graph.addCallEdge("usr:a", "usr:b", fold::ir::CallGraphEdgeKind::Direct, 1.0);
|
|
graph.addCallEdge("usr:b", "usr:a", fold::ir::CallGraphEdgeKind::Direct, 1.0);
|
|
graph.addCallEdge("usr:a", "unknown:usr:a", fold::ir::CallGraphEdgeKind::Unknown, 0.0);
|
|
graph.computeSCCs();
|
|
|
|
CHECK(graph.edgeCount() == 3);
|
|
CHECK(graph.edgeCount(fold::ir::CallGraphEdgeKind::Direct) == 2);
|
|
CHECK(graph.edgeCount(fold::ir::CallGraphEdgeKind::Conservative) == 0);
|
|
CHECK(graph.edgeCount(fold::ir::CallGraphEdgeKind::Unknown) == 1);
|
|
CHECK(graph.unresolvedNodeCount() == 1);
|
|
CHECK(graph.getNode("usr:a")->escapes);
|
|
|
|
const unsigned scc = graph.getSccId("usr:a");
|
|
CHECK(scc == graph.getSccId("usr:b"));
|
|
CHECK(graph.getSccFunctionIds(scc) == std::vector<std::string>{"usr:a", "usr:b"});
|
|
}
|