Add ERC check for local and global labels with same name

Fixes https://gitlab.com/kicad/code/kicad/-/issues/9461
This commit is contained in:
JamesJCode 2024-07-21 23:25:35 +01:00
parent 5120a3bd82
commit 96977d44d9
9 changed files with 792 additions and 2 deletions

View File

@ -1082,6 +1082,65 @@ int ERC_TESTER::TestMultUnitPinConflicts()
}
int ERC_TESTER::TestSameLocalGlobalLabel()
{
int errCount = 0;
std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> globalLabels;
std::unordered_map<wxString, std::pair<SCH_ITEM*, SCH_SHEET_PATH>> localLabels;
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : m_nets )
{
for( CONNECTION_SUBGRAPH* subgraph : net.second )
{
const SCH_SHEET_PATH& sheet = subgraph->GetSheet();
for( SCH_ITEM* item : subgraph->GetItems() )
{
switch( item->Type() )
{
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
{
SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
wxString text = label->GetShownText( &sheet, false );
auto& map = item->Type() == SCH_LABEL_T ? localLabels : globalLabels;
if( !map.count( text ) )
{
map[text] = std::make_pair( label, sheet );
}
}
}
}
}
}
for( auto& [globalText, globalItem] : globalLabels )
{
for( auto& [localText, localItem] : localLabels )
{
if( globalText == localText )
{
std::shared_ptr<ERC_ITEM> ercItem =
ERC_ITEM::Create( ERCE_SAME_LOCAL_GLOBAL_LABEL );
ercItem->SetItems( globalItem.first, localItem.first );
ercItem->SetSheetSpecificPath( globalItem.second );
ercItem->SetItemsSheetPaths( globalItem.second, localItem.second );
SCH_MARKER* marker = new SCH_MARKER( ercItem, globalItem.first->GetPosition() );
globalItem.second.LastScreen()->Append( marker );
errCount++;
}
}
}
return errCount;
}
int ERC_TESTER::TestSimilarLabels()
{
int errors = 0;
@ -1652,12 +1711,14 @@ void ERC_TESTER::RunTests( DS_PROXY_VIEW_ITEM* aDrawingSheet, SCH_EDIT_FRAME* aE
// using case insensitive comparisons)
if( m_settings.IsTestEnabled( ERCE_SIMILAR_LABELS )
|| m_settings.IsTestEnabled( ERCE_SIMILAR_POWER )
|| m_settings.IsTestEnabled( ERCE_SIMILAR_LABEL_AND_POWER ) )
|| m_settings.IsTestEnabled( ERCE_SIMILAR_LABEL_AND_POWER )
|| m_settings.IsTestEnabled( ERCE_SAME_LOCAL_GLOBAL_LABEL ) )
{
if( aProgressReporter )
aProgressReporter->AdvancePhase( _( "Checking labels..." ) );
TestSimilarLabels();
TestSameLocalGlobalLabel();
}
if( m_settings.IsTestEnabled( ERCE_UNRESOLVED_VARIABLE ) )

View File

@ -112,6 +112,12 @@ public:
*/
int TestMultUnitPinConflicts();
/**
* Checks for global and local labels with the same name
* @return the error count
*/
int TestSameLocalGlobalLabel();
/**
* Checks for labels that differ only in capitalization
* @return the error count

View File

@ -128,6 +128,10 @@ ERC_ITEM ERC_ITEM::singleGlobalLabel( ERCE_SINGLE_GLOBAL_LABEL,
_( "Global label only appears once in the schematic"),
wxT( "single_global_label" ) );
ERC_ITEM ERC_ITEM::sameLocalGlobalLabel( ERCE_SAME_LOCAL_GLOBAL_LABEL,
_( "Local and global labels have same name" ),
wxT( "same_local_global_label" ) );
ERC_ITEM ERC_ITEM::differentUnitFootprint( ERCE_DIFFERENT_UNIT_FP,
_( "Different footprint assigned in another unit of the symbol" ),
wxT( "different_unit_footprint" ) );
@ -238,6 +242,7 @@ std::vector<std::reference_wrapper<RC_ITEM>> ERC_ITEM::allItemTypes(
ERC_ITEM::noConnectDangling,
ERC_ITEM::globalLabelDangling,
ERC_ITEM::singleGlobalLabel,
ERC_ITEM::sameLocalGlobalLabel,
ERC_ITEM::wireDangling,
ERC_ITEM::busEntryNeeded,
ERC_ITEM::endpointOffGrid,
@ -290,7 +295,6 @@ std::vector<std::reference_wrapper<RC_ITEM>> ERC_ITEM::allItemTypes(
} );
std::shared_ptr<ERC_ITEM> ERC_ITEM::Create( int aErrorCode )
{
switch( aErrorCode )
@ -315,6 +319,7 @@ std::shared_ptr<ERC_ITEM> ERC_ITEM::Create( int aErrorCode )
case ERCE_SIMILAR_POWER: return std::make_shared<ERC_ITEM>( similarPower );
case ERCE_SIMILAR_LABEL_AND_POWER: return std::make_shared<ERC_ITEM>( similarLabelAndPower );
case ERCE_SINGLE_GLOBAL_LABEL: return std::make_shared<ERC_ITEM>( singleGlobalLabel );
case ERCE_SAME_LOCAL_GLOBAL_LABEL: return std::make_shared<ERC_ITEM>( sameLocalGlobalLabel );
case ERCE_DIFFERENT_UNIT_FP: return std::make_shared<ERC_ITEM>( differentUnitFootprint );
case ERCE_DIFFERENT_UNIT_NET: return std::make_shared<ERC_ITEM>( differentUnitNet );
case ERCE_BUS_ALIAS_CONFLICT: return std::make_shared<ERC_ITEM>( busDefinitionConflict );

View File

@ -215,6 +215,7 @@ private:
static ERC_ITEM labelDangling;
static ERC_ITEM globalLabelDangling;
static ERC_ITEM singleGlobalLabel;
static ERC_ITEM sameLocalGlobalLabel;
static ERC_ITEM similarLabels;
static ERC_ITEM similarPower;
static ERC_ITEM similarLabelAndPower;

View File

@ -100,6 +100,7 @@ ERC_SETTINGS::ERC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
m_ERCSeverities[ERCE_SIMILAR_POWER] = RPT_SEVERITY_WARNING;
m_ERCSeverities[ERCE_SIMILAR_LABEL_AND_POWER] = RPT_SEVERITY_WARNING;
m_ERCSeverities[ERCE_SINGLE_GLOBAL_LABEL] = RPT_SEVERITY_IGNORE;
m_ERCSeverities[ERCE_SAME_LOCAL_GLOBAL_LABEL] = RPT_SEVERITY_WARNING;
m_ERCSeverities[ERCE_GLOBLABEL] = RPT_SEVERITY_WARNING;
m_ERCSeverities[ERCE_DRIVER_CONFLICT] = RPT_SEVERITY_WARNING;
m_ERCSeverities[ERCE_BUS_ENTRY_CONFLICT] = RPT_SEVERITY_WARNING;

View File

@ -52,6 +52,7 @@ enum ERCE_T
ERCE_SIMILAR_POWER, ///< 2 power pins are equal for case insensitive comparisons.
ERCE_SIMILAR_LABEL_AND_POWER, ///< label and pin are equal for case insensitive comparisons.
ERCE_SINGLE_GLOBAL_LABEL, ///< A global label only exists once in the schematic.
ERCE_SAME_LOCAL_GLOBAL_LABEL, ///< 2 labels are equal for case insensitive comparisons.
ERCE_DIFFERENT_UNIT_FP, ///< Different units of the same symbol have different
///< footprints assigned.
ERCE_MISSING_POWER_INPUT_PIN, ///< Symbol has power input pins that are not placed on the

View File

@ -0,0 +1,344 @@
(kicad_sch
(version 20240620)
(generator "eeschema")
(generator_version "8.99")
(uuid "7df99c97-673d-40e6-b057-aca77b016307")
(paper "A4")
(lib_symbols
(symbol "Device:R"
(pin_numbers hide)
(pin_names
(offset 0)
)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(property "Reference" "R"
(at 2.032 0 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Value" "R"
(at 0 0 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Footprint" ""
(at -1.778 0 90)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Datasheet" "~"
(at 0 0 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Description" "Resistor"
(at 0 0 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "ki_keywords" "R res resistor"
(at 0 0 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "ki_fp_filters" "R_*"
(at 0 0 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(symbol "R_0_1"
(rectangle
(start -1.016 -2.54)
(end 1.016 2.54)
(stroke
(width 0.254)
(type default)
)
(fill
(type none)
)
)
)
(symbol "R_1_1"
(pin passive line
(at 0 3.81 270)
(length 1.27)
(name "~"
(effects
(font
(size 1.27 1.27)
)
)
)
(number "1"
(effects
(font
(size 1.27 1.27)
)
)
)
)
(pin passive line
(at 0 -3.81 90)
(length 1.27)
(name "~"
(effects
(font
(size 1.27 1.27)
)
)
)
(number "2"
(effects
(font
(size 1.27 1.27)
)
)
)
)
)
(embedded_fonts no)
)
)
(no_connect
(at 101.6 57.15)
(uuid "7397bf6f-9851-4d7a-9e24-3f577e3db8aa")
)
(no_connect
(at 142.24 57.15)
(uuid "fa09bca5-a22d-4f86-81d2-295d08f7e092")
)
(wire
(pts
(xy 109.22 57.15) (xy 134.62 57.15)
)
(stroke
(width 0)
(type default)
)
(uuid "96de3066-8e25-4a46-b2bd-c800b6386cc2")
)
(label "A_NET"
(at 115.57 57.15 0)
(fields_autoplaced yes)
(effects
(font
(size 1.27 1.27)
)
(justify left bottom)
)
(uuid "60946a3e-a035-4844-ac74-74b1c1150931")
)
(symbol
(lib_id "Device:R")
(at 105.41 57.15 90)
(unit 1)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(dnp no)
(fields_autoplaced yes)
(uuid "7a8e10c5-2755-4793-a528-af668c294a38")
(property "Reference" "R1"
(at 105.41 50.8 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Value" "R"
(at 105.41 53.34 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Footprint" ""
(at 105.41 58.928 90)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Datasheet" "~"
(at 105.41 57.15 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Description" "Resistor"
(at 105.41 57.15 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(pin "2"
(uuid "2c6d97e6-4a07-48b6-8856-54e9b503152e")
)
(pin "1"
(uuid "4ffa9d94-993e-4e47-b8f1-a1ebbbe570c3")
)
(instances
(project ""
(path "/7df99c97-673d-40e6-b057-aca77b016307"
(reference "R1")
(unit 1)
)
)
)
)
(symbol
(lib_id "Device:R")
(at 138.43 57.15 90)
(unit 1)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(dnp no)
(fields_autoplaced yes)
(uuid "86bacf67-8821-4e05-85ae-0959386a7716")
(property "Reference" "R2"
(at 138.43 50.8 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Value" "R"
(at 138.43 53.34 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Footprint" ""
(at 138.43 58.928 90)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Datasheet" "~"
(at 138.43 57.15 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Description" "Resistor"
(at 138.43 57.15 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(pin "2"
(uuid "7b7c1f05-683e-4c0d-8cc5-e5928fbcc935")
)
(pin "1"
(uuid "a31b62f8-170a-446a-b72f-8d99e2d48cdd")
)
(instances
(project "same_local_global_label"
(path "/7df99c97-673d-40e6-b057-aca77b016307"
(reference "R2")
(unit 1)
)
)
)
)
(sheet
(at 151.13 68.58)
(size 35.56 31.75)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(dnp no)
(fields_autoplaced yes)
(stroke
(width 0.1524)
(type solid)
)
(fill
(color 0 0 0 0.0000)
)
(uuid "e8449c08-f1e4-4195-9b34-1c9c4b63220e")
(property "Sheetname" "Subsheet"
(at 151.13 67.8684 0)
(effects
(font
(size 1.27 1.27)
)
(justify left bottom)
)
)
(property "Sheetfile" "same_local_global_label_subsheet.kicad_sch"
(at 151.13 100.9146 0)
(effects
(font
(size 1.27 1.27)
)
(justify left top)
)
)
(instances
(project "same_local_global_label"
(path "/7df99c97-673d-40e6-b057-aca77b016307"
(page "2")
)
)
)
)
(sheet_instances
(path "/"
(page "1")
)
)
(embedded_fonts no)
)

View File

@ -0,0 +1,333 @@
(kicad_sch
(version 20240620)
(generator "eeschema")
(generator_version "8.99")
(uuid "6efbd543-d9e6-40d5-9985-cbe8221e04b5")
(paper "A4")
(lib_symbols
(symbol "Device:R"
(pin_numbers hide)
(pin_names
(offset 0)
)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(property "Reference" "R"
(at 2.032 0 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Value" "R"
(at 0 0 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Footprint" ""
(at -1.778 0 90)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Datasheet" "~"
(at 0 0 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Description" "Resistor"
(at 0 0 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "ki_keywords" "R res resistor"
(at 0 0 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "ki_fp_filters" "R_*"
(at 0 0 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(symbol "R_0_1"
(rectangle
(start -1.016 -2.54)
(end 1.016 2.54)
(stroke
(width 0.254)
(type default)
)
(fill
(type none)
)
)
)
(symbol "R_1_1"
(pin passive line
(at 0 3.81 270)
(length 1.27)
(name "~"
(effects
(font
(size 1.27 1.27)
)
)
)
(number "1"
(effects
(font
(size 1.27 1.27)
)
)
)
)
(pin passive line
(at 0 -3.81 90)
(length 1.27)
(name "~"
(effects
(font
(size 1.27 1.27)
)
)
)
(number "2"
(effects
(font
(size 1.27 1.27)
)
)
)
)
)
(embedded_fonts no)
)
)
(junction
(at 129.54 68.58)
(diameter 0)
(color 0 0 0 0)
(uuid "9be06346-589f-4b9d-82c8-8317945e5717")
)
(no_connect
(at 149.86 68.58)
(uuid "db2eb20f-75ed-4ba0-b21d-119943abd49e")
)
(no_connect
(at 109.22 68.58)
(uuid "dcb1b1ff-2a87-4cef-8589-1bfdb21cc289")
)
(wire
(pts
(xy 129.54 68.58) (xy 142.24 68.58)
)
(stroke
(width 0)
(type default)
)
(uuid "7a08618b-9e32-4a39-9292-fd1f3009bd8f")
)
(wire
(pts
(xy 129.54 68.58) (xy 129.54 74.93)
)
(stroke
(width 0)
(type default)
)
(uuid "b6ac3635-3829-4d67-a047-1a42e4ca0ff9")
)
(wire
(pts
(xy 116.84 68.58) (xy 129.54 68.58)
)
(stroke
(width 0)
(type default)
)
(uuid "e132e406-ea7e-4035-9f83-2ec4dfc80c7e")
)
(global_label "A_NET"
(shape input)
(at 129.54 74.93 270)
(fields_autoplaced yes)
(effects
(font
(size 1.27 1.27)
)
(justify right)
)
(uuid "df841051-5ce8-4473-b8b2-556c0cd93135")
(property "Intersheetrefs" "${INTERSHEET_REFS}"
(at 129.54 83.4185 90)
(effects
(font
(size 1.27 1.27)
)
(justify right)
(hide yes)
)
)
)
(symbol
(lib_id "Device:R")
(at 146.05 68.58 90)
(unit 1)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(dnp no)
(fields_autoplaced yes)
(uuid "4e8baf80-758e-40eb-ba65-5d112459944a")
(property "Reference" "R4"
(at 146.05 62.23 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Value" "R"
(at 146.05 64.77 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Footprint" ""
(at 146.05 70.358 90)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Datasheet" "~"
(at 146.05 68.58 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Description" "Resistor"
(at 146.05 68.58 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(pin "2"
(uuid "93cc3cdb-088e-421e-b501-76d5ba19ec22")
)
(pin "1"
(uuid "2d054537-2dfa-4d56-9f7c-0d7977c0a99c")
)
(instances
(project "same_local_global_label"
(path "/7df99c97-673d-40e6-b057-aca77b016307/e8449c08-f1e4-4195-9b34-1c9c4b63220e"
(reference "R4")
(unit 1)
)
)
)
)
(symbol
(lib_id "Device:R")
(at 113.03 68.58 90)
(unit 1)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(dnp no)
(fields_autoplaced yes)
(uuid "5162a798-80b8-412e-b0b6-8fc67057fd6f")
(property "Reference" "R3"
(at 113.03 62.23 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Value" "R"
(at 113.03 64.77 90)
(effects
(font
(size 1.27 1.27)
)
)
)
(property "Footprint" ""
(at 113.03 70.358 90)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Datasheet" "~"
(at 113.03 68.58 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(property "Description" "Resistor"
(at 113.03 68.58 0)
(effects
(font
(size 1.27 1.27)
)
(hide yes)
)
)
(pin "2"
(uuid "0e0d0084-16ec-4b9f-a25e-4354533752b9")
)
(pin "1"
(uuid "b8a98347-4a5e-487b-b7e7-3c9e267b7d61")
)
(instances
(project "same_local_global_label"
(path "/7df99c97-673d-40e6-b057-aca77b016307/e8449c08-f1e4-4195-9b34-1c9c4b63220e"
(reference "R3")
(unit 1)
)
)
)
)
)

View File

@ -76,3 +76,41 @@ BOOST_FIXTURE_TEST_CASE( ERCLabelCapitalization, ERC_REGRESSION_TEST_FIXTURE )
<< reportWriter.GetTextReport() );
}
}
BOOST_FIXTURE_TEST_CASE( ERCSameLocalGlobalLabel, ERC_REGRESSION_TEST_FIXTURE )
{
LOCALE_IO dummy;
// Check for Errors when using rule area netclass directives
std::vector<std::pair<wxString, int>> tests = { { "same_local_global_label", 1 } };
for( const std::pair<wxString, int>& test : tests )
{
KI_TEST::LoadSchematic( m_settingsManager, test.first, m_schematic );
ERC_SETTINGS& settings = m_schematic->ErcSettings();
SHEETLIST_ERC_ITEMS_PROVIDER errors( m_schematic.get() );
// Skip the "Modified symbol" warning
settings.m_ERCSeverities[ERCE_LIB_SYMBOL_ISSUES] = RPT_SEVERITY_IGNORE;
settings.m_ERCSeverities[ERCE_LIB_SYMBOL_MISMATCH] = RPT_SEVERITY_IGNORE;
// Configure the rules under test
settings.m_ERCSeverities[ERCE_SAME_LOCAL_GLOBAL_LABEL] = RPT_SEVERITY_ERROR;
m_schematic->ConnectionGraph()->RunERC();
ERC_TESTER tester( m_schematic.get() );
tester.TestSameLocalGlobalLabel();
errors.SetSeverities( RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING );
ERC_REPORT reportWriter( m_schematic.get(), EDA_UNITS::MILLIMETRES );
BOOST_CHECK_MESSAGE( errors.GetCount() == test.second,
"Expected " << test.second << " errors in " << test.first.ToStdString()
<< " but got " << errors.GetCount() << "\n"
<< reportWriter.GetTextReport() );
}
}