Skip to content

Commit 7ea4cbc

Browse files
authored
Merge pull request #3460 from heplesser/fix_sanitizer_errors
Fix corner cases uncovered by Clang sanitizer
2 parents 55b486b + 0574b7f commit 7ea4cbc

12 files changed

+42
-19
lines changed

libnestutil/config.h.in

+2-2
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@
9696
/* Define to 1 if you have usable long long type. */
9797
#cmakedefine HAVE_LONG_LONG 1
9898

99-
/* Define to 1 if you have u_int46_t type. */
99+
/* Define to 1 if you have u_int64_t type. */
100100
#cmakedefine HAVE_U_INT64_T 1
101101

102-
/* Define to 1 if you have uint46_t type. */
102+
/* Define to 1 if you have uint64_t type. */
103103
#cmakedefine HAVE_UINT64_T 1
104104

105105
/* Define to 1 if you have the <mach/mach.h> header file. */

nestkernel/connector_base_impl.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ Connector< ConnectionT >::send_weight_event( const size_t tid,
5050
wr_e.set_port( e.get_port() );
5151
wr_e.set_rport( e.get_rport() );
5252
wr_e.set_stamp( e.get_stamp() );
53-
wr_e.set_sender( e.get_sender() );
53+
// Sender is not available for SecondaryEvents, and not needed, so we do not
54+
// set it to avoid undefined behavior.
5455
wr_e.set_sender_node_id( kernel().connection_manager.get_source_node_id( tid, syn_id_, lcid ) );
5556
wr_e.set_weight( e.get_weight() );
5657
wr_e.set_delay_steps( e.get_delay_steps() );

nestkernel/event.h

+2
Original file line numberDiff line numberDiff line change
@@ -930,12 +930,14 @@ Event::set_sender_node_id_info( const size_t tid, const synindex syn_id, const s
930930
inline Node&
931931
Event::get_receiver() const
932932
{
933+
assert( receiver_ );
933934
return *receiver_;
934935
}
935936

936937
inline Node&
937938
Event::get_sender() const
938939
{
940+
assert( sender_ );
939941
return *sender_;
940942
}
941943

nestkernel/exceptions.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -219,15 +219,15 @@ class UnknownSynapseType : public KernelException
219219

220220
class UnknownNode : public KernelException
221221
{
222-
int id_;
222+
long id_;
223223

224224
public:
225225
UnknownNode()
226226
: KernelException( "UnknownNode" )
227227
, id_( -1 )
228228
{
229229
}
230-
UnknownNode( int id )
230+
UnknownNode( long id )
231231
: KernelException( "UnknownNode" )
232232
, id_( id )
233233
{

nestkernel/modelrange_manager.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ ModelRangeManager::get_model_id( size_t node_id ) const
8282
{
8383
if ( not is_in_range( node_id ) )
8484
{
85-
throw UnknownNode( node_id );
85+
throw UnknownNode( static_cast< long >( node_id ) );
8686
}
8787

88-
int left = -1;
89-
int right = modelranges_.size();
88+
long left = -1;
89+
long right = static_cast< long >( modelranges_.size() );
9090
assert( right >= 1 );
9191

9292
// to ensure thread-safety, use local range_idx
93-
size_t range_idx = right / 2; // start in center
93+
long range_idx = right / 2; // start in center
9494
while ( not modelranges_[ range_idx ].is_in_range( node_id ) )
9595
{
9696
if ( node_id > modelranges_[ range_idx ].get_last_node_id() )

nestkernel/mpi_manager.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,12 @@ nest::MPIManager::communicate( std::vector< long >& local_nodes, std::vector< lo
326326
num_nodes_per_rank[ get_rank() ] = local_nodes.size();
327327
communicate( num_nodes_per_rank );
328328

329-
size_t num_globals = std::accumulate( num_nodes_per_rank.begin(), num_nodes_per_rank.end(), 0 );
329+
const size_t num_globals = std::accumulate( num_nodes_per_rank.begin(), num_nodes_per_rank.end(), 0 );
330+
if ( num_globals == 0 )
331+
{
332+
return; // must return here to avoid passing address to empty global_nodes below
333+
}
334+
330335
global_nodes.resize( num_globals, 0L );
331336

332337
// Set up displacements vector. Entry i specifies the displacement (relative
@@ -337,7 +342,9 @@ nest::MPIManager::communicate( std::vector< long >& local_nodes, std::vector< lo
337342
displacements.at( i ) = displacements.at( i - 1 ) + num_nodes_per_rank.at( i - 1 );
338343
}
339344

340-
MPI_Allgatherv( &( *local_nodes.begin() ),
345+
// avoid dereferencing empty vector
346+
const auto send_ptr = local_nodes.empty() ? nullptr : &local_nodes[ 0 ];
347+
MPI_Allgatherv( send_ptr,
341348
local_nodes.size(),
342349
MPI_Type< long >::type,
343350
&global_nodes[ 0 ],

nestkernel/nest_time.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ Time::compute_max()
6666
const tic_t tmax = std::numeric_limits< tic_t >::max();
6767

6868
tic_t tics;
69-
if ( lmax
70-
< static_cast< tic_t >( static_cast< double >( tmax ) * Range::TICS_PER_STEP_INV ) ) // step size is limiting factor
69+
if ( lmax < tmax * Range::TICS_PER_STEP_INV ) // step size is limiting factor
7170
{
7271
tics = Range::TICS_PER_STEP * ( lmax / Range::INF_MARGIN );
7372
}

sli/interpret.cc

+3-2
Original file line numberDiff line numberDiff line change
@@ -895,15 +895,16 @@ SLIInterpreter::message( std::ostream& out,
895895
// space available (as long as the word is shorter than the
896896
// total width of the printout).
897897
if ( i != 0 and text_str.at( i - 1 ) == ' '
898-
and static_cast< int >( space - i ) > static_cast< int >( width - pos ) )
898+
and static_cast< int >( space ) - static_cast< int >( i )
899+
> static_cast< int >( width ) - static_cast< int >( pos ) )
899900
{
900901
out << std::endl << std::string( indent, ' ' );
901902
pos = 0;
902903
}
903904

904905
// Only print character if we're not at the end of the
905906
// line and the last character is a space.
906-
if ( not( width - pos == 0 and text_str.at( i ) == ' ' ) )
907+
if ( not( static_cast< int >( width ) - static_cast< int >( pos ) == 0 and text_str.at( i ) == ' ' ) )
907908
{
908909
// Print the actual character.
909910
out << text_str.at( i );

sli/scanner.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ Scanner::operator()( Token& t )
558558
// so we cannot use unsigned char c as argument. The
559559
// get() is not picky. --- HEP 2001-08-09
560560
// in->get(c);
561-
c = in->get();
561+
c = static_cast< unsigned char >( in->get() );
562562
if ( col++ == 0 )
563563
{
564564
++line;

sli/slistack.cc

+4-2
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ RollFunction::execute( SLIInterpreter* i ) const
261261
throw ArgumentType( 0 );
262262
}
263263

264-
long& n = idn->get();
264+
const long n = idn->get();
265265
if ( n < 0 )
266266
{
267267
i->raiseerror( i->RangeCheckError );
@@ -273,10 +273,12 @@ RollFunction::execute( SLIInterpreter* i ) const
273273
return;
274274
}
275275

276+
const long k = idk->get();
277+
276278
i->EStack.pop();
277279
i->OStack.pop( 2 );
278280

279-
i->OStack.roll( n, idk->get() );
281+
i->OStack.roll( n, k );
280282
}
281283

282284
/** @BeginDocumentation

sli/tokenstack.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ class TokenStack : private TokenArrayObj
158158
}
159159

160160
void
161-
roll( size_t n, long k )
161+
roll( long n, long k )
162162
{
163163
if ( n < 2 or k == 0 )
164164
{
@@ -180,6 +180,7 @@ class TokenStack : private TokenArrayObj
180180
{
181181
return TokenArrayObj::capacity();
182182
}
183+
183184
Index
184185
load() const
185186
{

testsuite/pytests/test_getnodes.py

+10
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ def test_GetNodes_with_params(self):
6666

6767
self.assertEqual(nodes_exp_ref, nodes_exp)
6868

69+
def test_GetNodes_no_match(self):
70+
"""
71+
Ensure we get an empty result if nothing matches.
72+
73+
This would lead to crashes in MPI-parallel code before #3460.
74+
"""
75+
76+
nodes = nest.GetNodes({"V_m": 100.0})
77+
self.assertEqual(len(nodes), 0)
78+
6979

7080
def suite():
7181
suite = unittest.makeSuite(GetNodesTestCase, "test")

0 commit comments

Comments
 (0)