Prevent copy-elision issues by using smart-pointer.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16335

(cherry picked from commit e801e793dc)
This commit is contained in:
Jeff Young 2023-12-11 16:27:09 +00:00
parent 6d17d7d7a1
commit 874f7fbdff
2 changed files with 58 additions and 51 deletions

View File

@ -110,13 +110,15 @@ int BOARD_INSPECTION_TOOL::ShowBoardStatistics( const TOOL_EVENT& aEvent )
}
DRC_ENGINE BOARD_INSPECTION_TOOL::makeDRCEngine( bool* aCompileError, bool* aCourtyardError )
std::unique_ptr<DRC_ENGINE> BOARD_INSPECTION_TOOL::makeDRCEngine( bool* aCompileError,
bool* aCourtyardError )
{
DRC_ENGINE engine( m_frame->GetBoard(), &m_frame->GetBoard()->GetDesignSettings() );
auto engine = std::make_unique<DRC_ENGINE>( m_frame->GetBoard(),
&m_frame->GetBoard()->GetDesignSettings() );
try
{
engine.InitEngine( m_frame->GetDesignRulesPath() );
engine->InitEngine( m_frame->GetDesignRulesPath() );
}
catch( PARSE_ERROR& )
{
@ -252,9 +254,11 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
m_inspectClearanceDialog->DeleteAllPages();
bool compileError = false;
bool courtyardError = false;
std::unique_ptr<DRC_ENGINE> drcEngine = makeDRCEngine( &compileError, &courtyardError );
WX_HTML_REPORT_BOX* r = nullptr;
bool compileError = false;
DRC_ENGINE drcEngine = makeDRCEngine( &compileError );
DRC_CONSTRAINT constraint;
int clearance = 0;
wxString clearanceStr;
@ -277,7 +281,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
if( compileError )
reportCompileError( r );
constraint = drcEngine.EvalRules( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT, a, b, layer, r );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved max uncoupled length: %s." ),
@ -292,7 +296,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
if( compileError )
reportCompileError( r );
constraint = drcEngine.EvalRules( TEXT_HEIGHT_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( TEXT_HEIGHT_CONSTRAINT, a, b, layer, r );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved height constraints: min %s; max %s." ),
@ -307,7 +311,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
if( compileError )
reportCompileError( r );
constraint = drcEngine.EvalRules( TEXT_THICKNESS_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( TEXT_THICKNESS_CONSTRAINT, a, b, layer, r );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved thickness constraints: min %s; max %s." ),
@ -322,7 +326,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
if( compileError )
reportCompileError( r );
constraint = drcEngine.EvalRules( TRACK_WIDTH_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( TRACK_WIDTH_CONSTRAINT, a, b, layer, r );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved width constraints: min %s; max %s." ),
@ -337,7 +341,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
if( compileError )
reportCompileError( r );
constraint = drcEngine.EvalRules( CONNECTION_WIDTH_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( CONNECTION_WIDTH_CONSTRAINT, a, b, layer, r );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved min connection width constraint: %s." ),
@ -351,7 +355,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
if( compileError )
reportCompileError( r );
constraint = drcEngine.EvalRules( VIA_DIAMETER_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( VIA_DIAMETER_CONSTRAINT, a, b, layer, r );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved diameter constraints: min %s; max %s." ),
@ -366,7 +370,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
if( compileError )
reportCompileError( r );
constraint = drcEngine.EvalRules( ANNULAR_WIDTH_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( ANNULAR_WIDTH_CONSTRAINT, a, b, layer, r );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved annular width constraints: min %s; max %s." ),
@ -382,7 +386,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
if( compileError )
reportCompileError( r );
constraint = drcEngine.EvalRules( HOLE_SIZE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( HOLE_SIZE_CONSTRAINT, a, b, layer, r );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved diameter constraints: min %s; max %s." ),
@ -404,7 +408,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
}
else
{
constraint = drcEngine.EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
clearance = constraint.m_Value.Min();
clearanceStr = m_frame->StringFromValue( clearance, true );
@ -417,11 +421,11 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
r->Report( "" );
reportHeader( _( "Physical hole clearance resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalRules( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
clearance = constraint.m_Value.Min();
clearanceStr = m_frame->StringFromValue( clearance, true );
if( !drcEngine.HasRulesForConstraintType( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT ) )
if( !drcEngine->HasRulesForConstraintType( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT ) )
{
r->Report( "" );
r->Report( _( "No 'physical_hole_clearance' constraints defined." ) );
@ -441,7 +445,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
if( compileError )
reportCompileError( r );
constraint = drcEngine.EvalRules( HOLE_TO_HOLE_CONSTRAINT, a, b, UNDEFINED_LAYER, r );
constraint = drcEngine->EvalRules( HOLE_TO_HOLE_CONSTRAINT, a, b, UNDEFINED_LAYER, r );
clearance = constraint.m_Value.Min();
clearanceStr = m_frame->StringFromValue( clearance, true );
@ -456,7 +460,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
if( compileError )
reportCompileError( r );
constraint = drcEngine.EvalRules( EDGE_CLEARANCE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( EDGE_CLEARANCE_CONSTRAINT, a, b, layer, r );
clearance = constraint.m_Value.Min();
clearanceStr = m_frame->StringFromValue( clearance, true );
@ -505,7 +509,7 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
}
else
{
constraint = drcEngine.EvalRules( CLEARANCE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( CLEARANCE_CONSTRAINT, a, b, layer, r );
clearance = constraint.m_Value.Min();
clearanceStr = m_frame->StringFromValue( clearance, true );
@ -518,11 +522,11 @@ void BOARD_INSPECTION_TOOL::InspectDRCError( const std::shared_ptr<RC_ITEM>& aDR
r->Report( "" );
reportHeader( _( "Physical clearance resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalRules( PHYSICAL_CLEARANCE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( PHYSICAL_CLEARANCE_CONSTRAINT, a, b, layer, r );
clearance = constraint.m_Value.Min();
clearanceStr = m_frame->StringFromValue( clearance, true );
if( !drcEngine.HasRulesForConstraintType( PHYSICAL_CLEARANCE_CONSTRAINT ) )
if( !drcEngine->HasRulesForConstraintType( PHYSICAL_CLEARANCE_CONSTRAINT ) )
{
r->Report( "" );
r->Report( _( "No 'physical_clearance' constraints defined." ) );
@ -618,12 +622,13 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
PAD* pad = dynamic_cast<PAD*>( b );
FOOTPRINT* aFP = dynamic_cast<FOOTPRINT*>( a );
FOOTPRINT* bFP = dynamic_cast<FOOTPRINT*>( b );
bool compileError = false;
DRC_ENGINE drcEngine = makeDRCEngine( &compileError );
DRC_CONSTRAINT constraint;
int clearance = 0;
bool compileError = false;
bool courtyardError = false;
std::unique_ptr<DRC_ENGINE> drcEngine = makeDRCEngine( &compileError, &courtyardError );
if( copperIntersection.any() && zone && pad && zone->GetNetCode() == pad->GetNetCode() )
{
PCB_LAYER_ID layer = UNDEFINED_LAYER;
@ -636,7 +641,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r = m_inspectClearanceDialog->AddPage( _( "Zone" ) );
reportHeader( _( "Zone connection resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalZoneConnection( pad, zone, layer, r );
constraint = drcEngine->EvalZoneConnection( pad, zone, layer, r );
if( constraint.m_ZoneConnection == ZONE_CONNECTION::THERMAL )
{
@ -644,7 +649,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r->Report( "" );
reportHeader( _( "Thermal relief gap resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalRules( THERMAL_RELIEF_GAP_CONSTRAINT, pad, zone, layer, r );
constraint = drcEngine->EvalRules( THERMAL_RELIEF_GAP_CONSTRAINT, pad, zone, layer, r );
int gap = constraint.m_Value.Min();
if( compileError )
@ -658,7 +663,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r->Report( "" );
reportHeader( _( "Spoke width resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalRules( THERMAL_SPOKE_WIDTH_CONSTRAINT, pad, zone, layer, r );
constraint = drcEngine->EvalRules( THERMAL_SPOKE_WIDTH_CONSTRAINT, pad, zone, layer, r );
int width = constraint.m_Value.Opt();
if( compileError )
@ -672,7 +677,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r->Report( "" );
reportHeader( _( "Spoke count resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalRules( MIN_RESOLVED_SPOKES_CONSTRAINT, pad, zone, layer, r );
constraint = drcEngine->EvalRules( MIN_RESOLVED_SPOKES_CONSTRAINT, pad, zone, layer, r );
int minSpokes = constraint.m_Value.Min();
if( compileError )
@ -695,7 +700,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r->Report( wxString::Format( _( "Zone clearance: %s." ),
m_frame->StringFromValue( clearance, true ) ) );
constraint = drcEngine.EvalRules( PHYSICAL_CLEARANCE_CONSTRAINT, pad, zone, layer, r );
constraint = drcEngine->EvalRules( PHYSICAL_CLEARANCE_CONSTRAINT, pad, zone, layer, r );
if( constraint.m_Value.Min() > clearance )
{
@ -710,7 +715,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
if( !pad->FlashLayer( layer ) )
{
constraint = drcEngine.EvalRules( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, pad, zone,
constraint = drcEngine->EvalRules( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, pad, zone,
layer, r );
if( constraint.m_Value.Min() > clearance )
@ -767,7 +772,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
else
{
// Different nets (or one or both unconnected)....
constraint = drcEngine.EvalRules( CLEARANCE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( CLEARANCE_CONSTRAINT, a, b, layer, r );
if( constraint.IsNull() )
clearance = 0;
@ -800,7 +805,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r = m_inspectClearanceDialog->AddPage( _( "Diff Pair" ) );
reportHeader( _( "Diff pair gap resolution for:" ), ac, bc, active, r );
constraint = drcEngine.EvalRules( DIFF_PAIR_GAP_CONSTRAINT, ac, bc, active, r );
constraint = drcEngine->EvalRules( DIFF_PAIR_GAP_CONSTRAINT, ac, bc, active, r );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved gap constraints: min %s; opt %s; max %s." ),
@ -813,15 +818,15 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r->Report( "" );
reportHeader( _( "Diff pair max uncoupled length resolution for:" ), ac, bc, active, r );
if( !drcEngine.HasRulesForConstraintType( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT ) )
if( !drcEngine->HasRulesForConstraintType( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT ) )
{
r->Report( "" );
r->Report( _( "No 'diff_pair_uncoupled' constraints defined." ) );
}
else
{
constraint = drcEngine.EvalRules( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT, ac, bc,
active, r );
constraint = drcEngine->EvalRules( DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT, ac, bc,
active, r );
r->Report( "" );
r->Report( wxString::Format( _( "Resolved max uncoupled length: %s." ),
@ -867,7 +872,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r = m_inspectClearanceDialog->AddPage( m_frame->GetBoard()->GetLayerName( layer ) );
reportHeader( _( "Silkscreen clearance resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalRules( SILK_CLEARANCE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( SILK_CLEARANCE_CONSTRAINT, a, b, layer, r );
clearance = constraint.m_Value.Min();
if( compileError )
@ -895,7 +900,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r = m_inspectClearanceDialog->AddPage( m_frame->GetBoard()->GetLayerName( layer ) );
reportHeader( _( "Courtyard clearance resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalRules( COURTYARD_CLEARANCE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( COURTYARD_CLEARANCE_CONSTRAINT, a, b, layer, r );
clearance = constraint.m_Value.Min();
if( compileError )
@ -939,7 +944,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
reportHeader( _( "Hole clearance resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
clearance = constraint.m_Value.Min();
if( compileError )
@ -968,7 +973,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
reportHeader( _( "Hole to hole clearance resolution for:" ), a, b, r );
constraint = drcEngine.EvalRules( HOLE_TO_HOLE_CONSTRAINT, a, b, UNDEFINED_LAYER, r );
constraint = drcEngine->EvalRules( HOLE_TO_HOLE_CONSTRAINT, a, b, UNDEFINED_LAYER, r );
clearance = constraint.m_Value.Min();
if( compileError )
@ -1007,7 +1012,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
r = m_inspectClearanceDialog->AddPage( layerName + wxS( " " ) + _( "Clearance" ) );
reportHeader( _( "Edge clearance resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalRules( EDGE_CLEARANCE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( EDGE_CLEARANCE_CONSTRAINT, a, b, layer, r );
clearance = constraint.m_Value.Min();
if( compileError )
@ -1028,14 +1033,14 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
{
reportHeader( _( "Physical clearance resolution for:" ), a, b, aLayer, r );
constraint = drcEngine.EvalRules( PHYSICAL_CLEARANCE_CONSTRAINT, a, b, aLayer, r );
constraint = drcEngine->EvalRules( PHYSICAL_CLEARANCE_CONSTRAINT, a, b, aLayer, r );
clearance = constraint.m_Value.Min();
if( compileError )
{
reportCompileError( r );
}
else if( !drcEngine.HasRulesForConstraintType( PHYSICAL_CLEARANCE_CONSTRAINT ) )
else if( !drcEngine->HasRulesForConstraintType( PHYSICAL_CLEARANCE_CONSTRAINT ) )
{
r->Report( "" );
r->Report( _( "No 'physical_clearance' constraints defined." ) );
@ -1094,14 +1099,14 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
reportHeader( _( "Physical hole clearance resolution for:" ), a, b, layer, r );
constraint = drcEngine.EvalRules( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
constraint = drcEngine->EvalRules( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, a, b, layer, r );
clearance = constraint.m_Value.Min();
if( compileError )
{
reportCompileError( r );
}
else if( !drcEngine.HasRulesForConstraintType( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT ) )
else if( !drcEngine->HasRulesForConstraintType( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT ) )
{
r->Report( "" );
r->Report( _( "No 'physical_hole_clearance' constraints defined." ) );
@ -1124,7 +1129,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
{
#define EVAL_RULES( constraint, a, b, layer, r ) drcEngine.EvalRules( constraint, a, b, layer, r )
#define EVAL_RULES( constraint, a, b, layer, r ) drcEngine->EvalRules( constraint, a, b, layer, r )
PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
const PCB_SELECTION& selection = selTool->GetSelection();
@ -1147,12 +1152,13 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
m_inspectConstraintsDialog->DeleteAllPages();
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) );
bool compileError = false;
bool courtyardError = false;
DRC_ENGINE drcEngine = makeDRCEngine( &compileError, &courtyardError );
BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( selection.GetItem( 0 ) );
DRC_CONSTRAINT constraint;
bool compileError = false;
bool courtyardError = false;
std::unique_ptr<DRC_ENGINE> drcEngine = makeDRCEngine( &compileError, &courtyardError );
WX_HTML_REPORT_BOX* r = nullptr;
if( item->Type() == PCB_TRACE_T )
@ -1306,7 +1312,7 @@ int BOARD_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent )
+ wxT( " <a href='drc'>" ) + _( "Run DRC for a full analysis." ) + wxT( "</a>" ) );
}
drcEngine.ProcessAssertions( item, []( const DRC_CONSTRAINT* c ){}, r );
drcEngine->ProcessAssertions( item, []( const DRC_CONSTRAINT* c ){}, r );
r->Flush();
m_inspectConstraintsDialog->FinishInitialization();

View File

@ -118,7 +118,8 @@ private:
void onInspectClearanceDialogClosed( wxCommandEvent& aEvent );
void onInspectConstraintsDialogClosed( wxCommandEvent& aEvent );
DRC_ENGINE makeDRCEngine( bool* aCompileError, bool* aCourtyardError = nullptr );
std::unique_ptr<DRC_ENGINE> makeDRCEngine( bool* aCompileError,
bool* aCourtyardError = nullptr );
wxString getItemDescription( BOARD_ITEM* aItem );