From d513640572703185d01a773c5f8b23a1dc9d561d Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 1 Nov 2023 17:08:51 +0000 Subject: [PATCH] Behave (or assert) when source or target are null or dirty. (cherry picked from commit 7f8e397dfb26a5311c88c365a6a4447e5c495dc0) --- pcbnew/connectivity/connectivity_data.cpp | 16 ++++++++++++++++ pcbnew/dialogs/dialog_drc.cpp | 8 ++++++++ pcbnew/drc/drc_test_provider_connectivity.cpp | 3 +++ pcbnew/ratsnest/ratsnest_data.cpp | 4 ++++ pcbnew/ratsnest/ratsnest_view_item.cpp | 2 +- pcbnew/router/router_tool.cpp | 7 +++++-- pcbnew/tools/pcb_selection_tool.cpp | 5 +++++ 7 files changed, 42 insertions(+), 3 deletions(-) diff --git a/pcbnew/connectivity/connectivity_data.cpp b/pcbnew/connectivity/connectivity_data.cpp index 5feee61a0f..2694ee4cbc 100644 --- a/pcbnew/connectivity/connectivity_data.cpp +++ b/pcbnew/connectivity/connectivity_data.cpp @@ -385,6 +385,10 @@ void CONNECTIVITY_DATA::ComputeLocalRatsnest( const std::vector& aI { const std::shared_ptr& nodeA = edge.GetSourceNode(); const std::shared_ptr& nodeB = edge.GetTargetNode(); + + if( !nodeA || nodeA->Dirty() || !nodeB || nodeB->Dirty() ) + continue; + RN_DYNAMIC_LINE l; // Use the parents' positions @@ -964,6 +968,9 @@ const std::vector CONNECTIVITY_DATA::GetRatsnestForItems( std::vector srcNode = edge.GetSourceNode(); std::shared_ptr dstNode = edge.GetTargetNode(); + if( !srcNode || srcNode->Dirty() || !dstNode || dstNode->Dirty() ) + continue; + BOARD_CONNECTED_ITEM* srcParent = srcNode->Parent(); BOARD_CONNECTED_ITEM* dstParent = dstNode->Parent(); @@ -986,6 +993,12 @@ const std::vector CONNECTIVITY_DATA::GetRatsnestForPad( const PAD* aPad for( const CN_EDGE& edge : net->GetEdges() ) { + if( !edge.GetSourceNode() || edge.GetSourceNode()->Dirty() ) + continue; + + if( !edge.GetTargetNode() || edge.GetTargetNode()->Dirty() ) + continue; + if( edge.GetSourceNode()->Parent() == aPad || edge.GetTargetNode()->Parent() == aPad ) edges.push_back( edge ); } @@ -1015,6 +1028,9 @@ const std::vector CONNECTIVITY_DATA::GetRatsnestForComponent( FOOTPRINT auto srcNode = edge.GetSourceNode(); auto dstNode = edge.GetTargetNode(); + if( !srcNode || srcNode->Dirty() || !dstNode || dstNode->Dirty() ) + continue; + const PAD* srcParent = static_cast( srcNode->Parent() ); const PAD* dstParent = static_cast( dstNode->Parent() ); diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp index 5f3c9a4b29..e4ecae5ed9 100644 --- a/pcbnew/dialogs/dialog_drc.cpp +++ b/pcbnew/dialogs/dialog_drc.cpp @@ -479,6 +479,14 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent ) m_frame->GetBoard()->GetConnectivity()->RunOnUnconnectedEdges( [&]( CN_EDGE& edge ) { + // Connectivity was valid when DRC was run, but this is a modeless dialog + // so it might not be now. + if( !edge.GetSourceNode() || edge.GetSourceNode()->Dirty() ) + return true; + + if( !edge.GetTargetNode() || edge.GetTargetNode()->Dirty() ) + return true; + if( edge.GetSourceNode()->Parent() == a && edge.GetTargetNode()->Parent() == b ) { diff --git a/pcbnew/drc/drc_test_provider_connectivity.cpp b/pcbnew/drc/drc_test_provider_connectivity.cpp index afd46c5dc8..07f4927ba8 100644 --- a/pcbnew/drc/drc_test_provider_connectivity.cpp +++ b/pcbnew/drc/drc_test_provider_connectivity.cpp @@ -151,6 +151,9 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run() if( !reportProgress( ii++, count, progressDelta ) ) return false; // DRC cancelled + wxCHECK( edge.GetSourceNode() && !edge.GetSourceNode()->Dirty(), true ); + wxCHECK( edge.GetTargetNode() && !edge.GetTargetNode()->Dirty(), true ); + std::shared_ptr drcItem = DRC_ITEM::Create( DRCE_UNCONNECTED_ITEMS ); drcItem->SetItems( edge.GetSourceNode()->Parent(), edge.GetTargetNode()->Parent() ); reportViolation( drcItem, edge.GetSourceNode()->Pos(), UNDEFINED_LAYER ); diff --git a/pcbnew/ratsnest/ratsnest_data.cpp b/pcbnew/ratsnest/ratsnest_data.cpp index f1f24583fa..b84a91fa4e 100644 --- a/pcbnew/ratsnest/ratsnest_data.cpp +++ b/pcbnew/ratsnest/ratsnest_data.cpp @@ -123,6 +123,8 @@ void RN_NET::kruskalMST( const std::vector &aEdges ) const std::shared_ptr& source = tmp.GetSourceNode(); const std::shared_ptr& target = tmp.GetTargetNode(); + wxCHECK2( source && !source->Dirty() && target && !target->Dirty(), continue ); + if( dset.unite( source->GetTag(), target->GetTag() ) ) { if( tmp.GetWeight() > 0 ) @@ -416,6 +418,8 @@ void RN_NET::OptimizeRNEdges() const std::shared_ptr& source = edge.GetSourceNode(); const std::shared_ptr& target = edge.GetTargetNode(); + wxCHECK2( source && !source->Dirty() && target && !target->Dirty(), continue ); + if( source->ConnectedItemsCount() == 0 ) { optimizeZoneAnchor( source->Pos(), source->Parent()->GetLayerSet(), target, diff --git a/pcbnew/ratsnest/ratsnest_view_item.cpp b/pcbnew/ratsnest/ratsnest_view_item.cpp index 495e405ac1..b5e9d88319 100644 --- a/pcbnew/ratsnest/ratsnest_view_item.cpp +++ b/pcbnew/ratsnest/ratsnest_view_item.cpp @@ -197,7 +197,7 @@ void RATSNEST_VIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const const std::shared_ptr& sourceNode = edge.GetSourceNode(); const std::shared_ptr& targetNode = edge.GetTargetNode(); - if( !sourceNode || !sourceNode->Valid() || !targetNode || !targetNode->Valid() ) + if( !sourceNode || sourceNode->Dirty() || !targetNode || targetNode->Dirty() ) continue; const VECTOR2I source( sourceNode->Pos() ); diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index bf9d1832c0..ab6a7a87de 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -1612,10 +1612,13 @@ int ROUTER_TOOL::RouteSelected( const TOOL_EVENT& aEvent ) std::shared_ptr target = edge.GetTargetNode(); std::shared_ptr source = edge.GetSourceNode(); + if( !source || source->Dirty() || !target || target->Dirty() ) + continue; + if( source->Parent() == item ) - anchors.push_back( edge.GetSourceNode() ); + anchors.push_back( source ); else if( target->Parent() == item ) - anchors.push_back( edge.GetTargetNode() ); + anchors.push_back( target ); } // Route them diff --git a/pcbnew/tools/pcb_selection_tool.cpp b/pcbnew/tools/pcb_selection_tool.cpp index 5da655bdb1..11e8ab2465 100644 --- a/pcbnew/tools/pcb_selection_tool.cpp +++ b/pcbnew/tools/pcb_selection_tool.cpp @@ -1474,6 +1474,9 @@ int PCB_SELECTION_TOOL::selectUnconnected( const TOOL_EVENT& aEvent ) { for( const CN_EDGE& edge : conn->GetRatsnestForPad( pad ) ) { + wxCHECK2( edge.GetSourceNode() && !edge.GetSourceNode()->Dirty(), continue ); + wxCHECK2( edge.GetTargetNode() && !edge.GetTargetNode()->Dirty(), continue ); + BOARD_CONNECTED_ITEM* sourceParent = edge.GetSourceNode()->Parent(); BOARD_CONNECTED_ITEM* targetParent = edge.GetTargetNode()->Parent(); @@ -1537,6 +1540,8 @@ int PCB_SELECTION_TOOL::grabUnconnected( const TOOL_EVENT& aEvent ) const CN_ANCHOR* other = edge.GetSourceNode()->Parent() == pad ? edge.GetTargetNode().get() : edge.GetSourceNode().get(); + wxCHECK2( other && !other->Dirty(), continue ); + // We only want to grab footprints, so the ratnest has to point to a pad if( other->Parent()->Type() != PCB_PAD_T ) continue;