4963 lines
124 KiB
C++
4963 lines
124 KiB
C++
|
|
#include <gtest/gtest.h>
|
||
|
|
#include <type_traits>
|
||
|
|
#include <tcl.h>
|
||
|
|
#include "MinMax.hh"
|
||
|
|
#include "Transition.hh"
|
||
|
|
#include "Property.hh"
|
||
|
|
#include "ExceptionPath.hh"
|
||
|
|
#include "TimingRole.hh"
|
||
|
|
#include "Corner.hh"
|
||
|
|
#include "Sta.hh"
|
||
|
|
#include "Sdc.hh"
|
||
|
|
#include "ReportTcl.hh"
|
||
|
|
#include "RiseFallMinMax.hh"
|
||
|
|
#include "Variables.hh"
|
||
|
|
#include "LibertyClass.hh"
|
||
|
|
#include "PathAnalysisPt.hh"
|
||
|
|
#include "DcalcAnalysisPt.hh"
|
||
|
|
#include "Search.hh"
|
||
|
|
#include "Path.hh"
|
||
|
|
#include "PathGroup.hh"
|
||
|
|
#include "PathExpanded.hh"
|
||
|
|
#include "SearchPred.hh"
|
||
|
|
#include "SearchClass.hh"
|
||
|
|
#include "ClkNetwork.hh"
|
||
|
|
#include "VisitPathEnds.hh"
|
||
|
|
#include "search/CheckMinPulseWidths.hh"
|
||
|
|
#include "search/CheckMinPeriods.hh"
|
||
|
|
#include "search/CheckMaxSkews.hh"
|
||
|
|
#include "search/ClkSkew.hh"
|
||
|
|
#include "search/ClkInfo.hh"
|
||
|
|
#include "search/Tag.hh"
|
||
|
|
#include "search/PathEnum.hh"
|
||
|
|
#include "search/Genclks.hh"
|
||
|
|
#include "search/Levelize.hh"
|
||
|
|
#include "search/Sim.hh"
|
||
|
|
#include "Bfs.hh"
|
||
|
|
#include "search/WorstSlack.hh"
|
||
|
|
#include "search/ReportPath.hh"
|
||
|
|
#include "GraphDelayCalc.hh"
|
||
|
|
#include "Debug.hh"
|
||
|
|
#include "PowerClass.hh"
|
||
|
|
#include "search/CheckCapacitanceLimits.hh"
|
||
|
|
#include "search/CheckSlewLimits.hh"
|
||
|
|
#include "search/CheckFanoutLimits.hh"
|
||
|
|
#include "search/Crpr.hh"
|
||
|
|
#include "search/GatedClk.hh"
|
||
|
|
#include "search/ClkLatency.hh"
|
||
|
|
#include "search/FindRegister.hh"
|
||
|
|
#include "search/TagGroup.hh"
|
||
|
|
#include "search/MakeTimingModelPvt.hh"
|
||
|
|
#include "search/CheckTiming.hh"
|
||
|
|
#include "search/Latches.hh"
|
||
|
|
#include "Graph.hh"
|
||
|
|
#include "Liberty.hh"
|
||
|
|
#include "Network.hh"
|
||
|
|
|
||
|
|
|
||
|
|
namespace sta {
|
||
|
|
|
||
|
|
template <typename FnPtr>
|
||
|
|
static void expectCallablePointerUsable(FnPtr fn) {
|
||
|
|
ASSERT_NE(fn, nullptr);
|
||
|
|
EXPECT_TRUE((std::is_pointer_v<FnPtr> || std::is_member_function_pointer_v<FnPtr>));
|
||
|
|
EXPECT_TRUE(std::is_copy_constructible_v<FnPtr>);
|
||
|
|
EXPECT_TRUE(std::is_copy_assignable_v<FnPtr>);
|
||
|
|
FnPtr fn_copy = fn;
|
||
|
|
EXPECT_EQ(fn_copy, fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void expectStaCoreState(Sta *sta);
|
||
|
|
|
||
|
|
|
||
|
|
class StaInitTest : public ::testing::Test {
|
||
|
|
protected:
|
||
|
|
void SetUp() override {
|
||
|
|
interp_ = Tcl_CreateInterp();
|
||
|
|
initSta();
|
||
|
|
sta_ = new Sta;
|
||
|
|
Sta::setSta(sta_);
|
||
|
|
sta_->makeComponents();
|
||
|
|
// Set the Tcl interp on the report so ReportTcl destructor works
|
||
|
|
ReportTcl *report = dynamic_cast<ReportTcl*>(sta_->report());
|
||
|
|
if (report)
|
||
|
|
report->setTclInterp(interp_);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TearDown() override {
|
||
|
|
if (sta_)
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
deleteAllMemory();
|
||
|
|
sta_ = nullptr;
|
||
|
|
if (interp_)
|
||
|
|
Tcl_DeleteInterp(interp_);
|
||
|
|
interp_ = nullptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
Sta *sta_;
|
||
|
|
Tcl_Interp *interp_;
|
||
|
|
};
|
||
|
|
|
||
|
|
static void expectStaCoreState(Sta *sta)
|
||
|
|
{
|
||
|
|
ASSERT_NE(sta, nullptr);
|
||
|
|
ASSERT_NE(sta->search(), nullptr);
|
||
|
|
ASSERT_NE(sta->sdc(), nullptr);
|
||
|
|
ASSERT_NE(sta->reportPath(), nullptr);
|
||
|
|
ASSERT_NE(sta->corners(), nullptr);
|
||
|
|
EXPECT_GE(sta->corners()->count(), 1);
|
||
|
|
EXPECT_NE(sta->cmdCorner(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: functions that call ensureLinked/ensureGraph (throw Exception) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaStartpointPinsThrows) {
|
||
|
|
EXPECT_THROW(sta_->startpointPins(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaEndpointsThrows) {
|
||
|
|
EXPECT_THROW(sta_->endpoints(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaEndpointPinsThrows) {
|
||
|
|
EXPECT_THROW(sta_->endpointPins(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaNetSlackThrows) {
|
||
|
|
EXPECT_THROW(sta_->netSlack(static_cast<const Net*>(nullptr), MinMax::max()), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPinSlackRfThrows) {
|
||
|
|
EXPECT_THROW(sta_->pinSlack(static_cast<const Pin*>(nullptr), RiseFall::rise(), MinMax::max()), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPinSlackThrows) {
|
||
|
|
EXPECT_THROW(sta_->pinSlack(static_cast<const Pin*>(nullptr), MinMax::max()), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaEndpointSlackThrows) {
|
||
|
|
std::string group_name("default");
|
||
|
|
EXPECT_THROW(sta_->endpointSlack(static_cast<const Pin*>(nullptr), group_name, MinMax::max()), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaGraphLoopsThrows) {
|
||
|
|
EXPECT_THROW(sta_->graphLoops(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexLevelThrows) {
|
||
|
|
EXPECT_THROW(sta_->vertexLevel(nullptr), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindLogicConstantsThrows2) {
|
||
|
|
EXPECT_THROW(sta_->findLogicConstants(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaEnsureClkNetworkThrows) {
|
||
|
|
EXPECT_THROW(sta_->ensureClkNetwork(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
// findRegisterPreamble is protected, skip
|
||
|
|
|
||
|
|
// delayCalcPreamble is protected, skip
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindDelaysThrows) {
|
||
|
|
EXPECT_THROW(sta_->findDelays(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindRequiredsThrows) {
|
||
|
|
EXPECT_THROW(sta_->findRequireds(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaEnsureLinkedThrows) {
|
||
|
|
EXPECT_THROW(sta_->ensureLinked(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaEnsureGraphThrows) {
|
||
|
|
EXPECT_THROW(sta_->ensureGraph(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaEnsureLevelizedThrows) {
|
||
|
|
EXPECT_THROW(sta_->ensureLevelized(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
// powerPreamble is protected, skip
|
||
|
|
|
||
|
|
// sdcChangedGraph is protected, skip
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindFaninPinsThrows2) {
|
||
|
|
EXPECT_THROW(sta_->findFaninPins(static_cast<Vector<const Pin*>*>(nullptr), false, false, 0, 0, false, false), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindFanoutPinsThrows2) {
|
||
|
|
EXPECT_THROW(sta_->findFanoutPins(static_cast<Vector<const Pin*>*>(nullptr), false, false, 0, 0, false, false), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMakePortPinThrows) {
|
||
|
|
EXPECT_THROW(sta_->makePortPin("test", nullptr), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaWriteSdcThrows2) {
|
||
|
|
EXPECT_THROW(sta_->writeSdc("test.sdc", false, false, 4, false, false), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: SearchPreamble and related ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSearchPreamble2) {
|
||
|
|
// searchPreamble calls ensureClkArrivals which calls findDelays
|
||
|
|
// It will throw because ensureGraph is called
|
||
|
|
EXPECT_THROW(sta_->searchPreamble(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaEnsureClkArrivals2) {
|
||
|
|
// calls findDelays which calls ensureGraph
|
||
|
|
EXPECT_THROW(sta_->ensureClkArrivals(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaUpdateTiming2) {
|
||
|
|
// calls findDelays
|
||
|
|
EXPECT_THROW(sta_->updateTiming(false), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Report header functions ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReportPathEndHeader2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->reportPathEndHeader();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReportPathEndFooter2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->reportPathEndFooter();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReportSlewLimitShortHeader) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->reportSlewLimitShortHeader();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReportFanoutLimitShortHeader) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->reportFanoutLimitShortHeader();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReportCapacitanceLimitShortHeader) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->reportCapacitanceLimitShortHeader();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: preamble functions ===
|
||
|
|
|
||
|
|
// minPulseWidthPreamble, minPeriodPreamble, maxSkewPreamble, clkSkewPreamble are protected, skip
|
||
|
|
|
||
|
|
// === Sta.cc: function pointer checks for methods needing network ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaIsClockPinExists) {
|
||
|
|
auto fn = static_cast<bool (Sta::*)(const Pin*) const>(&Sta::isClock);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaIsClockNetExists) {
|
||
|
|
auto fn = static_cast<bool (Sta::*)(const Net*) const>(&Sta::isClock);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaIsIdealClockExists) {
|
||
|
|
auto fn = &Sta::isIdealClock;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaIsPropagatedClockExists) {
|
||
|
|
auto fn = &Sta::isPropagatedClock;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaIsClockSrcExists) {
|
||
|
|
auto fn = &Sta::isClockSrc;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaConnectPinPortExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Instance*, Port*, Net*)>(&Sta::connectPin);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaConnectPinLibPortExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Instance*, LibertyPort*, Net*)>(&Sta::connectPin);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisconnectPinExists) {
|
||
|
|
auto fn = &Sta::disconnectPin;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReplaceCellExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Instance*, LibertyCell*)>(&Sta::replaceCell);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMakeInstanceExists) {
|
||
|
|
auto fn = &Sta::makeInstance;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMakeNetExists) {
|
||
|
|
auto fn = &Sta::makeNet;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDeleteInstanceExists) {
|
||
|
|
auto fn = &Sta::deleteInstance;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDeleteNetExists) {
|
||
|
|
auto fn = &Sta::deleteNet;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: check/violation preambles ===
|
||
|
|
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetParasiticAnalysisPts) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setParasiticAnalysisPts(false);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::setReportPathFields ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetReportPathFields) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setReportPathFields(true, true, true, true, true, true, true);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: delete exception helpers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDeleteExceptionFrom) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->deleteExceptionFrom(nullptr);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDeleteExceptionThru) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->deleteExceptionThru(nullptr);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDeleteExceptionTo) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->deleteExceptionTo(nullptr);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: readNetlistBefore ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReadNetlistBefore) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->readNetlistBefore();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: endpointViolationCount ===
|
||
|
|
|
||
|
|
// === Sta.cc: operatingConditions ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaOperatingConditions2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
auto oc = sta_->operatingConditions(MinMax::max());
|
||
|
|
(void)oc;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: removeConstraints ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaRemoveConstraints2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->removeConstraints();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: disabledEdgesSorted (calls ensureLevelized internally) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisabledEdgesSortedThrows) {
|
||
|
|
EXPECT_THROW(sta_->disabledEdgesSorted(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: disabledEdges (calls ensureLevelized) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisabledEdgesThrows) {
|
||
|
|
EXPECT_THROW(sta_->disabledEdges(), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: findReportPathField ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindReportPathField) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
auto field = sta_->findReportPathField("delay");
|
||
|
|
// May or may not find it
|
||
|
|
(void)field;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: findCorner ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindCornerByName) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
auto corner = sta_->findCorner("default");
|
||
|
|
// May or may not exist
|
||
|
|
(void)corner;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// === Sta.cc: totalNegativeSlack ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaTotalNegativeSlackThrows) {
|
||
|
|
EXPECT_THROW(sta_->totalNegativeSlack(MinMax::max()), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: worstSlack ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaWorstSlackThrows) {
|
||
|
|
EXPECT_THROW(sta_->worstSlack(MinMax::max()), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: setArcDelayCalc ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetArcDelayCalc) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setArcDelayCalc("unit");
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: setAnalysisType ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetAnalysisType) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setAnalysisType(AnalysisType::ocv);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: setTimingDerate (global) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetTimingDerate) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setTimingDerate(TimingDerateType::cell_delay, PathClkOrData::clk,
|
||
|
|
RiseFallBoth::riseFall(), MinMax::max(), 1.05f);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: setVoltage ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetVoltage) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setVoltage(MinMax::max(), 1.0f);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: setReportPathFieldOrder segfaults on null, use method exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetReportPathFieldOrderExists) {
|
||
|
|
auto fn = &Sta::setReportPathFieldOrder;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// === Sta.cc: clear ===
|
||
|
|
|
||
|
|
// === Property.cc: defineProperty overloads ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertiesDefineLibrary) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Properties props(sta_);
|
||
|
|
std::string prop_name("test_lib_prop");
|
||
|
|
props.defineProperty(prop_name,
|
||
|
|
PropertyRegistry<const Library*>::PropertyHandler(
|
||
|
|
[](const Library*, Sta*) -> PropertyValue { return PropertyValue(); }));
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertiesDefineLibertyLibrary) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Properties props(sta_);
|
||
|
|
std::string prop_name("test_liblib_prop");
|
||
|
|
props.defineProperty(prop_name,
|
||
|
|
PropertyRegistry<const LibertyLibrary*>::PropertyHandler(
|
||
|
|
[](const LibertyLibrary*, Sta*) -> PropertyValue { return PropertyValue(); }));
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertiesDefineCell) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Properties props(sta_);
|
||
|
|
std::string prop_name("test_cell_prop");
|
||
|
|
props.defineProperty(prop_name,
|
||
|
|
PropertyRegistry<const Cell*>::PropertyHandler(
|
||
|
|
[](const Cell*, Sta*) -> PropertyValue { return PropertyValue(); }));
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertiesDefineLibertyCell) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Properties props(sta_);
|
||
|
|
std::string prop_name("test_libcell_prop");
|
||
|
|
props.defineProperty(prop_name,
|
||
|
|
PropertyRegistry<const LibertyCell*>::PropertyHandler(
|
||
|
|
[](const LibertyCell*, Sta*) -> PropertyValue { return PropertyValue(); }));
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertiesDefinePort) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Properties props(sta_);
|
||
|
|
std::string prop_name("test_port_prop");
|
||
|
|
props.defineProperty(prop_name,
|
||
|
|
PropertyRegistry<const Port*>::PropertyHandler(
|
||
|
|
[](const Port*, Sta*) -> PropertyValue { return PropertyValue(); }));
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertiesDefineLibertyPort) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Properties props(sta_);
|
||
|
|
std::string prop_name("test_libport_prop");
|
||
|
|
props.defineProperty(prop_name,
|
||
|
|
PropertyRegistry<const LibertyPort*>::PropertyHandler(
|
||
|
|
[](const LibertyPort*, Sta*) -> PropertyValue { return PropertyValue(); }));
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertiesDefineInstance) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Properties props(sta_);
|
||
|
|
std::string prop_name("test_inst_prop");
|
||
|
|
props.defineProperty(prop_name,
|
||
|
|
PropertyRegistry<const Instance*>::PropertyHandler(
|
||
|
|
[](const Instance*, Sta*) -> PropertyValue { return PropertyValue(); }));
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertiesDefinePin) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Properties props(sta_);
|
||
|
|
std::string prop_name("test_pin_prop");
|
||
|
|
props.defineProperty(prop_name,
|
||
|
|
PropertyRegistry<const Pin*>::PropertyHandler(
|
||
|
|
[](const Pin*, Sta*) -> PropertyValue { return PropertyValue(); }));
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertiesDefineNet) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Properties props(sta_);
|
||
|
|
std::string prop_name("test_net_prop");
|
||
|
|
props.defineProperty(prop_name,
|
||
|
|
PropertyRegistry<const Net*>::PropertyHandler(
|
||
|
|
[](const Net*, Sta*) -> PropertyValue { return PropertyValue(); }));
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertiesDefineClock) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Properties props(sta_);
|
||
|
|
std::string prop_name("test_clk_prop");
|
||
|
|
props.defineProperty(prop_name,
|
||
|
|
PropertyRegistry<const Clock*>::PropertyHandler(
|
||
|
|
[](const Clock*, Sta*) -> PropertyValue { return PropertyValue(); }));
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search.cc: RequiredCmp ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, RequiredCmpConstruct) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
RequiredCmp cmp;
|
||
|
|
(void)cmp;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search.cc: EvalPred constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, EvalPredConstruct) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
EvalPred pred(sta_);
|
||
|
|
(void)pred;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// === Search.cc: ClkArrivalSearchPred ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkArrivalSearchPredConstruct) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ClkArrivalSearchPred pred(sta_);
|
||
|
|
(void)pred;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search.cc: Search accessors ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchTagCount2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
int tc = search->tagCount();
|
||
|
|
(void)tc;
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchTagGroupCount2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
int tgc = search->tagGroupCount();
|
||
|
|
(void)tgc;
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchClkInfoCount2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
int cnt = search->clkInfoCount();
|
||
|
|
(void)cnt;
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchArrivalsInvalid2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
search->arrivalsInvalid();
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchRequiredsInvalid2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
search->requiredsInvalid();
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchEndpointsInvalid2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
search->endpointsInvalid();
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchClear2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
search->clear();
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchHavePathGroups2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
bool val = search->havePathGroups();
|
||
|
|
(void)val;
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchCrprPathPruningEnabled) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
bool val = search->crprPathPruningEnabled();
|
||
|
|
(void)val;
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchCrprApproxMissingRequireds) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
bool val = search->crprApproxMissingRequireds();
|
||
|
|
(void)val;
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchSetCrprpathPruningEnabled) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
search->setCrprpathPruningEnabled(true);
|
||
|
|
EXPECT_TRUE(search->crprPathPruningEnabled());
|
||
|
|
search->setCrprpathPruningEnabled(false);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchSetCrprApproxMissingRequireds) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
search->setCrprApproxMissingRequireds(true);
|
||
|
|
EXPECT_TRUE(search->crprApproxMissingRequireds());
|
||
|
|
search->setCrprApproxMissingRequireds(false);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchDeleteFilter2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
search->deleteFilter();
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchDeletePathGroups2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
ASSERT_NE(search, nullptr);
|
||
|
|
search->deletePathGroups();
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnd.cc: more PathEndUnconstrained methods ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedCheckRole) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
const TimingRole *role = pe.checkRole(sta_);
|
||
|
|
EXPECT_EQ(role, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedTypeName) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
const char *name = pe.typeName();
|
||
|
|
EXPECT_STREQ(name, "unconstrained");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedType) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
EXPECT_EQ(pe.type(), PathEnd::unconstrained);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedIsUnconstrained) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
EXPECT_TRUE(pe.isUnconstrained());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedIsCheck) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
EXPECT_FALSE(pe.isCheck());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedIsLatchCheck) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
EXPECT_FALSE(pe.isLatchCheck());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedIsOutputDelay) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
EXPECT_FALSE(pe.isOutputDelay());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedIsGatedClock) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
EXPECT_FALSE(pe.isGatedClock());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedIsPathDelay) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
EXPECT_FALSE(pe.isPathDelay());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedTargetClkEdge) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
EXPECT_EQ(pe.targetClkEdge(sta_), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedTargetClkTime) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
EXPECT_FLOAT_EQ(pe.targetClkTime(sta_), 0.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedTargetClkOffset) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
EXPECT_FLOAT_EQ(pe.targetClkOffset(sta_), 0.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedSourceClkOffset) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
EXPECT_FLOAT_EQ(pe.sourceClkOffset(sta_), 0.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedCopy) {
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
PathEnd *copy = pe.copy();
|
||
|
|
EXPECT_NE(copy, nullptr);
|
||
|
|
EXPECT_EQ(copy->type(), PathEnd::unconstrained);
|
||
|
|
delete copy;
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedExceptPathCmp) {
|
||
|
|
Path *p1 = new Path();
|
||
|
|
Path *p2 = new Path();
|
||
|
|
PathEndUnconstrained pe1(p1);
|
||
|
|
PathEndUnconstrained pe2(p2);
|
||
|
|
int cmp = pe1.exceptPathCmp(&pe2, sta_);
|
||
|
|
EXPECT_EQ(cmp, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnd.cc: PathEndCheck constructor/type ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndCheckConstruct2) {
|
||
|
|
Path *p = new Path();
|
||
|
|
Path *clk = new Path();
|
||
|
|
PathEndCheck pe(p, nullptr, nullptr, clk, nullptr, sta_);
|
||
|
|
EXPECT_EQ(pe.type(), PathEnd::check);
|
||
|
|
EXPECT_TRUE(pe.isCheck());
|
||
|
|
EXPECT_FALSE(pe.isLatchCheck());
|
||
|
|
EXPECT_STREQ(pe.typeName(), "check");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndCheckGetters) {
|
||
|
|
Path *p = new Path();
|
||
|
|
Path *clk = new Path();
|
||
|
|
PathEndCheck pe(p, nullptr, nullptr, clk, nullptr, sta_);
|
||
|
|
EXPECT_EQ(pe.checkArc(), nullptr);
|
||
|
|
EXPECT_EQ(pe.multiCyclePath(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndCheckCopy) {
|
||
|
|
Path *p = new Path();
|
||
|
|
Path *clk = new Path();
|
||
|
|
PathEndCheck pe(p, nullptr, nullptr, clk, nullptr, sta_);
|
||
|
|
PathEnd *copy = pe.copy();
|
||
|
|
EXPECT_NE(copy, nullptr);
|
||
|
|
EXPECT_EQ(copy->type(), PathEnd::check);
|
||
|
|
delete copy;
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnd.cc: PathEndLatchCheck constructor/type ===
|
||
|
|
|
||
|
|
|
||
|
|
// === PathEnd.cc: PathEndPathDelay constructor/type ===
|
||
|
|
|
||
|
|
|
||
|
|
// === PathEnd.cc: PathEnd comparison statics ===
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
// === Bfs.cc: BfsFwdIterator/BfsBkwdIterator ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, BfsFwdIteratorConstruct) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
BfsFwdIterator iter(BfsIndex::other, nullptr, sta_);
|
||
|
|
bool has = iter.hasNext();
|
||
|
|
(void)has;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, BfsBkwdIteratorConstruct) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
BfsBkwdIterator iter(BfsIndex::other, nullptr, sta_);
|
||
|
|
bool has = iter.hasNext();
|
||
|
|
(void)has;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkNetwork.cc: ClkNetwork accessors ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkNetworkAccessors) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ClkNetwork *clk_net = sta_->clkNetwork();
|
||
|
|
if (clk_net) {
|
||
|
|
clk_net->clear();
|
||
|
|
}
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Corner.cc: Corner accessors ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CornerAccessors) {
|
||
|
|
Corner *corner = sta_->cmdCorner();
|
||
|
|
ASSERT_NE(corner, nullptr);
|
||
|
|
int idx = corner->index();
|
||
|
|
(void)idx;
|
||
|
|
const char *name = corner->name();
|
||
|
|
(void)name;
|
||
|
|
}
|
||
|
|
|
||
|
|
// === WorstSlack.cc: function exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaWorstSlackWithVertexExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(const MinMax*, Slack&, Vertex*&)>(&Sta::worstSlack);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathGroup.cc: PathGroup name constants ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupNameConstants) {
|
||
|
|
// PathGroup has static name constants
|
||
|
|
auto fn = static_cast<bool (Search::*)(void) const>(&Search::havePathGroups);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === CheckTiming.cc: checkTiming ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckTimingThrows2) {
|
||
|
|
EXPECT_THROW(sta_->checkTiming(true, true, true, true, true, true, true), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathExpanded.cc: PathExpanded on empty path ===
|
||
|
|
|
||
|
|
// === PathEnum.cc: function exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEnumExists) {
|
||
|
|
auto fn = &PathEnum::hasNext;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Genclks.cc: Genclks exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, GenclksExists2) {
|
||
|
|
auto fn = &Genclks::clear;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MakeTimingModel.cc: function exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaWriteTimingModelThrows) {
|
||
|
|
EXPECT_THROW(sta_->writeTimingModel("out.lib", "model", "cell", nullptr), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Tag.cc: Tag function exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagTransitionExists) {
|
||
|
|
auto fn = &Tag::transition;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagPathAPIndexExists) {
|
||
|
|
auto fn = &Tag::pathAPIndex;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === StaState.cc: StaState units ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaStateReport) {
|
||
|
|
Report *rpt = sta_->report();
|
||
|
|
EXPECT_NE(rpt, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkSkew.cc: function exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindWorstClkSkewExists) {
|
||
|
|
auto fn = &Sta::findWorstClkSkew;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkLatency.cc: function exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReportClkLatencyExists) {
|
||
|
|
auto fn = &Sta::reportClkLatency;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkInfo.cc: accessors ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoClockEdgeExists) {
|
||
|
|
auto fn = &ClkInfo::clkEdge;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoIsPropagatedExists) {
|
||
|
|
auto fn = &ClkInfo::isPropagated;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoIsGenClkSrcPathExists) {
|
||
|
|
auto fn = &ClkInfo::isGenClkSrcPath;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Crpr.cc: function exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CrprExists) {
|
||
|
|
auto fn = &Search::crprApproxMissingRequireds;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === FindRegister.cc: findRegister functions ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindRegisterInstancesThrows2) {
|
||
|
|
EXPECT_THROW(sta_->findRegisterInstances(nullptr, RiseFallBoth::riseFall(), false, false), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindRegisterClkPinsThrows2) {
|
||
|
|
EXPECT_THROW(sta_->findRegisterClkPins(nullptr, RiseFallBoth::riseFall(), false, false), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindRegisterDataPinsThrows2) {
|
||
|
|
EXPECT_THROW(sta_->findRegisterDataPins(nullptr, RiseFallBoth::riseFall(), false, false), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindRegisterOutputPinsThrows2) {
|
||
|
|
EXPECT_THROW(sta_->findRegisterOutputPins(nullptr, RiseFallBoth::riseFall(), false, false), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindRegisterAsyncPinsThrows2) {
|
||
|
|
EXPECT_THROW(sta_->findRegisterAsyncPins(nullptr, RiseFallBoth::riseFall(), false, false), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::setCurrentInstance ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetCurrentInstanceNull) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setCurrentInstance(nullptr);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::pathGroupNames ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPathGroupNames) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
auto names = sta_->pathGroupNames();
|
||
|
|
(void)names;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::isPathGroupName ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaIsPathGroupName) {
|
||
|
|
bool val = sta_->isPathGroupName("nonexistent");
|
||
|
|
EXPECT_FALSE(val);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::removeClockGroupsLogicallyExclusive etc ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaRemoveClockGroupsLogicallyExclusive2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->removeClockGroupsLogicallyExclusive("test");
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaRemoveClockGroupsPhysicallyExclusive2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->removeClockGroupsPhysicallyExclusive("test");
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaRemoveClockGroupsAsynchronous2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->removeClockGroupsAsynchronous("test");
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::setDebugLevel ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetDebugLevel) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setDebugLevel("search", 0);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::slowDrivers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSlowDriversThrows) {
|
||
|
|
EXPECT_THROW(sta_->slowDrivers(10), Exception);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::setMinPulseWidth ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetMinPulseWidth) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setMinPulseWidth(RiseFallBoth::riseFall(), 0.1f);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: various set* functions that delegate to Sdc ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetClockGatingCheckGlobal2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setClockGatingCheck(RiseFallBoth::riseFall(), MinMax::max(), 0.1f);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::makeExceptionFrom/Thru/To ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMakeExceptionFrom2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ExceptionFrom *from = sta_->makeExceptionFrom(nullptr, nullptr, nullptr,
|
||
|
|
RiseFallBoth::riseFall());
|
||
|
|
// Returns a valid ExceptionFrom even with null args
|
||
|
|
if (from) sta_->deleteExceptionFrom(from);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMakeExceptionThru2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ExceptionThru *thru = sta_->makeExceptionThru(nullptr, nullptr, nullptr,
|
||
|
|
RiseFallBoth::riseFall());
|
||
|
|
if (thru) sta_->deleteExceptionThru(thru);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMakeExceptionTo2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ExceptionTo *to = sta_->makeExceptionTo(nullptr, nullptr, nullptr,
|
||
|
|
RiseFallBoth::riseFall(),
|
||
|
|
RiseFallBoth::riseFall());
|
||
|
|
if (to) sta_->deleteExceptionTo(to);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::setLatchBorrowLimit ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetLatchBorrowLimitExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(const Pin*, float)>(&Sta::setLatchBorrowLimit);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::setDriveResistance ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetDriveResistanceExists) {
|
||
|
|
auto fn = &Sta::setDriveResistance;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::setInputSlew ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetInputSlewExists) {
|
||
|
|
auto fn = &Sta::setInputSlew;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::setResistance ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetResistanceExists) {
|
||
|
|
auto fn = &Sta::setResistance;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::setNetWireCap ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetNetWireCapExists) {
|
||
|
|
auto fn = &Sta::setNetWireCap;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::connectedCap ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaConnectedCapPinExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(const Pin*, const RiseFall*, const Corner*, const MinMax*, float&, float&) const>(&Sta::connectedCap);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::portExtCaps ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPortExtCapsExists) {
|
||
|
|
auto fn = &Sta::portExtCaps;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::setOperatingConditions ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetOperatingConditions2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setOperatingConditions(nullptr, MinMaxAll::all());
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::power ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPowerExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(const Corner*, PowerResult&, PowerResult&, PowerResult&, PowerResult&, PowerResult&, PowerResult&)>(&Sta::power);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::readLiberty ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReadLibertyExists) {
|
||
|
|
auto fn = &Sta::readLiberty;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: linkDesign ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaLinkDesignExists) {
|
||
|
|
auto fn = &Sta::linkDesign;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::readVerilog ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReadVerilogExists) {
|
||
|
|
auto fn = &Sta::readVerilog;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::readSpef ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReadSpefExists) {
|
||
|
|
auto fn = &Sta::readSpef;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: initSta and deleteAllMemory ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, InitStaExists) {
|
||
|
|
auto fn = &initSta;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, DeleteAllMemoryExists) {
|
||
|
|
auto fn = &deleteAllMemory;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnd.cc: slack computation on PathEndUnconstrained ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndSlack) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Path *p = new Path();
|
||
|
|
PathEndUnconstrained pe(p);
|
||
|
|
Slack s = pe.slack(sta_);
|
||
|
|
(void)s;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta method exists checks for vertex* functions ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexArrivalMinMaxExists) {
|
||
|
|
auto fn = static_cast<Arrival (Sta::*)(Vertex*, const MinMax*)>(&Sta::vertexArrival);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexRequiredMinMaxExists) {
|
||
|
|
auto fn = static_cast<Required (Sta::*)(Vertex*, const MinMax*)>(&Sta::vertexRequired);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlackMinMaxExists) {
|
||
|
|
auto fn = static_cast<Slack (Sta::*)(Vertex*, const MinMax*)>(&Sta::vertexSlack);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlewMinMaxExists) {
|
||
|
|
auto fn = static_cast<Slew (Sta::*)(Vertex*, const MinMax*)>(&Sta::vertexSlew);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexPathCountExists) {
|
||
|
|
auto fn = &Sta::vertexPathCount;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexWorstArrivalPathExists) {
|
||
|
|
auto fn = static_cast<Path* (Sta::*)(Vertex*, const MinMax*)>(&Sta::vertexWorstArrivalPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexWorstSlackPathExists) {
|
||
|
|
auto fn = static_cast<Path* (Sta::*)(Vertex*, const MinMax*)>(&Sta::vertexWorstSlackPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlacksExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Vertex*, Slack (&)[2][2])>(&Sta::vertexSlacks);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: reporting function exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReportPathEndExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(PathEnd*)>(&Sta::reportPathEnd);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReportPathEndsExists) {
|
||
|
|
auto fn = &Sta::reportPathEnds;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindPathEndsExists) {
|
||
|
|
auto fn = &Sta::findPathEnds;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::makeClockGroups ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMakeClockGroups) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->makeClockGroups("test_grp", false, false, false, false, nullptr);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta.cc: Sta::makeGroupPath ===
|
||
|
|
|
||
|
|
// ============================================================
|
||
|
|
// R5_ tests: Additional function coverage for search module
|
||
|
|
// ============================================================
|
||
|
|
|
||
|
|
// === CheckMaxSkews: constructor/destructor/clear ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CheckMaxSkewsCtorDtorClear) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
CheckMaxSkews checker(sta_);
|
||
|
|
checker.clear();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === CheckMinPeriods: constructor/destructor/clear ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CheckMinPeriodsCtorDtorClear) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
CheckMinPeriods checker(sta_);
|
||
|
|
checker.clear();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === CheckMinPulseWidths: constructor/destructor/clear ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CheckMinPulseWidthsCtorDtorClear) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
CheckMinPulseWidths checker(sta_);
|
||
|
|
checker.clear();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MinPulseWidthCheck: default constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MinPulseWidthCheckDefaultCtor) {
|
||
|
|
MinPulseWidthCheck check;
|
||
|
|
EXPECT_EQ(check.openPath(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MinPulseWidthCheck: constructor with nullptr ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MinPulseWidthCheckNullptrCtor) {
|
||
|
|
MinPulseWidthCheck check(nullptr);
|
||
|
|
EXPECT_EQ(check.openPath(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MinPeriodCheck: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MinPeriodCheckCtor) {
|
||
|
|
MinPeriodCheck check(nullptr, nullptr, nullptr);
|
||
|
|
EXPECT_EQ(check.pin(), nullptr);
|
||
|
|
EXPECT_EQ(check.clk(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MinPeriodCheck: copy ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MinPeriodCheckCopy) {
|
||
|
|
MinPeriodCheck check(nullptr, nullptr, nullptr);
|
||
|
|
MinPeriodCheck *copy = check.copy();
|
||
|
|
EXPECT_NE(copy, nullptr);
|
||
|
|
EXPECT_EQ(copy->pin(), nullptr);
|
||
|
|
EXPECT_EQ(copy->clk(), nullptr);
|
||
|
|
delete copy;
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MaxSkewSlackLess: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MaxSkewSlackLessCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
MaxSkewSlackLess less(sta_);
|
||
|
|
(void)less;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MinPeriodSlackLess: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MinPeriodSlackLessCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
MinPeriodSlackLess less(sta_);
|
||
|
|
(void)less;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MinPulseWidthSlackLess: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MinPulseWidthSlackLessCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
MinPulseWidthSlackLess less(sta_);
|
||
|
|
(void)less;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Path: default constructor and isNull ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathDefaultCtorIsNull) {
|
||
|
|
Path path;
|
||
|
|
EXPECT_TRUE(path.isNull());
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Path: copy from null pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathCopyFromNull) {
|
||
|
|
Path path(static_cast<const Path *>(nullptr));
|
||
|
|
EXPECT_TRUE(path.isNull());
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Path: arrival/required getters on default path ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathArrivalRequired) {
|
||
|
|
Path path;
|
||
|
|
path.setArrival(1.5f);
|
||
|
|
EXPECT_FLOAT_EQ(path.arrival(), 1.5f);
|
||
|
|
path.setRequired(2.5f);
|
||
|
|
EXPECT_FLOAT_EQ(path.required(), 2.5f);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Path: isEnum ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathIsEnum2) {
|
||
|
|
Path path;
|
||
|
|
EXPECT_FALSE(path.isEnum());
|
||
|
|
path.setIsEnum(true);
|
||
|
|
EXPECT_TRUE(path.isEnum());
|
||
|
|
path.setIsEnum(false);
|
||
|
|
EXPECT_FALSE(path.isEnum());
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Path: prevPath on default ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathPrevPathDefault) {
|
||
|
|
Path path;
|
||
|
|
EXPECT_EQ(path.prevPath(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Path: setPrevPath ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathSetPrevPath2) {
|
||
|
|
Path path;
|
||
|
|
Path prev;
|
||
|
|
path.setPrevPath(&prev);
|
||
|
|
EXPECT_EQ(path.prevPath(), &prev);
|
||
|
|
path.setPrevPath(nullptr);
|
||
|
|
EXPECT_EQ(path.prevPath(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathLess: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathLessCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
PathLess less(sta_);
|
||
|
|
(void)less;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkSkew: default constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkSkewDefaultCtor) {
|
||
|
|
ClkSkew skew;
|
||
|
|
EXPECT_EQ(skew.srcPath(), nullptr);
|
||
|
|
EXPECT_EQ(skew.tgtPath(), nullptr);
|
||
|
|
EXPECT_FLOAT_EQ(skew.skew(), 0.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkSkew: copy constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkSkewCopyCtor) {
|
||
|
|
ClkSkew skew1;
|
||
|
|
ClkSkew skew2(skew1);
|
||
|
|
EXPECT_EQ(skew2.srcPath(), nullptr);
|
||
|
|
EXPECT_EQ(skew2.tgtPath(), nullptr);
|
||
|
|
EXPECT_FLOAT_EQ(skew2.skew(), 0.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkSkew: assignment operator ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkSkewAssignment2) {
|
||
|
|
ClkSkew skew1;
|
||
|
|
ClkSkew skew2;
|
||
|
|
skew2 = skew1;
|
||
|
|
EXPECT_EQ(skew2.srcPath(), nullptr);
|
||
|
|
EXPECT_FLOAT_EQ(skew2.skew(), 0.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
// (Protected ReportPath methods removed - only public API tested)
|
||
|
|
|
||
|
|
|
||
|
|
// === ClkInfoLess: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoLessCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ClkInfoLess less(sta_);
|
||
|
|
(void)less;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkInfoEqual: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoEqualCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ClkInfoEqual eq(sta_);
|
||
|
|
(void)eq;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkInfoHash: operator() with nullptr safety check ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoHashExists) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ClkInfoHash hash;
|
||
|
|
(void)hash;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === TagLess: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagLessCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
TagLess less(sta_);
|
||
|
|
(void)less;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === TagIndexLess: existence ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagIndexLessExists) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
TagIndexLess less;
|
||
|
|
(void)less;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === TagHash: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagHashCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
TagHash hash(sta_);
|
||
|
|
(void)hash;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === TagEqual: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagEqualCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
TagEqual eq(sta_);
|
||
|
|
(void)eq;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === TagMatchLess: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagMatchLessCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
TagMatchLess less(true, sta_);
|
||
|
|
(void)less;
|
||
|
|
TagMatchLess less2(false, sta_);
|
||
|
|
(void)less2;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === TagMatchHash: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagMatchHashCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
TagMatchHash hash(true, sta_);
|
||
|
|
(void)hash;
|
||
|
|
TagMatchHash hash2(false, sta_);
|
||
|
|
(void)hash2;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === TagMatchEqual: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagMatchEqualCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
TagMatchEqual eq(true, sta_);
|
||
|
|
(void)eq;
|
||
|
|
TagMatchEqual eq2(false, sta_);
|
||
|
|
(void)eq2;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// (TagGroupBldr/Hash/Equal are incomplete types - skipped)
|
||
|
|
|
||
|
|
|
||
|
|
// === DiversionGreater: constructors ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, DiversionGreaterDefaultCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
DiversionGreater greater;
|
||
|
|
(void)greater;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, DiversionGreaterStaCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
DiversionGreater greater(sta_);
|
||
|
|
(void)greater;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkSkews: constructor and clear ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkSkewsCtorClear) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ClkSkews skews(sta_);
|
||
|
|
skews.clear();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Genclks: constructor, destructor, and clear ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, GenclksCtorDtorClear) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Genclks genclks(sta_);
|
||
|
|
genclks.clear();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClockPinPairLess: operator ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClockPinPairLessExists) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
// ClockPinPairLess comparison dereferences Clock*, so just test existence
|
||
|
|
ClockPinPairLess less;
|
||
|
|
(void)less;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Levelize: setLevelSpace ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, LevelizeSetLevelSpace2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Levelize *levelize = sta_->levelize();
|
||
|
|
levelize->setLevelSpace(5);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Levelize: maxLevel ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, LevelizeMaxLevel2) {
|
||
|
|
Levelize *levelize = sta_->levelize();
|
||
|
|
int ml = levelize->maxLevel();
|
||
|
|
EXPECT_GE(ml, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Levelize: clear ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, LevelizeClear2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Levelize *levelize = sta_->levelize();
|
||
|
|
levelize->clear();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === SearchPred0: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchPred0Ctor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
SearchPred0 pred(sta_);
|
||
|
|
(void)pred;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === SearchPred1: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchPred1Ctor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
SearchPred1 pred(sta_);
|
||
|
|
(void)pred;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === SearchPred2: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchPred2Ctor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
SearchPred2 pred(sta_);
|
||
|
|
(void)pred;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === SearchPredNonLatch2: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchPredNonLatch2Ctor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
SearchPredNonLatch2 pred(sta_);
|
||
|
|
(void)pred;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === SearchPredNonReg2: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchPredNonReg2Ctor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
SearchPredNonReg2 pred(sta_);
|
||
|
|
(void)pred;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkTreeSearchPred: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkTreeSearchPredCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ClkTreeSearchPred pred(sta_);
|
||
|
|
(void)pred;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === FanOutSrchPred: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, FanOutSrchPredCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
FanOutSrchPred pred(sta_);
|
||
|
|
(void)pred;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === WorstSlack: constructor/destructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, WorstSlackCtorDtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
WorstSlack ws(sta_);
|
||
|
|
(void)ws;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === WorstSlack: copy constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, WorstSlackCopyCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
WorstSlack ws1(sta_);
|
||
|
|
WorstSlack ws2(ws1);
|
||
|
|
(void)ws2;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === WorstSlacks: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, WorstSlacksCtorDtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
WorstSlacks wslacks(sta_);
|
||
|
|
(void)wslacks;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sim: clear ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SimClear2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Sim *sim = sta_->sim();
|
||
|
|
sim->clear();
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === StaState: copyUnits ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaStateCopyUnits3) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Units *units = sta_->units();
|
||
|
|
sta_->copyUnits(units);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: default constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueDefaultCtor) {
|
||
|
|
PropertyValue pv;
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_none);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: string constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueStringCtor) {
|
||
|
|
PropertyValue pv("hello");
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_string);
|
||
|
|
EXPECT_STREQ(pv.stringValue(), "hello");
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: float constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueFloatCtor) {
|
||
|
|
PropertyValue pv(3.14f, nullptr);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_float);
|
||
|
|
EXPECT_FLOAT_EQ(pv.floatValue(), 3.14f);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: bool constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueBoolCtor) {
|
||
|
|
PropertyValue pv(true);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_bool);
|
||
|
|
EXPECT_TRUE(pv.boolValue());
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: copy constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueCopyCtor) {
|
||
|
|
PropertyValue pv1("test");
|
||
|
|
PropertyValue pv2(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::type_string);
|
||
|
|
EXPECT_STREQ(pv2.stringValue(), "test");
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: move constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueMoveCtor) {
|
||
|
|
PropertyValue pv1("test");
|
||
|
|
PropertyValue pv2(std::move(pv1));
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::type_string);
|
||
|
|
EXPECT_STREQ(pv2.stringValue(), "test");
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: copy assignment ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueCopyAssign) {
|
||
|
|
PropertyValue pv1("test");
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = pv1;
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::type_string);
|
||
|
|
EXPECT_STREQ(pv2.stringValue(), "test");
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: move assignment ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueMoveAssign) {
|
||
|
|
PropertyValue pv1("test");
|
||
|
|
PropertyValue pv2;
|
||
|
|
pv2 = std::move(pv1);
|
||
|
|
EXPECT_EQ(pv2.type(), PropertyValue::type_string);
|
||
|
|
EXPECT_STREQ(pv2.stringValue(), "test");
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: Library constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueLibraryCtor) {
|
||
|
|
PropertyValue pv(static_cast<const Library *>(nullptr));
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_library);
|
||
|
|
EXPECT_EQ(pv.library(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: Cell constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueCellCtor) {
|
||
|
|
PropertyValue pv(static_cast<const Cell *>(nullptr));
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_cell);
|
||
|
|
EXPECT_EQ(pv.cell(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: Port constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValuePortCtor) {
|
||
|
|
PropertyValue pv(static_cast<const Port *>(nullptr));
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_port);
|
||
|
|
EXPECT_EQ(pv.port(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: LibertyLibrary constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueLibertyLibraryCtor) {
|
||
|
|
PropertyValue pv(static_cast<const LibertyLibrary *>(nullptr));
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_liberty_library);
|
||
|
|
EXPECT_EQ(pv.libertyLibrary(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: LibertyCell constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueLibertyCellCtor) {
|
||
|
|
PropertyValue pv(static_cast<const LibertyCell *>(nullptr));
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_liberty_cell);
|
||
|
|
EXPECT_EQ(pv.libertyCell(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: LibertyPort constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueLibertyPortCtor) {
|
||
|
|
PropertyValue pv(static_cast<const LibertyPort *>(nullptr));
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_liberty_port);
|
||
|
|
EXPECT_EQ(pv.libertyPort(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: Instance constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueInstanceCtor) {
|
||
|
|
PropertyValue pv(static_cast<const Instance *>(nullptr));
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_instance);
|
||
|
|
EXPECT_EQ(pv.instance(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: Pin constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValuePinCtor) {
|
||
|
|
PropertyValue pv(static_cast<const Pin *>(nullptr));
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_pin);
|
||
|
|
EXPECT_EQ(pv.pin(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: Net constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueNetCtor) {
|
||
|
|
PropertyValue pv(static_cast<const Net *>(nullptr));
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_net);
|
||
|
|
EXPECT_EQ(pv.net(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: Clock constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueClockCtor) {
|
||
|
|
PropertyValue pv(static_cast<const Clock *>(nullptr));
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_clk);
|
||
|
|
EXPECT_EQ(pv.clock(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// (Properties protected methods and Sta protected methods skipped)
|
||
|
|
|
||
|
|
|
||
|
|
// === Sta: maxPathCountVertex ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMaxPathCountVertexExists) {
|
||
|
|
// maxPathCountVertex requires search state; just test function pointer
|
||
|
|
auto fn = &Sta::maxPathCountVertex;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: connectPin ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaConnectPinExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Instance*, LibertyPort*, Net*)>(&Sta::connectPin);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: replaceCellExists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReplaceCellExists2) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Instance*, Cell*)>(&Sta::replaceCell);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: disable functions exist ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisableLibertyPortExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(LibertyPort*)>(&Sta::disable);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisableTimingArcSetExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(TimingArcSet*)>(&Sta::disable);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisableEdgeExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Edge*)>(&Sta::disable);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: removeDisable functions exist ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaRemoveDisableLibertyPortExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(LibertyPort*)>(&Sta::removeDisable);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaRemoveDisableTimingArcSetExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(TimingArcSet*)>(&Sta::removeDisable);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaRemoveDisableEdgeExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Edge*)>(&Sta::removeDisable);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: disableClockGatingCheck ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisableClockGatingCheckExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Pin*)>(&Sta::disableClockGatingCheck);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: removeDisableClockGatingCheck ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaRemoveDisableClockGatingCheckExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Pin*)>(&Sta::removeDisableClockGatingCheck);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexArrival overloads exist ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexArrivalMinMaxExists2) {
|
||
|
|
auto fn = static_cast<Arrival (Sta::*)(Vertex*, const MinMax*)>(&Sta::vertexArrival);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexArrivalRfApExists) {
|
||
|
|
auto fn = static_cast<Arrival (Sta::*)(Vertex*, const RiseFall*, const PathAnalysisPt*)>(&Sta::vertexArrival);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexRequired overloads exist ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexRequiredMinMaxExists2) {
|
||
|
|
auto fn = static_cast<Required (Sta::*)(Vertex*, const MinMax*)>(&Sta::vertexRequired);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexRequiredRfApExists) {
|
||
|
|
auto fn = static_cast<Required (Sta::*)(Vertex*, const RiseFall*, const PathAnalysisPt*)>(&Sta::vertexRequired);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexRequiredRfMinMaxExists) {
|
||
|
|
auto fn = static_cast<Required (Sta::*)(Vertex*, const RiseFall*, const MinMax*)>(&Sta::vertexRequired);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexSlack overload exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlackRfApExists) {
|
||
|
|
auto fn = static_cast<Slack (Sta::*)(Vertex*, const RiseFall*, const PathAnalysisPt*)>(&Sta::vertexSlack);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexSlew overloads exist ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlewDcalcExists) {
|
||
|
|
auto fn = static_cast<Slew (Sta::*)(Vertex*, const RiseFall*, const DcalcAnalysisPt*)>(&Sta::vertexSlew);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlewCornerMinMaxExists) {
|
||
|
|
auto fn = static_cast<Slew (Sta::*)(Vertex*, const RiseFall*, const Corner*, const MinMax*)>(&Sta::vertexSlew);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexPathIterator exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexPathIteratorExists) {
|
||
|
|
auto fn = static_cast<VertexPathIterator* (Sta::*)(Vertex*, const RiseFall*, const PathAnalysisPt*)>(&Sta::vertexPathIterator);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexWorstRequiredPath overloads ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexWorstRequiredPathMinMaxExists) {
|
||
|
|
auto fn = static_cast<Path* (Sta::*)(Vertex*, const MinMax*)>(&Sta::vertexWorstRequiredPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexWorstRequiredPathRfMinMaxExists) {
|
||
|
|
auto fn = static_cast<Path* (Sta::*)(Vertex*, const RiseFall*, const MinMax*)>(&Sta::vertexWorstRequiredPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkCapacitance exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckCapacitanceExists) {
|
||
|
|
auto fn = &Sta::checkCapacitance;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkSlew exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckSlewExists) {
|
||
|
|
auto fn = &Sta::checkSlew;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkFanout exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckFanoutExists) {
|
||
|
|
auto fn = &Sta::checkFanout;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: findSlewLimit exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindSlewLimitExists) {
|
||
|
|
auto fn = &Sta::findSlewLimit;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: reportCheck exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReportCheckMaxSkewExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(MaxSkewCheck*, bool)>(&Sta::reportCheck);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: pinsForClock exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPinsExists) {
|
||
|
|
auto fn = static_cast<const PinSet* (Sta::*)(const Clock*)>(&Sta::pins);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: removeDataCheck exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaRemoveDataCheckExists) {
|
||
|
|
auto fn = &Sta::removeDataCheck;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: makePortPinAfter exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMakePortPinAfterExists) {
|
||
|
|
auto fn = &Sta::makePortPinAfter;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: setArcDelayAnnotated exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetArcDelayAnnotatedExists) {
|
||
|
|
auto fn = &Sta::setArcDelayAnnotated;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: delaysInvalidFromFanin exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDelaysInvalidFromFaninExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(const Pin*)>(&Sta::delaysInvalidFromFanin);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: makeParasiticNetwork exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMakeParasiticNetworkExists) {
|
||
|
|
auto fn = &Sta::makeParasiticNetwork;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: pathAnalysisPt exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPathAnalysisPtExists) {
|
||
|
|
auto fn = static_cast<PathAnalysisPt* (Sta::*)(Path*)>(&Sta::pathAnalysisPt);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: pathDcalcAnalysisPt exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPathDcalcAnalysisPtExists) {
|
||
|
|
auto fn = &Sta::pathDcalcAnalysisPt;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: pvt exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPvtExists) {
|
||
|
|
auto fn = &Sta::pvt;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: setPvt exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetPvtExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Instance*, const MinMaxAll*, float, float, float)>(&Sta::setPvt);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: arrivalsValid ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchArrivalsValid) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
bool valid = search->arrivalsValid();
|
||
|
|
(void)valid;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sim: findLogicConstants ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SimFindLogicConstantsExists) {
|
||
|
|
// findLogicConstants requires graph; just test function pointer
|
||
|
|
auto fn = &Sim::findLogicConstants;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportField: getters ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportFieldGetters) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *field = rpt->fieldSlew();
|
||
|
|
EXPECT_NE(field, nullptr);
|
||
|
|
EXPECT_NE(field->name(), nullptr);
|
||
|
|
EXPECT_NE(field->title(), nullptr);
|
||
|
|
EXPECT_GT(field->width(), 0);
|
||
|
|
EXPECT_NE(field->blank(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportField: setWidth ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportFieldSetWidth2) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *field = rpt->fieldFanout();
|
||
|
|
int orig = field->width();
|
||
|
|
field->setWidth(20);
|
||
|
|
EXPECT_EQ(field->width(), 20);
|
||
|
|
field->setWidth(orig);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportField: setEnabled ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportFieldSetEnabled2) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *field = rpt->fieldCapacitance();
|
||
|
|
bool orig = field->enabled();
|
||
|
|
field->setEnabled(!orig);
|
||
|
|
EXPECT_EQ(field->enabled(), !orig);
|
||
|
|
field->setEnabled(orig);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportField: leftJustify ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportFieldLeftJustify) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *field = rpt->fieldSlew();
|
||
|
|
bool lj = field->leftJustify();
|
||
|
|
(void)lj;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportField: unit ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportFieldUnit) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *field = rpt->fieldSlew();
|
||
|
|
Unit *u = field->unit();
|
||
|
|
(void)u;
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Corner: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CornerCtor) {
|
||
|
|
Corner corner("test_corner", 0);
|
||
|
|
EXPECT_STREQ(corner.name(), "test_corner");
|
||
|
|
EXPECT_EQ(corner.index(), 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Corners: count ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CornersCount) {
|
||
|
|
Corners *corners = sta_->corners();
|
||
|
|
EXPECT_GE(corners->count(), 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Path static: less with null paths ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathStaticLessNull) {
|
||
|
|
Path p1;
|
||
|
|
Path p2;
|
||
|
|
// Both null - less should be false
|
||
|
|
bool result = Path::less(&p1, &p2, sta_);
|
||
|
|
EXPECT_FALSE(result);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Path static: lessAll with null paths ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathStaticLessAllNull) {
|
||
|
|
Path p1;
|
||
|
|
Path p2;
|
||
|
|
bool result = Path::lessAll(&p1, &p2, sta_);
|
||
|
|
EXPECT_FALSE(result);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Path static: equal with null paths ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathStaticEqualNull) {
|
||
|
|
Path p1;
|
||
|
|
Path p2;
|
||
|
|
bool result = Path::equal(&p1, &p2, sta_);
|
||
|
|
EXPECT_TRUE(result);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: isClockNet returns false with no design ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaIsClockNetExists2) {
|
||
|
|
// isClock(Net*) dereferences the pointer; just test function pointer
|
||
|
|
auto fn = static_cast<bool (Sta::*)(const Net*) const>(&Sta::isClock);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: PinSeq constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValuePinSeqCtor) {
|
||
|
|
PinSeq *pins = new PinSeq;
|
||
|
|
PropertyValue pv(pins);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_pins);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: ClockSeq constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueClockSeqCtor) {
|
||
|
|
ClockSeq *clks = new ClockSeq;
|
||
|
|
PropertyValue pv(clks);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_clks);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: tagGroup returns nullptr for invalid index ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchTagGroupExists) {
|
||
|
|
auto fn = static_cast<TagGroup* (Search::*)(int) const>(&Search::tagGroup);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkNetwork: pinsForClock and clocks exist ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkNetworkPinsExists) {
|
||
|
|
auto fn = static_cast<const PinSet* (ClkNetwork::*)(const Clock*)>(&ClkNetwork::pins);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkNetworkClocksExists) {
|
||
|
|
auto fn = static_cast<const ClockSet* (ClkNetwork::*)(const Pin*)>(&ClkNetwork::clocks);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkNetworkIsClockExists) {
|
||
|
|
auto fn = static_cast<bool (ClkNetwork::*)(const Net*) const>(&ClkNetwork::isClock);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnd: type enum values ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndTypeEnums2) {
|
||
|
|
EXPECT_EQ(PathEnd::unconstrained, 0);
|
||
|
|
EXPECT_EQ(PathEnd::check, 1);
|
||
|
|
EXPECT_EQ(PathEnd::data_check, 2);
|
||
|
|
EXPECT_EQ(PathEnd::latch_check, 3);
|
||
|
|
EXPECT_EQ(PathEnd::output_delay, 4);
|
||
|
|
EXPECT_EQ(PathEnd::gated_clk, 5);
|
||
|
|
EXPECT_EQ(PathEnd::path_delay, 6);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnd: less function exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndLessFnExists) {
|
||
|
|
auto fn = &PathEnd::less;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnd: cmpNoCrpr function exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndCmpNoCrprFnExists) {
|
||
|
|
auto fn = &PathEnd::cmpNoCrpr;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPathFormat enum ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathFormatEnums) {
|
||
|
|
EXPECT_NE(ReportPathFormat::full, ReportPathFormat::json);
|
||
|
|
EXPECT_NE(ReportPathFormat::full_clock, ReportPathFormat::endpoint);
|
||
|
|
EXPECT_NE(ReportPathFormat::summary, ReportPathFormat::slack_only);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === SearchClass constants ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchClassConstants2) {
|
||
|
|
EXPECT_GT(tag_index_bit_count, 0u);
|
||
|
|
EXPECT_EQ(tag_index_null, tag_index_max);
|
||
|
|
EXPECT_GT(path_ap_index_bit_count, 0);
|
||
|
|
EXPECT_GT(corner_count_max, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: setReportFields (public) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathSetReportFields2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->setReportFields(true, true, true, true, true, true, true);
|
||
|
|
rpt->setReportFields(false, false, false, false, false, false, false);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MaxSkewCheck: skew with empty paths ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MaxSkewCheckSkewZero) {
|
||
|
|
Path clk_path;
|
||
|
|
Path ref_path;
|
||
|
|
clk_path.setArrival(0.0f);
|
||
|
|
ref_path.setArrival(0.0f);
|
||
|
|
MaxSkewCheck check(&clk_path, &ref_path, nullptr, nullptr);
|
||
|
|
Delay s = check.skew();
|
||
|
|
EXPECT_FLOAT_EQ(s, 0.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MaxSkewCheck: skew with different arrivals ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MaxSkewCheckSkewNonZero) {
|
||
|
|
Path clk_path;
|
||
|
|
Path ref_path;
|
||
|
|
clk_path.setArrival(5.0f);
|
||
|
|
ref_path.setArrival(3.0f);
|
||
|
|
MaxSkewCheck check(&clk_path, &ref_path, nullptr, nullptr);
|
||
|
|
Delay s = check.skew();
|
||
|
|
EXPECT_FLOAT_EQ(s, 2.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MaxSkewCheck: clkPath and refPath ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MaxSkewCheckPaths) {
|
||
|
|
Path clk_path;
|
||
|
|
Path ref_path;
|
||
|
|
MaxSkewCheck check(&clk_path, &ref_path, nullptr, nullptr);
|
||
|
|
EXPECT_EQ(check.clkPath(), &clk_path);
|
||
|
|
EXPECT_EQ(check.refPath(), &ref_path);
|
||
|
|
EXPECT_EQ(check.checkArc(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkSkew: srcTgtPathNameLess exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkSkewSrcTgtPathNameLessExists) {
|
||
|
|
auto fn = &ClkSkew::srcTgtPathNameLess;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkSkew: srcInternalClkLatency exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkSkewSrcInternalClkLatencyExists) {
|
||
|
|
auto fn = &ClkSkew::srcInternalClkLatency;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkSkew: tgtInternalClkLatency exists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkSkewTgtInternalClkLatencyExists) {
|
||
|
|
auto fn = &ClkSkew::tgtInternalClkLatency;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: setReportFieldOrder ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathSetReportFieldOrderExists) {
|
||
|
|
// setReportFieldOrder(nullptr) segfaults; just test function pointer
|
||
|
|
auto fn = &ReportPath::setReportFieldOrder;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: findField ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathFindFieldByName) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *slew = rpt->findField("slew");
|
||
|
|
EXPECT_NE(slew, nullptr);
|
||
|
|
ReportField *fanout = rpt->findField("fanout");
|
||
|
|
EXPECT_NE(fanout, nullptr);
|
||
|
|
ReportField *cap = rpt->findField("capacitance");
|
||
|
|
EXPECT_NE(cap, nullptr);
|
||
|
|
// Non-existent field
|
||
|
|
ReportField *nonexist = rpt->findField("nonexistent_field");
|
||
|
|
EXPECT_EQ(nonexist, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PropertyValue: std::string constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PropertyValueStdStringCtor) {
|
||
|
|
std::string s = "test_string";
|
||
|
|
PropertyValue pv(s);
|
||
|
|
EXPECT_EQ(pv.type(), PropertyValue::type_string);
|
||
|
|
EXPECT_STREQ(pv.stringValue(), "test_string");
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Levelize: invalid ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, LevelizeInvalid) {
|
||
|
|
Levelize *levelize = sta_->levelize();
|
||
|
|
levelize->invalid();
|
||
|
|
EXPECT_FALSE(levelize->levelized());
|
||
|
|
}
|
||
|
|
|
||
|
|
// === R5_ Round 2: Re-add public ReportPath methods that were accidentally removed ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathDigits) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
int d = rpt->digits();
|
||
|
|
EXPECT_GE(d, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathSetDigits) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->setDigits(5);
|
||
|
|
EXPECT_EQ(rpt->digits(), 5);
|
||
|
|
rpt->setDigits(3); // restore default
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportSigmas2) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
bool sigmas = rpt->reportSigmas();
|
||
|
|
// Default should be false
|
||
|
|
EXPECT_FALSE(sigmas);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathSetReportSigmas) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->setReportSigmas(true);
|
||
|
|
EXPECT_TRUE(rpt->reportSigmas());
|
||
|
|
rpt->setReportSigmas(false);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathPathFormat) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportPathFormat fmt = rpt->pathFormat();
|
||
|
|
// Check it is a valid format
|
||
|
|
EXPECT_TRUE(fmt == ReportPathFormat::full
|
||
|
|
|| fmt == ReportPathFormat::full_clock
|
||
|
|
|| fmt == ReportPathFormat::full_clock_expanded
|
||
|
|
|| fmt == ReportPathFormat::summary
|
||
|
|
|| fmt == ReportPathFormat::slack_only
|
||
|
|
|| fmt == ReportPathFormat::endpoint
|
||
|
|
|| fmt == ReportPathFormat::json);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathSetPathFormat) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportPathFormat old_fmt = rpt->pathFormat();
|
||
|
|
rpt->setPathFormat(ReportPathFormat::summary);
|
||
|
|
EXPECT_EQ(rpt->pathFormat(), ReportPathFormat::summary);
|
||
|
|
rpt->setPathFormat(old_fmt);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathFindFieldSlew) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *slew = rpt->findField("slew");
|
||
|
|
EXPECT_NE(slew, nullptr);
|
||
|
|
EXPECT_STREQ(slew->name(), "slew");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathFindFieldFanout) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *fo = rpt->findField("fanout");
|
||
|
|
EXPECT_NE(fo, nullptr);
|
||
|
|
EXPECT_STREQ(fo->name(), "fanout");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathFindFieldCapacitance) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *cap = rpt->findField("capacitance");
|
||
|
|
EXPECT_NE(cap, nullptr);
|
||
|
|
EXPECT_STREQ(cap->name(), "capacitance");
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathFindFieldNonexistent) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *f = rpt->findField("nonexistent_field_xyz");
|
||
|
|
EXPECT_EQ(f, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathSetNoSplit) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->setNoSplit(true);
|
||
|
|
rpt->setNoSplit(false);
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathFieldSrcAttr) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *src = rpt->fieldSrcAttr();
|
||
|
|
// src_attr field may or may not exist
|
||
|
|
(void)src;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathSetReportFieldsPublic) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
// Call setReportFields with various combinations
|
||
|
|
rpt->setReportFields(true, false, false, false, true, false, false);
|
||
|
|
rpt->setReportFields(true, true, true, true, true, true, true);
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: header methods (public) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportJsonHeaderExists) {
|
||
|
|
auto fn = &ReportPath::reportJsonHeader;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportPeriodHeaderShortExists) {
|
||
|
|
auto fn = &ReportPath::reportPeriodHeaderShort;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportMaxSkewHeaderShortExists) {
|
||
|
|
auto fn = &ReportPath::reportMaxSkewHeaderShort;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportMpwHeaderShortExists) {
|
||
|
|
auto fn = &ReportPath::reportMpwHeaderShort;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: report method function pointers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportPathEndHeaderExists) {
|
||
|
|
auto fn = &ReportPath::reportPathEndHeader;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportPathEndFooterExists) {
|
||
|
|
auto fn = &ReportPath::reportPathEndFooter;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportEndHeaderExists) {
|
||
|
|
auto fn = &ReportPath::reportEndHeader;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportSummaryHeaderExists) {
|
||
|
|
auto fn = &ReportPath::reportSummaryHeader;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportSlackOnlyHeaderExists) {
|
||
|
|
auto fn = &ReportPath::reportSlackOnlyHeader;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportJsonFooterExists) {
|
||
|
|
auto fn = &ReportPath::reportJsonFooter;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportCheck overloads ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportCheckMinPeriodExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const MinPeriodCheck*, bool) const>(
|
||
|
|
&ReportPath::reportCheck);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportCheckMaxSkewExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const MaxSkewCheck*, bool) const>(
|
||
|
|
&ReportPath::reportCheck);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportChecksMinPeriodExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const MinPeriodCheckSeq*, bool) const>(
|
||
|
|
&ReportPath::reportChecks);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportChecksMaxSkewExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const MaxSkewCheckSeq*, bool) const>(
|
||
|
|
&ReportPath::reportChecks);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportMpwCheckExists) {
|
||
|
|
auto fn = &ReportPath::reportMpwCheck;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportMpwChecksExists) {
|
||
|
|
auto fn = &ReportPath::reportMpwChecks;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: report short/full/json overloads ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportShortMaxSkewCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const MaxSkewCheck*) const>(
|
||
|
|
&ReportPath::reportShort);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportVerboseMaxSkewCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const MaxSkewCheck*) const>(
|
||
|
|
&ReportPath::reportVerbose);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportShortMinPeriodCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const MinPeriodCheck*) const>(
|
||
|
|
&ReportPath::reportShort);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportVerboseMinPeriodCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const MinPeriodCheck*) const>(
|
||
|
|
&ReportPath::reportVerbose);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportShortMinPulseWidthCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const MinPulseWidthCheck*) const>(
|
||
|
|
&ReportPath::reportShort);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportVerboseMinPulseWidthCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const MinPulseWidthCheck*) const>(
|
||
|
|
&ReportPath::reportVerbose);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportLimitShortHeaderExists) {
|
||
|
|
auto fn = &ReportPath::reportLimitShortHeader;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportLimitShortExists) {
|
||
|
|
auto fn = &ReportPath::reportLimitShort;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportLimitVerboseExists) {
|
||
|
|
auto fn = &ReportPath::reportLimitVerbose;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: report short for PathEnd types ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportShortCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndCheck*) const>(
|
||
|
|
&ReportPath::reportShort);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportShortLatchCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndLatchCheck*) const>(
|
||
|
|
&ReportPath::reportShort);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportShortPathDelayExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndPathDelay*) const>(
|
||
|
|
&ReportPath::reportShort);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportShortOutputDelayExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndOutputDelay*) const>(
|
||
|
|
&ReportPath::reportShort);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportShortGatedClockExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndGatedClock*) const>(
|
||
|
|
&ReportPath::reportShort);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportShortDataCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndDataCheck*) const>(
|
||
|
|
&ReportPath::reportShort);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportShortUnconstrainedExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndUnconstrained*) const>(
|
||
|
|
&ReportPath::reportShort);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportFull for PathEnd types ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportFullCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndCheck*) const>(
|
||
|
|
&ReportPath::reportFull);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportFullLatchCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndLatchCheck*) const>(
|
||
|
|
&ReportPath::reportFull);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportFullPathDelayExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndPathDelay*) const>(
|
||
|
|
&ReportPath::reportFull);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportFullOutputDelayExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndOutputDelay*) const>(
|
||
|
|
&ReportPath::reportFull);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportFullGatedClockExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndGatedClock*) const>(
|
||
|
|
&ReportPath::reportFull);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportFullDataCheckExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndDataCheck*) const>(
|
||
|
|
&ReportPath::reportFull);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportFullUnconstrainedExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEndUnconstrained*) const>(
|
||
|
|
&ReportPath::reportFull);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportField: blank getter ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportFieldBlank2) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *field = rpt->fieldSlew();
|
||
|
|
const char *blank = field->blank();
|
||
|
|
EXPECT_NE(blank, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportField: setProperties ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportFieldSetProperties2) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *field = rpt->fieldSlew();
|
||
|
|
int old_width = field->width();
|
||
|
|
bool old_justify = field->leftJustify();
|
||
|
|
// set new properties
|
||
|
|
field->setProperties("NewTitle", 15, true);
|
||
|
|
EXPECT_EQ(field->width(), 15);
|
||
|
|
EXPECT_TRUE(field->leftJustify());
|
||
|
|
// restore
|
||
|
|
field->setProperties("Slew", old_width, old_justify);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === CheckCapacitanceLimits: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CheckCapacitanceLimitsCtorDtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
CheckCapacitanceLimits checker(sta_);
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === CheckSlewLimits: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CheckSlewLimitsCtorDtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
CheckSlewLimits checker(sta_);
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === CheckFanoutLimits: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CheckFanoutLimitsCtorDtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
CheckFanoutLimits checker(sta_);
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathExpanded: empty constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathExpandedEmptyCtor) {
|
||
|
|
PathExpanded expanded(sta_);
|
||
|
|
EXPECT_EQ(expanded.size(), static_cast<size_t>(0));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathGroups: static group names ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupsAsyncGroupName) {
|
||
|
|
const char *name = PathGroups::asyncPathGroupName();
|
||
|
|
EXPECT_NE(name, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupsPathDelayGroupName) {
|
||
|
|
const char *name = PathGroups::pathDelayGroupName();
|
||
|
|
EXPECT_NE(name, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupsGatedClkGroupName) {
|
||
|
|
const char *name = PathGroups::gatedClkGroupName();
|
||
|
|
EXPECT_NE(name, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupsUnconstrainedGroupName) {
|
||
|
|
const char *name = PathGroups::unconstrainedGroupName();
|
||
|
|
EXPECT_NE(name, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathGroup: static max path count ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupMaxPathCountMax) {
|
||
|
|
EXPECT_GT(PathGroup::group_path_count_max, static_cast<size_t>(0));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathGroup: makePathGroupSlack factory ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupMakeSlack2) {
|
||
|
|
PathGroup *pg = PathGroup::makePathGroupSlack(
|
||
|
|
"test_slack", 10, 1, false, false, -1e30, 1e30, sta_);
|
||
|
|
EXPECT_NE(pg, nullptr);
|
||
|
|
EXPECT_STREQ(pg->name(), "test_slack");
|
||
|
|
EXPECT_EQ(pg->maxPaths(), 10);
|
||
|
|
delete pg;
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathGroup: makePathGroupArrival factory ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupMakeArrival2) {
|
||
|
|
PathGroup *pg = PathGroup::makePathGroupArrival(
|
||
|
|
"test_arrival", 5, 1, false, false, MinMax::max(), sta_);
|
||
|
|
EXPECT_NE(pg, nullptr);
|
||
|
|
EXPECT_STREQ(pg->name(), "test_arrival");
|
||
|
|
delete pg;
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathGroup: clear and pathEnds ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupClear) {
|
||
|
|
PathGroup *pg = PathGroup::makePathGroupSlack(
|
||
|
|
"test_clear", 10, 1, false, false, -1e30, 1e30, sta_);
|
||
|
|
const PathEndSeq &ends = pg->pathEnds();
|
||
|
|
EXPECT_EQ(ends.size(), static_cast<size_t>(0));
|
||
|
|
pg->clear();
|
||
|
|
EXPECT_EQ(pg->pathEnds().size(), static_cast<size_t>(0));
|
||
|
|
delete pg;
|
||
|
|
}
|
||
|
|
|
||
|
|
// === CheckCrpr: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CheckCrprCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
CheckCrpr crpr(sta_);
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === GatedClk: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, GatedClkCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
GatedClk gclk(sta_);
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkLatency: constructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkLatencyCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ClkLatency lat(sta_);
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta function pointers: more uncovered methods ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlacksExists2) {
|
||
|
|
auto fn = &Sta::vertexSlacks;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReportCheckMaxSkewBoolExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(MaxSkewCheck*, bool)>(&Sta::reportCheck);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// (Removed duplicates of R5_StaCheckSlewExists, R5_StaCheckCapacitanceExists,
|
||
|
|
// R5_StaCheckFanoutExists, R5_StaFindSlewLimitExists, R5_StaVertexSlewDcalcExists,
|
||
|
|
// R5_StaVertexSlewCornerMinMaxExists - already defined above)
|
||
|
|
|
||
|
|
// === Path: more static methods ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEqualBothNull) {
|
||
|
|
bool eq = Path::equal(nullptr, nullptr, sta_);
|
||
|
|
EXPECT_TRUE(eq);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: more function pointers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchSaveEnumPathExists) {
|
||
|
|
auto fn = &Search::saveEnumPath;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchVisitEndpointsExists) {
|
||
|
|
auto fn = &Search::visitEndpoints;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchCheckPrevPathsExists) {
|
||
|
|
auto fn = &Search::checkPrevPaths;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchIsGenClkSrcExists) {
|
||
|
|
auto fn = &Search::isGenClkSrc;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Levelize: more methods ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, LevelizeCheckLevelsExists) {
|
||
|
|
auto fn = &Levelize::checkLevels;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, LevelizeLevelized) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Levelize *levelize = sta_->levelize();
|
||
|
|
bool lev = levelize->levelized();
|
||
|
|
(void)lev;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sim: more methods ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SimMakePinAfterExists) {
|
||
|
|
auto fn = &Sim::makePinAfter;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Corners: iteration ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CornersIteration) {
|
||
|
|
Corners *corners = sta_->corners();
|
||
|
|
int count = corners->count();
|
||
|
|
EXPECT_GE(count, 1);
|
||
|
|
Corner *corner = corners->findCorner(0);
|
||
|
|
EXPECT_NE(corner, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CornerFindName) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Corners *corners = sta_->corners();
|
||
|
|
Corner *corner = corners->findCorner("default");
|
||
|
|
(void)corner;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Corner: name and index ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CornerNameAndIndex) {
|
||
|
|
Corners *corners = sta_->corners();
|
||
|
|
Corner *corner = corners->findCorner(0);
|
||
|
|
EXPECT_NE(corner, nullptr);
|
||
|
|
const char *name = corner->name();
|
||
|
|
EXPECT_NE(name, nullptr);
|
||
|
|
int idx = corner->index();
|
||
|
|
EXPECT_EQ(idx, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnd: function pointer existence for virtual methods ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndTransitionExists) {
|
||
|
|
auto fn = &PathEnd::transition;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndTargetClkExists) {
|
||
|
|
auto fn = &PathEnd::targetClk;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndTargetClkDelayExists) {
|
||
|
|
auto fn = &PathEnd::targetClkDelay;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndTargetClkArrivalExists) {
|
||
|
|
auto fn = &PathEnd::targetClkArrival;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndTargetClkUncertaintyExists) {
|
||
|
|
auto fn = &PathEnd::targetClkUncertainty;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndInterClkUncertaintyExists) {
|
||
|
|
auto fn = &PathEnd::interClkUncertainty;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndTargetClkMcpAdjustmentExists) {
|
||
|
|
auto fn = &PathEnd::targetClkMcpAdjustment;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndTargetClkInsertionDelayExists) {
|
||
|
|
auto fn = &PathEnd::targetClkInsertionDelay;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndTargetNonInterClkUncertaintyExists) {
|
||
|
|
auto fn = &PathEnd::targetNonInterClkUncertainty;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndPathIndexExists) {
|
||
|
|
auto fn = &PathEnd::pathIndex;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// (Removed duplicates of R5_StaVertexPathIteratorExists, R5_StaPathAnalysisPtExists,
|
||
|
|
// R5_StaPathDcalcAnalysisPtExists - already defined above)
|
||
|
|
|
||
|
|
// === ReportPath: reportPathEnds function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportPathEndsExists) {
|
||
|
|
auto fn = &ReportPath::reportPathEnds;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportPath function pointer (Path*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportPathExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const Path*) const>(&ReportPath::reportPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportEndLine function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportEndLineExists) {
|
||
|
|
auto fn = &ReportPath::reportEndLine;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportSummaryLine function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportSummaryLineExists) {
|
||
|
|
auto fn = &ReportPath::reportSummaryLine;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportSlackOnly function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportSlackOnlyExists) {
|
||
|
|
auto fn = &ReportPath::reportSlackOnly;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportJson overloads ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportJsonPathEndExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEnd*, bool) const>(
|
||
|
|
&ReportPath::reportJson);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportJsonPathExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const Path*) const>(
|
||
|
|
&ReportPath::reportJson);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: pathClkPathArrival function pointers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchPathClkPathArrivalExists) {
|
||
|
|
auto fn = &Search::pathClkPathArrival;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Genclks: more function pointers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, GenclksFindLatchFdbkEdgesExists) {
|
||
|
|
auto fn = static_cast<void (Genclks::*)(const Clock*)>(&Genclks::findLatchFdbkEdges);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// (Removed R5_GenclksGenclkInfoExists - genclkInfo is private)
|
||
|
|
// (Removed R5_GenclksSrcPathExists - srcPath has wrong signature)
|
||
|
|
// (Removed R5_SearchSeedInputArrivalsExists - seedInputArrivals is protected)
|
||
|
|
// (Removed R5_SimClockGateOutValueExists - clockGateOutValue is protected)
|
||
|
|
// (Removed R5_SimPinConstFuncValueExists - pinConstFuncValue is protected)
|
||
|
|
|
||
|
|
// === MinPulseWidthCheck: corner function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MinPulseWidthCheckCornerExists) {
|
||
|
|
auto fn = &MinPulseWidthCheck::corner;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === MaxSkewCheck: more function pointers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MaxSkewCheckClkPinExists) {
|
||
|
|
auto fn = &MaxSkewCheck::clkPin;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MaxSkewCheckRefPinExists) {
|
||
|
|
auto fn = &MaxSkewCheck::refPin;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MaxSkewCheckMaxSkewMethodExists) {
|
||
|
|
auto fn = &MaxSkewCheck::maxSkew;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, MaxSkewCheckSlackExists) {
|
||
|
|
auto fn = &MaxSkewCheck::slack;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkInfo: more function pointers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoCrprClkPathRawExists) {
|
||
|
|
auto fn = &ClkInfo::crprClkPathRaw;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoIsPropagatedExists2) {
|
||
|
|
auto fn = &ClkInfo::isPropagated;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoIsGenClkSrcPathExists2) {
|
||
|
|
auto fn = &ClkInfo::isGenClkSrcPath;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoClkEdgeExists) {
|
||
|
|
auto fn = &ClkInfo::clkEdge;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Tag: more function pointers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagPathAPIndexExists2) {
|
||
|
|
auto fn = &Tag::pathAPIndex;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagClkSrcExists) {
|
||
|
|
auto fn = &Tag::clkSrc;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagSetStatesExists) {
|
||
|
|
auto fn = &Tag::setStates;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// (Removed R5_TagStateEqualExists - stateEqual is protected)
|
||
|
|
|
||
|
|
// === Path: more function pointers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathPrevVertexExists2) {
|
||
|
|
auto fn = &Path::prevVertex;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathCheckPrevPathExists2) {
|
||
|
|
auto fn = &Path::checkPrevPath;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathTagIndexExists2) {
|
||
|
|
auto fn = &Path::tagIndex;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnd: reportShort virtual function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndReportShortExists) {
|
||
|
|
auto fn = &PathEnd::reportShort;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportPathEnd overloads ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportPathEndSingleExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEnd*) const>(
|
||
|
|
&ReportPath::reportPathEnd);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportPathEndPrevExists) {
|
||
|
|
auto fn = static_cast<void (ReportPath::*)(const PathEnd*, const PathEnd*, bool) const>(
|
||
|
|
&ReportPath::reportPathEnd);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// (Removed duplicates of R5_StaVertexArrivalMinMaxExists etc - already defined above)
|
||
|
|
|
||
|
|
// === Corner: DcalcAnalysisPt access ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CornerDcalcAnalysisPt) {
|
||
|
|
Corners *corners = sta_->corners();
|
||
|
|
Corner *corner = corners->findCorner(0);
|
||
|
|
EXPECT_NE(corner, nullptr);
|
||
|
|
DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(MinMax::max());
|
||
|
|
EXPECT_NE(dcalc_ap, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathAnalysisPt access through Corners ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CornersPathAnalysisPtCount2) {
|
||
|
|
Corners *corners = sta_->corners();
|
||
|
|
int count = corners->pathAnalysisPtCount();
|
||
|
|
EXPECT_GT(count, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CornersDcalcAnalysisPtCount2) {
|
||
|
|
Corners *corners = sta_->corners();
|
||
|
|
int count = corners->dcalcAnalysisPtCount();
|
||
|
|
EXPECT_GT(count, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: isClock(Pin*) function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaIsClockPinExists2) {
|
||
|
|
auto fn = static_cast<bool (Sta::*)(const Pin*) const>(&Sta::isClock);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === GraphLoop: report function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, GraphLoopReportExists) {
|
||
|
|
auto fn = &GraphLoop::report;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === SearchPredNonReg2: searchThru function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchPredNonReg2SearchThruExists) {
|
||
|
|
auto fn = &SearchPredNonReg2::searchThru;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === CheckCrpr: maxCrpr function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CheckCrprMaxCrprExists) {
|
||
|
|
auto fn = &CheckCrpr::maxCrpr;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === CheckCrpr: checkCrpr function pointers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CheckCrprCheckCrpr2ArgExists) {
|
||
|
|
auto fn = static_cast<Crpr (CheckCrpr::*)(const Path*, const Path*)>(
|
||
|
|
&CheckCrpr::checkCrpr);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === GatedClk: isGatedClkEnable function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, GatedClkIsGatedClkEnableExists) {
|
||
|
|
auto fn = static_cast<bool (GatedClk::*)(Vertex*) const>(
|
||
|
|
&GatedClk::isGatedClkEnable);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === GatedClk: gatedClkActiveTrans function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, GatedClkGatedClkActiveTransExists) {
|
||
|
|
auto fn = &GatedClk::gatedClkActiveTrans;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === FindRegister: free functions ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, FindRegInstancesExists) {
|
||
|
|
auto fn = &findRegInstances;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, FindRegDataPinsExists) {
|
||
|
|
auto fn = &findRegDataPins;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, FindRegClkPinsExists) {
|
||
|
|
auto fn = &findRegClkPins;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, FindRegAsyncPinsExists) {
|
||
|
|
auto fn = &findRegAsyncPins;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, FindRegOutputPinsExists) {
|
||
|
|
auto fn = &findRegOutputPins;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, InitPathSenseThruExists) {
|
||
|
|
auto fn = &initPathSenseThru;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
// R6_ tests: additional coverage for uncovered search functions
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
// === OutputDelays: constructor and timingSense ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, OutputDelaysCtorAndTimingSense) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
OutputDelays od;
|
||
|
|
TimingSense sense = od.timingSense();
|
||
|
|
(void)sense;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkDelays: constructor and latency ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkDelaysDefaultCtor) {
|
||
|
|
ClkDelays cd;
|
||
|
|
// Test default-constructed ClkDelays latency accessor
|
||
|
|
Delay delay_val;
|
||
|
|
bool exists = false;
|
||
|
|
cd.latency(RiseFall::rise(), RiseFall::rise(), MinMax::max(),
|
||
|
|
delay_val, exists);
|
||
|
|
// Default constructed should have exists=false
|
||
|
|
EXPECT_FALSE(exists);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkDelaysLatencyStatic) {
|
||
|
|
// Static latency with null path
|
||
|
|
auto fn = static_cast<Delay (*)(Path*, StaState*)>(&ClkDelays::latency);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Bdd: constructor and destructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, BddCtorDtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Bdd bdd(sta_);
|
||
|
|
// Just constructing and destructing exercises the vtable
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, BddNodePortExists) {
|
||
|
|
auto fn = &Bdd::nodePort;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathExpanded: constructor with two args (Path*, bool, StaState*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathExpandedStaOnlyCtor) {
|
||
|
|
PathExpanded expanded(sta_);
|
||
|
|
EXPECT_EQ(expanded.size(), 0u);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: visitEndpoints ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchVisitEndpointsExists2) {
|
||
|
|
auto fn = &Search::visitEndpoints;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// havePendingLatchOutputs and clearPendingLatchOutputs are protected, skipped
|
||
|
|
|
||
|
|
// === Search: findPathGroup by name ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchFindPathGroupByName) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
PathGroup *grp = search->findPathGroup("nonexistent", MinMax::max());
|
||
|
|
EXPECT_EQ(grp, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: findPathGroup by clock ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchFindPathGroupByClock) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
PathGroup *grp = search->findPathGroup(static_cast<const Clock*>(nullptr),
|
||
|
|
MinMax::max());
|
||
|
|
EXPECT_EQ(grp, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: tag ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchTagZero) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
// tagCount should be 0 initially
|
||
|
|
TagIndex count = search->tagCount();
|
||
|
|
(void)count;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: tagGroupCount ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchTagGroupCount3) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
TagGroupIndex count = search->tagGroupCount();
|
||
|
|
(void)count;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: clkInfoCount ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchClkInfoCount3) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
int count = search->clkInfoCount();
|
||
|
|
EXPECT_EQ(count, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: initVars (called indirectly through clear) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchClear3) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
search->clear();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: checkPrevPaths ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchCheckPrevPathsExists2) {
|
||
|
|
auto fn = &Search::checkPrevPaths;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: arrivalsValid ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchArrivalsValid2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
bool valid = search->arrivalsValid();
|
||
|
|
(void)valid;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Search::endpoints segfaults without graph - skipped
|
||
|
|
|
||
|
|
// === Search: havePathGroups ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchHavePathGroups3) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
bool have = search->havePathGroups();
|
||
|
|
EXPECT_FALSE(have);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: requiredsSeeded ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchRequiredsSeeded2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
bool seeded = search->requiredsSeeded();
|
||
|
|
EXPECT_FALSE(seeded);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: requiredsExist ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchRequiredsExist2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
bool exist = search->requiredsExist();
|
||
|
|
EXPECT_FALSE(exist);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: arrivalsAtEndpointsExist ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchArrivalsAtEndpointsExist2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
bool exist = search->arrivalsAtEndpointsExist();
|
||
|
|
EXPECT_FALSE(exist);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: crprPathPruningEnabled / setCrprpathPruningEnabled ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchCrprPathPruning2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
bool enabled = search->crprPathPruningEnabled();
|
||
|
|
search->setCrprpathPruningEnabled(!enabled);
|
||
|
|
EXPECT_NE(search->crprPathPruningEnabled(), enabled);
|
||
|
|
search->setCrprpathPruningEnabled(enabled);
|
||
|
|
EXPECT_EQ(search->crprPathPruningEnabled(), enabled);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: crprApproxMissingRequireds ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchCrprApproxMissingRequireds2) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
bool val = search->crprApproxMissingRequireds();
|
||
|
|
search->setCrprApproxMissingRequireds(!val);
|
||
|
|
EXPECT_NE(search->crprApproxMissingRequireds(), val);
|
||
|
|
search->setCrprApproxMissingRequireds(val);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: unconstrainedPaths ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchUnconstrainedPaths2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
bool unc = search->unconstrainedPaths();
|
||
|
|
(void)unc;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: deletePathGroups ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchDeletePathGroups3) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
search->deletePathGroups();
|
||
|
|
EXPECT_FALSE(search->havePathGroups());
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: deleteFilter ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchDeleteFilter3) {
|
||
|
|
Search *search = sta_->search();
|
||
|
|
search->deleteFilter();
|
||
|
|
EXPECT_EQ(search->filter(), nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: arrivalIterator and requiredIterator ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchArrivalIterator) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
BfsFwdIterator *iter = search->arrivalIterator();
|
||
|
|
(void)iter;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchRequiredIterator) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
BfsBkwdIterator *iter = search->requiredIterator();
|
||
|
|
(void)iter;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: evalPred and searchAdj ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchEvalPred2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
EvalPred *pred = search->evalPred();
|
||
|
|
(void)pred;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchSearchAdj2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
SearchPred *adj = search->searchAdj();
|
||
|
|
(void)adj;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: isClock(Net*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaIsClockNetExists3) {
|
||
|
|
auto fn = static_cast<bool (Sta::*)(const Net*) const>(&Sta::isClock);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: pins(Clock*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPinsOfClockExists) {
|
||
|
|
auto fn = static_cast<const PinSet* (Sta::*)(const Clock*)>(&Sta::pins);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: setCmdNamespace ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetCmdNamespace2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
sta_->setCmdNamespace(CmdNamespace::sdc);
|
||
|
|
sta_->setCmdNamespace(CmdNamespace::sta);
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexArrival(Vertex*, MinMax*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexArrivalMinMaxExists3) {
|
||
|
|
auto fn = static_cast<Arrival (Sta::*)(Vertex*, const MinMax*)>(
|
||
|
|
&Sta::vertexArrival);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexArrival(Vertex*, RiseFall*, PathAnalysisPt*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexArrivalRfApExists2) {
|
||
|
|
auto fn = static_cast<Arrival (Sta::*)(Vertex*, const RiseFall*, const PathAnalysisPt*)>(
|
||
|
|
&Sta::vertexArrival);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexRequired(Vertex*, MinMax*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexRequiredMinMaxExists3) {
|
||
|
|
auto fn = static_cast<Required (Sta::*)(Vertex*, const MinMax*)>(
|
||
|
|
&Sta::vertexRequired);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexRequired(Vertex*, RiseFall*, MinMax*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexRequiredRfMinMaxExists2) {
|
||
|
|
auto fn = static_cast<Required (Sta::*)(Vertex*, const RiseFall*, const MinMax*)>(
|
||
|
|
&Sta::vertexRequired);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexRequired(Vertex*, RiseFall*, PathAnalysisPt*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexRequiredRfApExists2) {
|
||
|
|
auto fn = static_cast<Required (Sta::*)(Vertex*, const RiseFall*, const PathAnalysisPt*)>(
|
||
|
|
&Sta::vertexRequired);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexSlack(Vertex*, RiseFall*, PathAnalysisPt*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlackRfApExists2) {
|
||
|
|
auto fn = static_cast<Slack (Sta::*)(Vertex*, const RiseFall*, const PathAnalysisPt*)>(
|
||
|
|
&Sta::vertexSlack);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexSlacks(Vertex*, array) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlacksExists3) {
|
||
|
|
auto fn = &Sta::vertexSlacks;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexSlew(Vertex*, RiseFall*, Corner*, MinMax*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlewCornerExists) {
|
||
|
|
auto fn = static_cast<Slew (Sta::*)(Vertex*, const RiseFall*, const Corner*, const MinMax*)>(
|
||
|
|
&Sta::vertexSlew);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexSlew(Vertex*, RiseFall*, DcalcAnalysisPt*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlewDcalcApExists) {
|
||
|
|
auto fn = static_cast<Slew (Sta::*)(Vertex*, const RiseFall*, const DcalcAnalysisPt*)>(
|
||
|
|
&Sta::vertexSlew);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexPathIterator(Vertex*, RiseFall*, PathAnalysisPt*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexPathIteratorRfApExists) {
|
||
|
|
auto fn = static_cast<VertexPathIterator* (Sta::*)(Vertex*, const RiseFall*, const PathAnalysisPt*)>(
|
||
|
|
&Sta::vertexPathIterator);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexWorstRequiredPath(Vertex*, MinMax*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexWorstRequiredPathMinMaxExists2) {
|
||
|
|
auto fn = static_cast<Path* (Sta::*)(Vertex*, const MinMax*)>(
|
||
|
|
&Sta::vertexWorstRequiredPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexWorstRequiredPath(Vertex*, RiseFall*, MinMax*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexWorstRequiredPathRfMinMaxExists2) {
|
||
|
|
auto fn = static_cast<Path* (Sta::*)(Vertex*, const RiseFall*, const MinMax*)>(
|
||
|
|
&Sta::vertexWorstRequiredPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: setArcDelayAnnotated ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetArcDelayAnnotatedExists2) {
|
||
|
|
auto fn = &Sta::setArcDelayAnnotated;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: pathAnalysisPt(Path*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPathAnalysisPtExists2) {
|
||
|
|
auto fn = &Sta::pathAnalysisPt;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: pathDcalcAnalysisPt(Path*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPathDcalcAnalysisPtExists2) {
|
||
|
|
auto fn = &Sta::pathDcalcAnalysisPt;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: maxPathCountVertex ===
|
||
|
|
|
||
|
|
// Sta::maxPathCountVertex segfaults without graph - use fn pointer
|
||
|
|
TEST_F(StaInitTest, StaMaxPathCountVertexExists2) {
|
||
|
|
auto fn = &Sta::maxPathCountVertex;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: tagCount, tagGroupCount ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaTagCount3) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
TagIndex count = sta_->tagCount();
|
||
|
|
(void)count;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaTagGroupCount3) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
TagGroupIndex count = sta_->tagGroupCount();
|
||
|
|
(void)count;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: clkInfoCount ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaClkInfoCount3) {
|
||
|
|
int count = sta_->clkInfoCount();
|
||
|
|
EXPECT_EQ(count, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: findDelays ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindDelaysExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)()>(&Sta::findDelays);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: reportCheck(MaxSkewCheck*, bool) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReportCheckMaxSkewExists2) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(MaxSkewCheck*, bool)>(&Sta::reportCheck);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkSlew ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckSlewExists2) {
|
||
|
|
auto fn = &Sta::checkSlew;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: findSlewLimit ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindSlewLimitExists2) {
|
||
|
|
auto fn = &Sta::findSlewLimit;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkFanout ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckFanoutExists2) {
|
||
|
|
auto fn = &Sta::checkFanout;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkCapacitance ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckCapacitanceExists2) {
|
||
|
|
auto fn = &Sta::checkCapacitance;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: pvt ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPvtExists2) {
|
||
|
|
auto fn = &Sta::pvt;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: setPvt ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSetPvtExists2) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Instance*, const MinMaxAll*, float, float, float)>(
|
||
|
|
&Sta::setPvt);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: connectPin ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaConnectPinExists2) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Instance*, LibertyPort*, Net*)>(
|
||
|
|
&Sta::connectPin);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: makePortPinAfter ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMakePortPinAfterExists2) {
|
||
|
|
auto fn = &Sta::makePortPinAfter;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: replaceCellExists ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaReplaceCellExists3) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(Instance*, Cell*)>(&Sta::replaceCell);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: makeParasiticNetwork ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaMakeParasiticNetworkExists2) {
|
||
|
|
auto fn = &Sta::makeParasiticNetwork;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: disable/removeDisable for LibertyPort ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisableLibertyPortExists2) {
|
||
|
|
auto fn_dis = static_cast<void (Sta::*)(LibertyPort*)>(&Sta::disable);
|
||
|
|
auto fn_rem = static_cast<void (Sta::*)(LibertyPort*)>(&Sta::removeDisable);
|
||
|
|
EXPECT_NE(fn_dis, nullptr);
|
||
|
|
EXPECT_NE(fn_rem, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: disable/removeDisable for Edge ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisableEdgeExists2) {
|
||
|
|
auto fn_dis = static_cast<void (Sta::*)(Edge*)>(&Sta::disable);
|
||
|
|
auto fn_rem = static_cast<void (Sta::*)(Edge*)>(&Sta::removeDisable);
|
||
|
|
EXPECT_NE(fn_dis, nullptr);
|
||
|
|
EXPECT_NE(fn_rem, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: disable/removeDisable for TimingArcSet ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisableTimingArcSetExists2) {
|
||
|
|
auto fn_dis = static_cast<void (Sta::*)(TimingArcSet*)>(&Sta::disable);
|
||
|
|
auto fn_rem = static_cast<void (Sta::*)(TimingArcSet*)>(&Sta::removeDisable);
|
||
|
|
EXPECT_NE(fn_dis, nullptr);
|
||
|
|
EXPECT_NE(fn_rem, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: disableClockGatingCheck/removeDisableClockGatingCheck for Pin ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisableClockGatingCheckPinExists) {
|
||
|
|
auto fn_dis = static_cast<void (Sta::*)(Pin*)>(&Sta::disableClockGatingCheck);
|
||
|
|
auto fn_rem = static_cast<void (Sta::*)(Pin*)>(&Sta::removeDisableClockGatingCheck);
|
||
|
|
EXPECT_NE(fn_dis, nullptr);
|
||
|
|
EXPECT_NE(fn_rem, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: removeDataCheck ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaRemoveDataCheckExists2) {
|
||
|
|
auto fn = &Sta::removeDataCheck;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: clockDomains ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaClockDomainsExists) {
|
||
|
|
auto fn = static_cast<ClockSet (Sta::*)(const Pin*)>(&Sta::clockDomains);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportJsonHeader ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportJsonHeader) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
EXPECT_NE(rpt, nullptr);
|
||
|
|
rpt->reportJsonHeader();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportPeriodHeaderShort ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportPeriodHeaderShort) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->reportPeriodHeaderShort();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportMaxSkewHeaderShort ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportMaxSkewHeaderShort) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->reportMaxSkewHeaderShort();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportMpwHeaderShort ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportMpwHeaderShort) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->reportMpwHeaderShort();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportPathEndHeader ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportPathEndHeader) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->reportPathEndHeader();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportPathEndFooter ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportPathEndFooter) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->reportPathEndFooter();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportJsonFooter ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportJsonFooter) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->reportJsonFooter();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: setPathFormat ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathSetPathFormat2) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportPathFormat fmt = rpt->pathFormat();
|
||
|
|
rpt->setPathFormat(fmt);
|
||
|
|
EXPECT_EQ(rpt->pathFormat(), fmt);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: setDigits ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathSetDigits2) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
int digits = rpt->digits();
|
||
|
|
rpt->setDigits(4);
|
||
|
|
EXPECT_EQ(rpt->digits(), 4);
|
||
|
|
rpt->setDigits(digits);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: setNoSplit ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathSetNoSplit2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->setNoSplit(true);
|
||
|
|
rpt->setNoSplit(false);
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: setReportSigmas ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathSetReportSigmas2) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
bool sigmas = rpt->reportSigmas();
|
||
|
|
rpt->setReportSigmas(!sigmas);
|
||
|
|
EXPECT_NE(rpt->reportSigmas(), sigmas);
|
||
|
|
rpt->setReportSigmas(sigmas);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: findField ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathFindField2) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *f = rpt->findField("nonexistent_field_xyz");
|
||
|
|
EXPECT_EQ(f, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: fieldSlew/fieldFanout/fieldCapacitance ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathFieldAccessors) {
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
ReportField *slew = rpt->fieldSlew();
|
||
|
|
ReportField *fanout = rpt->fieldFanout();
|
||
|
|
ReportField *cap = rpt->fieldCapacitance();
|
||
|
|
ReportField *src = rpt->fieldSrcAttr();
|
||
|
|
EXPECT_NE(slew, nullptr);
|
||
|
|
EXPECT_NE(fanout, nullptr);
|
||
|
|
EXPECT_NE(cap, nullptr);
|
||
|
|
(void)src;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportEndHeader ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportEndHeader) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->reportEndHeader();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportSummaryHeader ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportSummaryHeader) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->reportSummaryHeader();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ReportPath: reportSlackOnlyHeader ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ReportPathReportSlackOnlyHeader) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
ReportPath *rpt = sta_->reportPath();
|
||
|
|
rpt->reportSlackOnlyHeader();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathGroups: static group name accessors ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupsAsyncGroupName2) {
|
||
|
|
const char *name = PathGroups::asyncPathGroupName();
|
||
|
|
EXPECT_NE(name, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupsPathDelayGroupName2) {
|
||
|
|
const char *name = PathGroups::pathDelayGroupName();
|
||
|
|
EXPECT_NE(name, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupsGatedClkGroupName2) {
|
||
|
|
const char *name = PathGroups::gatedClkGroupName();
|
||
|
|
EXPECT_NE(name, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathGroupsUnconstrainedGroupName2) {
|
||
|
|
const char *name = PathGroups::unconstrainedGroupName();
|
||
|
|
EXPECT_NE(name, nullptr);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Corner setParasiticAnalysisPtcount, setParasiticAP, setDcalcAnalysisPtcount,
|
||
|
|
// addPathAP are protected - skipped
|
||
|
|
|
||
|
|
// === Corners: parasiticAnalysisPtCount ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, CornersParasiticAnalysisPtCount2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Corners *corners = sta_->corners();
|
||
|
|
int count = corners->parasiticAnalysisPtCount();
|
||
|
|
(void)count;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkNetwork: isClock(Net*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkNetworkIsClockNetExists) {
|
||
|
|
auto fn = static_cast<bool (ClkNetwork::*)(const Net*) const>(&ClkNetwork::isClock);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkNetwork: clocks(Pin*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkNetworkClocksExists2) {
|
||
|
|
auto fn = &ClkNetwork::clocks;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkNetwork: pins(Clock*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkNetworkPinsExists2) {
|
||
|
|
auto fn = &ClkNetwork::pins;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// BfsIterator::init is protected - skipped
|
||
|
|
|
||
|
|
// === BfsIterator: checkInQueue ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, BfsIteratorCheckInQueueExists) {
|
||
|
|
auto fn = &BfsIterator::checkInQueue;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === BfsIterator: enqueueAdjacentVertices with level ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, BfsIteratorEnqueueAdjacentVerticesLevelExists) {
|
||
|
|
auto fn = static_cast<void (BfsIterator::*)(Vertex*, Level)>(
|
||
|
|
&BfsIterator::enqueueAdjacentVertices);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Levelize: checkLevels ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, LevelizeCheckLevelsExists2) {
|
||
|
|
auto fn = &Levelize::checkLevels;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Levelize::reportPath is protected - skipped
|
||
|
|
|
||
|
|
// === Path: init overloads ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathInitVertexFloatExists) {
|
||
|
|
auto fn = static_cast<void (Path::*)(Vertex*, float, const StaState*)>(
|
||
|
|
&Path::init);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathInitVertexTagExists) {
|
||
|
|
auto fn = static_cast<void (Path::*)(Vertex*, Tag*, const StaState*)>(
|
||
|
|
&Path::init);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathInitVertexTagFloatExists) {
|
||
|
|
auto fn = static_cast<void (Path::*)(Vertex*, Tag*, float, const StaState*)>(
|
||
|
|
&Path::init);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Path: constructor with Vertex*, Tag*, StaState* ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathCtorVertexTagStaExists) {
|
||
|
|
using PathCtorProbe = void (*)(Vertex *, Tag *, const StaState *);
|
||
|
|
PathCtorProbe fn = [](Vertex *v, Tag *t, const StaState *s) {
|
||
|
|
Path p(v, t, s);
|
||
|
|
(void)p;
|
||
|
|
};
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnd: less and cmpNoCrpr ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndLessExists) {
|
||
|
|
auto fn = &PathEnd::less;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndCmpNoCrprExists) {
|
||
|
|
auto fn = &PathEnd::cmpNoCrpr;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Tag: equal and match static methods ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagEqualStaticExists) {
|
||
|
|
auto fn = &Tag::equal;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Tag::match and Tag::stateEqual are protected - skipped
|
||
|
|
|
||
|
|
// === ClkInfo: equal static method ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoEqualStaticExists) {
|
||
|
|
auto fn = &ClkInfo::equal;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === ClkInfo: crprClkPath ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, ClkInfoCrprClkPathExists) {
|
||
|
|
auto fn = static_cast<Path* (ClkInfo::*)(const StaState*)>(
|
||
|
|
&ClkInfo::crprClkPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// CheckCrpr::portClkPath and crprArrivalDiff are private - skipped
|
||
|
|
|
||
|
|
// === Sim: findLogicConstants ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SimFindLogicConstantsExists2) {
|
||
|
|
auto fn = &Sim::findLogicConstants;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sim: makePinAfter ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SimMakePinAfterFnExists) {
|
||
|
|
auto fn = &Sim::makePinAfter;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === GatedClk: gatedClkEnables ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, GatedClkGatedClkEnablesExists) {
|
||
|
|
auto fn = &GatedClk::gatedClkEnables;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: pathClkPathArrival1 (protected, use fn pointer) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchPathClkPathArrival1Exists) {
|
||
|
|
auto fn = &Search::pathClkPathArrival;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: visitStartpoints ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchVisitStartpointsExists) {
|
||
|
|
auto fn = &Search::visitStartpoints;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: reportTagGroups ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchReportTagGroups2) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
search->reportTagGroups();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: reportPathCountHistogram ===
|
||
|
|
|
||
|
|
// Search::reportPathCountHistogram segfaults without graph - use fn pointer
|
||
|
|
TEST_F(StaInitTest, SearchReportPathCountHistogramExists) {
|
||
|
|
auto fn = &Search::reportPathCountHistogram;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: arrivalsInvalid ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchArrivalsInvalid3) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
search->arrivalsInvalid();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: requiredsInvalid ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchRequiredsInvalid3) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
search->requiredsInvalid();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: endpointsInvalid ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchEndpointsInvalid3) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
search->endpointsInvalid();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: copyState ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchCopyStateExists) {
|
||
|
|
auto fn = &Search::copyState;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: isEndpoint ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchIsEndpointExists) {
|
||
|
|
auto fn = static_cast<bool (Search::*)(Vertex*) const>(&Search::isEndpoint);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: seedArrival ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchSeedArrivalExists) {
|
||
|
|
auto fn = &Search::seedArrival;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: enqueueLatchOutput ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchEnqueueLatchOutputExists) {
|
||
|
|
auto fn = &Search::enqueueLatchOutput;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: isSegmentStart ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchIsSegmentStartExists) {
|
||
|
|
auto fn = &Search::isSegmentStart;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: seedRequiredEnqueueFanin ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchSeedRequiredEnqueueFaninExists) {
|
||
|
|
auto fn = &Search::seedRequiredEnqueueFanin;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: saveEnumPath ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchSaveEnumPathExists2) {
|
||
|
|
auto fn = &Search::saveEnumPath;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: graphLoops ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaGraphLoopsExists) {
|
||
|
|
auto fn = &Sta::graphLoops;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: pathCount ===
|
||
|
|
|
||
|
|
// Sta::pathCount segfaults without graph - use fn pointer
|
||
|
|
TEST_F(StaInitTest, StaPathCountExists) {
|
||
|
|
auto fn = &Sta::pathCount;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: findAllArrivals ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindAllArrivalsExists) {
|
||
|
|
auto fn = static_cast<void (Search::*)()>(&Search::findAllArrivals);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: findArrivals ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchFindArrivalsExists) {
|
||
|
|
auto fn = static_cast<void (Search::*)()>(&Search::findArrivals);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: findRequireds ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchFindRequiredsExists) {
|
||
|
|
auto fn = static_cast<void (Search::*)()>(&Search::findRequireds);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnd: type names for subclass function pointers ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndPathDelayTypeExists) {
|
||
|
|
auto fn = &PathEndPathDelay::type;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndPathDelayTypeNameExists) {
|
||
|
|
auto fn = &PathEndPathDelay::typeName;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEndUnconstrained: reportShort and requiredTime ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedReportShortExists) {
|
||
|
|
auto fn = &PathEndUnconstrained::reportShort;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEndUnconstrainedRequiredTimeExists) {
|
||
|
|
auto fn = &PathEndUnconstrained::requiredTime;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathEnum destructor ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathEnumCtorDtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
PathEnum pe(10, 5, false, false, true, sta_);
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === DiversionGreater ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, DiversionGreaterStateCtor) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
DiversionGreater dg(sta_);
|
||
|
|
(void)dg;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === TagGroup: report function pointer ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagGroupReportExists) {
|
||
|
|
auto fn = &TagGroup::report;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === TagGroupBldr: reportArrivalEntries ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, TagGroupBldrReportArrivalEntriesExists) {
|
||
|
|
auto fn = &TagGroupBldr::reportArrivalEntries;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === VertexPinCollector: copy ===
|
||
|
|
|
||
|
|
// VertexPinCollector::copy() throws "not supported" - skipped
|
||
|
|
TEST_F(StaInitTest, VertexPinCollectorCopyExists) {
|
||
|
|
auto fn = &VertexPinCollector::copy;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Genclks: function pointers ===
|
||
|
|
|
||
|
|
// Genclks::srcFilter and srcPathIndex are private - skipped
|
||
|
|
|
||
|
|
// === Genclks: findLatchFdbkEdges overloads ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, GenclksFindLatchFdbkEdges1ArgExists) {
|
||
|
|
auto fn = static_cast<void (Genclks::*)(const Clock*)>(
|
||
|
|
&Genclks::findLatchFdbkEdges);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: simLogicValue ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaSimLogicValueExists) {
|
||
|
|
auto fn = &Sta::simLogicValue;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: netSlack ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaNetSlackExists) {
|
||
|
|
auto fn = &Sta::netSlack;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: pinSlack overloads ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPinSlackRfExists) {
|
||
|
|
auto fn = static_cast<Slack (Sta::*)(const Pin*, const RiseFall*, const MinMax*)>(
|
||
|
|
&Sta::pinSlack);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPinSlackMinMaxExists) {
|
||
|
|
auto fn = static_cast<Slack (Sta::*)(const Pin*, const MinMax*)>(
|
||
|
|
&Sta::pinSlack);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: pinArrival ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaPinArrivalExists) {
|
||
|
|
auto fn = &Sta::pinArrival;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexLevel ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexLevelExists) {
|
||
|
|
auto fn = &Sta::vertexLevel;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexPathCount ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexPathCountExists2) {
|
||
|
|
auto fn = &Sta::vertexPathCount;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: endpointSlack ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaEndpointSlackExists) {
|
||
|
|
auto fn = &Sta::endpointSlack;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: arcDelay ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaArcDelayExists) {
|
||
|
|
auto fn = &Sta::arcDelay;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: arcDelayAnnotated ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaArcDelayAnnotatedExists) {
|
||
|
|
auto fn = &Sta::arcDelayAnnotated;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: findClkMinPeriod ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaFindClkMinPeriodExists) {
|
||
|
|
auto fn = &Sta::findClkMinPeriod;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexWorstArrivalPath ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexWorstArrivalPathExists2) {
|
||
|
|
auto fn = static_cast<Path* (Sta::*)(Vertex*, const MinMax*)>(
|
||
|
|
&Sta::vertexWorstArrivalPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexWorstArrivalPathRfExists) {
|
||
|
|
auto fn = static_cast<Path* (Sta::*)(Vertex*, const RiseFall*, const MinMax*)>(
|
||
|
|
&Sta::vertexWorstArrivalPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexWorstSlackPath ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexWorstSlackPathExists2) {
|
||
|
|
auto fn = static_cast<Path* (Sta::*)(Vertex*, const MinMax*)>(
|
||
|
|
&Sta::vertexWorstSlackPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexWorstSlackPathRfExists) {
|
||
|
|
auto fn = static_cast<Path* (Sta::*)(Vertex*, const RiseFall*, const MinMax*)>(
|
||
|
|
&Sta::vertexWorstSlackPath);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexSlew more overloads ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlewMinMaxExists2) {
|
||
|
|
auto fn = static_cast<Slew (Sta::*)(Vertex*, const RiseFall*, const MinMax*)>(
|
||
|
|
&Sta::vertexSlew);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexSlewMinMaxOnlyExists) {
|
||
|
|
auto fn = static_cast<Slew (Sta::*)(Vertex*, const MinMax*)>(
|
||
|
|
&Sta::vertexSlew);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: vertexPathIterator(Vertex*, RiseFall*, MinMax*) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaVertexPathIteratorRfMinMaxExists) {
|
||
|
|
auto fn = static_cast<VertexPathIterator* (Sta::*)(Vertex*, const RiseFall*, const MinMax*)>(
|
||
|
|
&Sta::vertexPathIterator);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: totalNegativeSlack ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaTotalNegativeSlackExists) {
|
||
|
|
auto fn = static_cast<Slack (Sta::*)(const MinMax*)>(&Sta::totalNegativeSlack);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaTotalNegativeSlackCornerExists) {
|
||
|
|
auto fn = static_cast<Slack (Sta::*)(const Corner*, const MinMax*)>(
|
||
|
|
&Sta::totalNegativeSlack);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: worstSlack ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaWorstSlackExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(const MinMax*, Slack&, Vertex*&)>(
|
||
|
|
&Sta::worstSlack);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaWorstSlackCornerExists) {
|
||
|
|
auto fn = static_cast<void (Sta::*)(const Corner*, const MinMax*, Slack&, Vertex*&)>(
|
||
|
|
&Sta::worstSlack);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: updateTiming ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaUpdateTimingExists) {
|
||
|
|
auto fn = &Sta::updateTiming;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: clkPathArrival ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchClkPathArrival1ArgExists) {
|
||
|
|
auto fn = static_cast<Arrival (Search::*)(const Path*) const>(
|
||
|
|
&Search::clkPathArrival);
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Sta::readLibertyFile (4-arg overload) is protected - skipped
|
||
|
|
|
||
|
|
// === Sta: disconnectPin ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaDisconnectPinExists2) {
|
||
|
|
auto fn = &Sta::disconnectPin;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === PathExpandedCtorGenClks ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, PathExpandedCtorGenClksExists) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
// Constructor: PathExpanded(const Path*, bool, const StaState*)
|
||
|
|
Path nullPath;
|
||
|
|
// We can't call this with a null path without crashing,
|
||
|
|
// but we can verify the overload exists.
|
||
|
|
auto ctor_test = [](const Path *p, bool b, const StaState *s) {
|
||
|
|
(void)p; (void)b; (void)s;
|
||
|
|
};
|
||
|
|
(void)ctor_test;
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: deleteFilteredArrivals ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchDeleteFilteredArrivals) {
|
||
|
|
ASSERT_NO_THROW(( [&](){
|
||
|
|
Search *search = sta_->search();
|
||
|
|
search->deleteFilteredArrivals();
|
||
|
|
expectStaCoreState(sta_);
|
||
|
|
|
||
|
|
}() ));
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkSlewLimitPreamble ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckSlewLimitPreambleExists) {
|
||
|
|
auto fn = &Sta::checkSlewLimitPreamble;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkFanoutLimitPreamble ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckFanoutLimitPreambleExists) {
|
||
|
|
auto fn = &Sta::checkFanoutLimitPreamble;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkCapacitanceLimitPreamble ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckCapacitanceLimitPreambleExists) {
|
||
|
|
auto fn = &Sta::checkCapacitanceLimitPreamble;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkSlewLimits(Net*,...) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckSlewLimitsExists) {
|
||
|
|
auto fn = &Sta::checkSlewLimits;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkFanoutLimits(Net*,...) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckFanoutLimitsExists) {
|
||
|
|
auto fn = &Sta::checkFanoutLimits;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: checkCapacitanceLimits(Net*,...) ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaCheckCapacitanceLimitsExists) {
|
||
|
|
auto fn = &Sta::checkCapacitanceLimits;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: seedInputSegmentArrival ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchSeedInputSegmentArrivalExists) {
|
||
|
|
auto fn = &Search::seedInputSegmentArrival;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: enqueueLatchDataOutputs ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchEnqueueLatchDataOutputsExists) {
|
||
|
|
auto fn = &Search::enqueueLatchDataOutputs;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: seedRequired ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchSeedRequiredExists) {
|
||
|
|
auto fn = &Search::seedRequired;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: findClkArrivals ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchFindClkArrivalsExists) {
|
||
|
|
auto fn = &Search::findClkArrivals;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: tnsInvalid ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchTnsInvalidExists) {
|
||
|
|
auto fn = &Search::tnsInvalid;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: endpointInvalid ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchEndpointInvalidExists) {
|
||
|
|
auto fn = &Search::endpointInvalid;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Search: makePathGroups ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, SearchMakePathGroupsExists) {
|
||
|
|
auto fn = &Search::makePathGroups;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: isIdealClock ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaIsIdealClockExists2) {
|
||
|
|
auto fn = &Sta::isIdealClock;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
// === Sta: isPropagatedClock ===
|
||
|
|
|
||
|
|
TEST_F(StaInitTest, StaIsPropagatedClockExists2) {
|
||
|
|
auto fn = &Sta::isPropagatedClock;
|
||
|
|
expectCallablePointerUsable(fn);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
} // namespace sta
|