Null-ptr safety for diff-pair-coupling test.
Fixes https://gitlab.com/kicad/code/kicad/issues/12329
This commit is contained in:
parent
09aa28d78b
commit
854acd4c77
|
@ -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,33 +407,33 @@ 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() )
|
||||||
{
|
{
|
||||||
auto drce = DRC_ITEM::Create( DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG );
|
auto drce = DRC_ITEM::Create( DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG );
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
|
||||||
msg = wxString::Format( _( "(%s maximum uncoupled length: %s; actual: %s)" ),
|
msg = wxString::Format( _( "(%s maximum uncoupled length: %s; actual: %s)" ),
|
||||||
|
@ -442,36 +443,47 @@ 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;
|
||||||
|
|
||||||
msg = drcItem->GetErrorText() + wxT( " (" ) +
|
msg = drcItem->GetErrorText() + wxT( " (" ) +
|
||||||
gapConstraint->GetParentRule()->m_Name + wxS( " " );
|
gapConstraint->GetParentRule()->m_Name + wxS( " " );
|
||||||
|
@ -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() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue