Conversation
Greptile SummaryIntroduces a two-pass strategy in Confidence Score: 4/5Safe to merge with the two P2 gaps in mind; no data-loss or crash risk identified. All findings are P2. The dangling-pointer situation is currently benign, and the missing guard in the no-related-pin overload is an edge case unlikely to appear in typical Liberty files. Core bus-override logic looks correct. liberty/LibertyReader.cc — the no-related-pin makeTimingArcs overload and the bit_overrides_ lifetime after the deletion loop. Important Files Changed
Sequence DiagramsequenceDiagram
participant FPG as finishPortGroups()
participant MTA as makeTimingArcs(PortGroup*)
participant MTA2 as makeTimingArcs(from, to, timing)
participant HBPTO as hasBitPinTimingOverride()
participant SAI as sameArcIdentity()
participant RPIP as relatedPinIncludesPort()
participant B as builder_.makeTimingArcs()
FPG->>FPG: Pass 1 — populate bit_overrides_
FPG->>MTA: Pass 2 — makeTimingArcs(port_group)
MTA->>MTA2: iterate bits of bus port
MTA2->>HBPTO: hasBitPinTimingOverride(to_bit, from, timing)
HBPTO->>SAI: sameArcIdentity(pin_t, bus_timing, from)
SAI->>RPIP: relatedPinIncludesPort(pin_t, from, line)
RPIP-->>SAI: true/false
SAI-->>HBPTO: true/false
HBPTO-->>MTA2: override exists?
alt no override
MTA2->>B: create timing arc
else pin-level override exists
MTA2-->>MTA2: skip (pin arc takes precedence)
end
FPG->>FPG: delete port groups
|
| // Defer deletion until after the loop so overrides can safely walk. | ||
| for (PortGroup *port_group : cell_port_groups_) | ||
| delete port_group; | ||
| cell_port_groups_.clear(); |
There was a problem hiding this comment.
Dangling pointers remain in
bit_overrides_ after deletion loop
After the port-group deletion loop completes, bit_overrides_ still holds TimingGroup* pointers that now point to freed memory. The next call to finishPortGroups() clears the map before any use, so this is currently safe, but any subclass or future code that calls hasBitPinTimingOverride() between the end of finishPortGroups() and the next cell's finishPortGroups() would trigger undefined behaviour. A simple bit_overrides_.clear() immediately after the deletion loop makes the lifetime unambiguous.
Issue, given a bus and nested pin with the same timing types (when, related_pin, etc.) we will always pick the worst value (larger value), but we should pick the one that is nested deeper in the liberty cell's hierarchy.
Changes: