From 7ac0ca9c144e553acf510ab1bedd52d89c14a5bf Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Thu, 13 Jul 2023 10:53:50 +0200 Subject: [PATCH] Pcbnew, undo_redo: Do not cast to BOARD_ITEM items that are only EDA_ITEM A BOARD_ITEM is derived from EDA_ITEM, so the cast is not possible Fixes #15177 https://gitlab.com/kicad/code/kicad/-/issues/15177 --- pcbnew/undo_redo.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/pcbnew/undo_redo.cpp b/pcbnew/undo_redo.cpp index b112c3726e..edc87e55cd 100644 --- a/pcbnew/undo_redo.cpp +++ b/pcbnew/undo_redo.cpp @@ -236,12 +236,16 @@ void PCB_BASE_EDIT_FRAME::saveCopyInUndoList( PICKED_ITEMS_LIST* commandToUndo, case UNDO_REDO::CHANGED: case UNDO_REDO::DRILLORIGIN: case UNDO_REDO::GRIDORIGIN: - // If we don't yet have a copy in the link, set one up if( !commandToUndo->GetPickedItemLink( ii ) ) { - BOARD_ITEM* clone = static_cast( item->Clone() ); - clone->SetParentGroup( nullptr ); + // Warning: DRILLORIGIN and GRIDORIGIN undo/redo command create EDA_ITEMs + // that cannot be casted blindly to BOARD_ITEMs (a BOARD_ITEM is derived from a EDA_ITEM) + // Especially SetParentGroup() does not exist in EDA_ITEM + EDA_ITEM* clone = static_cast( item->Clone() ); + + if( BOARD_ITEM* brdclone = dynamic_cast( clone ) ) + brdclone->SetParentGroup( nullptr ); commandToUndo->SetPickedItemLink( clone, ii ); } @@ -546,15 +550,16 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) case UNDO_REDO::DRILLORIGIN: case UNDO_REDO::GRIDORIGIN: { - BOARD_ITEM* item = (BOARD_ITEM*) eda_item; - BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii ); + // Warning: DRILLORIGIN and GRIDORIGIN undo/redo command create EDA_ITEMs + // that cannot be casted to BOARD_ITEMs + EDA_ITEM* image = aList->GetPickedItemLink( ii ); VECTOR2D origin = image->GetPosition(); image->SetPosition( eda_item->GetPosition() ); if( aList->GetPickedItemStatus( ii ) == UNDO_REDO::DRILLORIGIN ) - BOARD_EDITOR_CONTROL::DoSetDrillOrigin( view, this, item, origin ); + BOARD_EDITOR_CONTROL::DoSetDrillOrigin( view, this, eda_item, origin ); else - PCB_CONTROL::DoSetGridOrigin( view, this, item, origin ); + PCB_CONTROL::DoSetGridOrigin( view, this, eda_item, origin ); break; }