Null-ptr safety for diff-pair-coupling test.

Fixes https://gitlab.com/kicad/code/kicad/issues/12329
This commit is contained in:
Jeff Young 2022-09-02 00:47:53 +01:00
parent 09aa28d78b
commit 854acd4c77
1 changed files with 78 additions and 56 deletions

View File

@ -324,10 +324,10 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
reportAux( wxT( "DPs evaluated:" ) ); reportAux( wxT( "DPs evaluated:" ) );
for( auto& it : dpRuleMatches ) for( auto& [ key, itemSet ] : dpRuleMatches )
{ {
NETINFO_ITEM *niP = m_board->GetNetInfo().GetNetItem( it.first.netP ); NETINFO_ITEM *niP = m_board->GetNetInfo().GetNetItem( key.netP );
NETINFO_ITEM *niN = m_board->GetNetInfo().GetNetItem( it.first.netN ); NETINFO_ITEM *niN = m_board->GetNetInfo().GetNetItem( key.netN );
assert( niP ); assert( niP );
assert( niN ); assert( niN );
@ -336,46 +336,47 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
wxString nameN = niN->GetNetname(); wxString nameN = niN->GetNetname();
reportAux( wxString::Format( wxT( "Rule '%s', DP: (+) %s - (-) %s" ), reportAux( wxString::Format( wxT( "Rule '%s', DP: (+) %s - (-) %s" ),
it.first.parentRule->m_Name, key.parentRule->m_Name,
nameP, nameP,
nameN ) ); nameN ) );
extractDiffPairCoupledItems( it.second ); extractDiffPairCoupledItems( itemSet );
it.second.totalCoupled = 0; itemSet.totalCoupled = 0;
it.second.totalLengthN = 0; itemSet.totalLengthN = 0;
it.second.totalLengthP = 0; itemSet.totalLengthP = 0;
drc_dbg(10, wxT( " coupled prims : %d\n" ), (int) it.second.coupled.size() ); drc_dbg(10, wxT( " coupled prims : %d\n" ), (int) itemSet.coupled.size() );
std::optional<DRC_CONSTRAINT> gapConstraint = std::optional<DRC_CONSTRAINT> gapConstraint
it.first.parentRule->FindConstraint( DIFF_PAIR_GAP_CONSTRAINT ); = key.parentRule->FindConstraint( DIFF_PAIR_GAP_CONSTRAINT );
std::optional<DRC_CONSTRAINT> maxUncoupledConstraint =
it.first.parentRule->FindConstraint( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT );
for( BOARD_CONNECTED_ITEM* item : it.second.itemsN ) std::optional<DRC_CONSTRAINT> maxUncoupledConstraint
= key.parentRule->FindConstraint( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT );
for( BOARD_CONNECTED_ITEM* item : itemSet.itemsN )
{ {
// fixme: include vias // fixme: include vias
if( PCB_TRACK* track = dyn_cast<PCB_TRACK*>( item ) ) if( PCB_TRACK* track = dyn_cast<PCB_TRACK*>( item ) )
it.second.totalLengthN += track->GetLength(); itemSet.totalLengthN += track->GetLength();
} }
for( BOARD_CONNECTED_ITEM* item : it.second.itemsP ) for( BOARD_CONNECTED_ITEM* item : itemSet.itemsP )
{ {
// fixme: include vias // fixme: include vias
if( PCB_TRACK* track = dyn_cast<PCB_TRACK*>( item ) ) if( PCB_TRACK* track = dyn_cast<PCB_TRACK*>( item ) )
it.second.totalLengthP += track->GetLength(); itemSet.totalLengthP += track->GetLength();
} }
for( auto& cpair : it.second.coupled ) for( DIFF_PAIR_COUPLED_SEGMENTS& dp : itemSet.coupled )
{ {
int length = cpair.coupledN.Length(); int length = dp.coupledN.Length();
int gap = cpair.coupledN.Distance( cpair.coupledP ); int gap = dp.coupledN.Distance( dp.coupledP );
gap -= cpair.parentN->GetWidth() / 2; gap -= dp.parentN->GetWidth() / 2;
gap -= cpair.parentP->GetWidth() / 2; gap -= dp.parentP->GetWidth() / 2;
cpair.computedGap = gap; dp.computedGap = gap;
auto overlay = m_drcEngine->GetDebugOverlay(); auto overlay = m_drcEngine->GetDebugOverlay();
@ -385,15 +386,15 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
overlay->SetIsStroke(true); overlay->SetIsStroke(true);
overlay->SetStrokeColor( RED ); overlay->SetStrokeColor( RED );
overlay->SetLineWidth( 100000 ); overlay->SetLineWidth( 100000 );
overlay->Line( cpair.coupledP ); overlay->Line( dp.coupledP );
overlay->SetStrokeColor( BLUE ); overlay->SetStrokeColor( BLUE );
overlay->Line( cpair.coupledN ); overlay->Line( dp.coupledN );
} }
drc_dbg( 10, wxT( " len %d gap %d l %d\n" ), drc_dbg( 10, wxT( " len %d gap %d l %d\n" ),
length, length,
gap, gap,
cpair.parentP->GetLayer() ); dp.parentP->GetLayer() );
if( gapConstraint ) if( gapConstraint )
{ {
@ -406,29 +407,29 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
if( val.HasMax() && gap > val.Max() ) if( val.HasMax() && gap > val.Max() )
insideRange = false; insideRange = false;
cpair.couplingOK = insideRange; dp.couplingOK = insideRange;
} }
else else
{ {
cpair.couplingOK = true; dp.couplingOK = true;
} }
if( cpair.couplingOK ) if( dp.couplingOK )
it.second.totalCoupled += length; itemSet.totalCoupled += length;
} }
int totalLen = std::max( it.second.totalLengthN, it.second.totalLengthP ); int totalLen = std::max( itemSet.totalLengthN, itemSet.totalLengthP );
reportAux( wxString::Format( wxT( " - coupled length: %s, total length: %s" ), reportAux( wxString::Format( wxT( " - coupled length: %s, total length: %s" ),
MessageTextFromValue( userUnits(), it.second.totalCoupled ), MessageTextFromValue( userUnits(), itemSet.totalCoupled ),
MessageTextFromValue( userUnits(), totalLen ) ) ); MessageTextFromValue( userUnits(), totalLen ) ) );
int totalUncoupled = totalLen - it.second.totalCoupled; int totalUncoupled = totalLen - itemSet.totalCoupled;
bool uncoupledViolation = false; bool uncoupledViolation = false;
if( maxUncoupledConstraint ) if( maxUncoupledConstraint && ( !itemSet.itemsP.empty() || ! itemSet.itemsN.empty() ) )
{ {
auto val = maxUncoupledConstraint->GetValue(); const MINOPTMAX<int>& val = maxUncoupledConstraint->GetValue();
if ( val.HasMax() && totalUncoupled > val.Max() ) if ( val.HasMax() && totalUncoupled > val.Max() )
{ {
@ -442,34 +443,45 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg ); drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
auto pit = it.second.itemsP.begin(); BOARD_CONNECTED_ITEM* item = nullptr;
auto nit = it.second.itemsN.begin(); auto p_it = itemSet.itemsP.begin();
auto n_it = itemSet.itemsN.begin();
drce->AddItem( *pit ); if( p_it != itemSet.itemsP.end() )
drce->AddItem( *nit ); {
item = *p_it;
drce->AddItem( *p_it );
p_it++;
}
for( pit++; pit != it.second.itemsP.end(); pit++ ) if( n_it != itemSet.itemsN.end() )
drce->AddItem( *pit ); {
item = *n_it;
drce->AddItem( *n_it );
n_it++;
}
for( nit++; nit != it.second.itemsN.end(); nit++ ) while( p_it != itemSet.itemsP.end() )
drce->AddItem( *nit ); drce->AddItem( *p_it++ );
while( n_it != itemSet.itemsN.end() )
drce->AddItem( *n_it++ );
uncoupledViolation = true; uncoupledViolation = true;
drce->SetViolatingRule( maxUncoupledConstraint->GetParentRule() ); drce->SetViolatingRule( maxUncoupledConstraint->GetParentRule() );
reportViolation( drce, ( *it.second.itemsP.begin() )->GetPosition(), reportViolation( drce, item->GetPosition(), item->GetLayer() );
( *it.second.itemsP.begin() )->GetLayer() );
} }
} }
if ( gapConstraint && ( uncoupledViolation || !maxUncoupledConstraint ) ) if ( gapConstraint && ( uncoupledViolation || !maxUncoupledConstraint ) )
{ {
for( auto& cpair : it.second.coupled ) for( DIFF_PAIR_COUPLED_SEGMENTS& dp : itemSet.coupled )
{ {
if( !cpair.couplingOK ) if( !dp.couplingOK && ( dp.parentP || dp.parentN ) )
{ {
auto val = gapConstraint->GetValue(); MINOPTMAX<int> val = gapConstraint->GetValue();
auto drcItem = DRC_ITEM::Create( DRCE_DIFF_PAIR_GAP_OUT_OF_RANGE ); auto drcItem = DRC_ITEM::Create( DRCE_DIFF_PAIR_GAP_OUT_OF_RANGE );
wxString msg; wxString msg;
@ -485,17 +497,27 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
MessageTextFromValue( userUnits(), val.Max() ) ); MessageTextFromValue( userUnits(), val.Max() ) );
msg += wxString::Format( _( "actual: %s)" ), msg += wxString::Format( _( "actual: %s)" ),
MessageTextFromValue( userUnits(), cpair.computedGap ) ); MessageTextFromValue( userUnits(), dp.computedGap ) );
drcItem->SetErrorMessage( msg ); drcItem->SetErrorMessage( msg );
drcItem->AddItem( cpair.parentP ); BOARD_CONNECTED_ITEM* item = nullptr;
drcItem->AddItem( cpair.parentN );
if( dp.parentP )
{
item = dp.parentP;
drcItem->AddItem( dp.parentP );
}
if( dp.parentN )
{
item = dp.parentN;
drcItem->AddItem( dp.parentN );
}
drcItem->SetViolatingRule( gapConstraint->GetParentRule() ); drcItem->SetViolatingRule( gapConstraint->GetParentRule() );
reportViolation( drcItem, cpair.parentP->GetPosition(), reportViolation( drcItem, item->GetPosition(), item->GetLayer() );
cpair.parentP->GetLayer() );
} }
} }
} }