diff --git a/pcbnew/drc/drc_test_provider_copper_clearance.cpp b/pcbnew/drc/drc_test_provider_copper_clearance.cpp index 46d7fe9e1d..b9dbec6716 100644 --- a/pcbnew/drc/drc_test_provider_copper_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_copper_clearance.cpp @@ -1376,7 +1376,24 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() zone_layer_poly_segs.push_back( seg ); } - std::sort( zone_layer_poly_segs.begin(), zone_layer_poly_segs.end() ); + // Sort by x-coordinates for the sweep-line optimization in the inner + // loop. SEG::operator< must not be used here because it delegates to + // VECTOR2I::operator< which compares by magnitude, violating strict + // weak ordering when mixed with VECTOR2I::operator== for tie-breaking. + std::sort( zone_layer_poly_segs.begin(), zone_layer_poly_segs.end(), + []( const SEG& a, const SEG& b ) -> bool + { + if( a.A.x != b.A.x ) + return a.A.x < b.A.x; + + if( a.A.y != b.A.y ) + return a.A.y < b.A.y; + + if( a.B.x != b.B.x ) + return a.B.x < b.B.x; + + return a.B.y < b.B.y; + } ); } } } @@ -1420,7 +1437,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() polyB = zoneB->GetFill( layer ); } - if( !polyA->BBoxFromCaches().Intersects( polyB->BBoxFromCaches() ) ) + if( !polyA || !polyB + || !polyA->BBoxFromCaches().Intersects( polyB->BBoxFromCaches() ) ) continue; count++;