@@ -109,14 +109,12 @@ TEST_F(TestDbSta, TestHierarchyConnectivity)
109109// nd1/A2 <- in2
110110//
111111// Flow:
112- // 1. Capture drvr_path at nd1/ZN and snapshot prevPath() pointer + pin.
113- // 2. Delete upstream b1 + updateTiming -> free b1/inv1 Path[] slots.
114- // 3. Add a fresh BUF + clock + updateTiming -> recycle freed slots.
112+ // 1. Capture drvr_path at nd1/ZN and snapshot prevPath() pointer + pin name
113+ // 2. Delete upstream b1 + updateTiming -> free
114+ // 3. Add a fresh BUF + clock + updateTiming -> recycle
115115// 4. Assert the captured Path's prev slot has been recycled: pin()
116116// decodes to data that belongs to a different instance than nd1's
117- // real input. When the drvr slot itself is preserved, also assert
118- // the strict stale-pointer signature (same raw address, different
119- // content).
117+ // real input.
120118TEST_F (TestDbSta, StalePrevPathAfterUpdateTiming)
121119{
122120 readVerilogAndSetup (" TestDbSta_StalePath.v" );
@@ -130,10 +128,9 @@ TEST_F(TestDbSta, StalePrevPathAfterUpdateTiming)
130128 MinMax::max ());
131129 ASSERT_NE (drvr_path, nullptr );
132130 ASSERT_EQ (network->pathName (drvr_path->pin (sta_.get ())), " nd1/ZN" );
133- const Path* prev_before = drvr_path->prevPath ();
134- ASSERT_NE (prev_before, nullptr );
135- const std::string prev_pin_before
136- = network->pathName (prev_before->pin (sta_.get ()));
131+ const Path* pre_addr = drvr_path->prevPath ();
132+ ASSERT_NE (pre_addr, nullptr );
133+ const std::string pre_pin_name = network->pathName (pre_addr->pin (sta_.get ()));
137134
138135 // 2. Free upstream Path[] slots.
139136 sta_->deleteInstance (db_network_->dbToSta (block_->findInst (" b1" )));
@@ -156,33 +153,17 @@ TEST_F(TestDbSta, StalePrevPathAfterUpdateTiming)
156153 " clk2" , clk2_pins, false , 0 .2f , clk2_waveform, " " , sta_->cmdMode ());
157154 sta_->updateTiming (true );
158155
159- // 4. Staleness evidence. Allocator behaviour decides which slot lands
160- // on the recycled memory:
161- // (a) drvr slot preserved + prev slot recycled (glibc in our CI) --
162- // strict stale-pointer signature: same raw prev address, but
163- // pin() decodes to content from an unrelated instance.
164- // (b) drvr slot itself recycled (other allocators) -- drvr pin decodes
165- // to something other than nd1/ZN.
166- // Either case proves the captured raw Path* outlived the slot.
167- const std::string drvr_pin_after
168- = network->pathName (drvr_path->pin (sta_.get ()));
169- const Path* prev_after = drvr_path->prevPath ();
170- const std::string prev_pin_after
171- = prev_after ? network->pathName (prev_after->pin (sta_.get ()))
172- : std::string (" <null>" );
173- const bool drvr_recycled = drvr_pin_after != " nd1/ZN" ;
174- const bool prev_recycled = prev_after != nullptr && prev_pin_after != " nd1/A1"
175- && prev_pin_after != " nd1/A2" ;
176- EXPECT_TRUE (drvr_recycled || prev_recycled)
177- << " expected slot reuse to be demonstrable; drvr=" << drvr_pin_after
178- << " prev=" << prev_pin_after;
179- if (!drvr_recycled && prev_after != nullptr ) {
180- EXPECT_EQ (prev_after, prev_before)
181- << " stale-pointer signature: prev_path_ address unchanged" ;
182- EXPECT_NE (prev_pin_after, prev_pin_before)
183- << " but slot content should differ after free+reuse. before="
184- << prev_pin_before << " after=" << prev_pin_after;
185- }
156+ // 4. Staleness evidence. Pointer address is same but pin name has changed.
157+ const Path* post_addr = drvr_path->prevPath ();
158+ const std::string post_pin_name
159+ = post_addr ? network->pathName (post_addr->pin (sta_.get ()))
160+ : std::string (" <null>" );
161+
162+ EXPECT_EQ (pre_addr, post_addr)
163+ << " stale-pointer signature: prev_path_ address unchanged" ;
164+ EXPECT_NE (pre_pin_name, post_pin_name)
165+ << " but slot content should differ after free+reuse. before="
166+ << pre_pin_name << " after=" << post_pin_name;
186167}
187168
188169} // namespace sta
0 commit comments