Skip to content
This repository was archived by the owner on Mar 25, 2025. It is now read-only.

Commit b5f1eae

Browse files
author
Nicolas Cornu
committed
Add a check for external definition that are not thread safe
1 parent 60249f1 commit b5f1eae

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

src/lexer/token_mapping.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,31 @@ const static std::vector<std::string> extern_definitions = {"acos",
246246
"tanh",
247247
"threshold"};
248248
const static std::vector<std::string> need_nt = {"at_time"};
249+
const static std::vector<std::string> not_thread_safe = {"force",
250+
"deflate",
251+
"expfit",
252+
"derivs",
253+
"spline",
254+
"exprand",
255+
"gauss",
256+
"normrand",
257+
"poisrand",
258+
"poisson",
259+
"setseed",
260+
"scop_random",
261+
"boundary",
262+
"romberg",
263+
"invert",
264+
"stepforce",
265+
"schedule",
266+
"set_seed",
267+
"nrn_random_play"};
268+
269+
bool is_external_definitions(const std::string& token) {
270+
return std::find(extern_definitions.cbegin(), extern_definitions.cend(), token) !=
271+
extern_definitions.cend();
272+
}
273+
249274

250275
/**
251276
* Checks if \c token is one of the functions coming from NEURON/CoreNEURON and needs
@@ -259,6 +284,12 @@ bool needs_neuron_thread_first_arg(const std::string& token) {
259284
}
260285

261286

287+
bool is_not_thread_safe(const std::string& token) {
288+
return std::find(not_thread_safe.cbegin(), not_thread_safe.cend(), token) !=
289+
not_thread_safe.cend();
290+
}
291+
292+
262293
/**
263294
* Variables from NEURON that are directly used in NMODL
264295
*

src/lexer/token_mapping.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ std::vector<std::string> get_external_functions();
2727

2828
namespace details {
2929

30+
bool is_external_definitions(const std::string& token);
3031
bool needs_neuron_thread_first_arg(const std::string& token);
32+
bool is_not_thread_safe(const std::string& token);
3133

3234
} // namespace details
3335

src/visitors/semantic_analysis_visitor.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "ast/program.hpp"
55
#include "ast/suffix.hpp"
66
#include "ast/table_statement.hpp"
7+
#include "lexer/token_mapping.hpp"
78
#include "utils/logger.hpp"
89
#include "visitors/visitor_utils.hpp"
910

@@ -78,5 +79,17 @@ void SemanticAnalysisVisitor::visit_destructor_block(const ast::DestructorBlock&
7879
/// -->
7980
}
8081

82+
void SemanticAnalysisVisitor::visit_function_call(const ast::FunctionCall& node) {
83+
/// <-- This code is for check 4
84+
const auto& name = node.get_node_name();
85+
if (details::is_external_definitions(name) && details::is_not_thread_safe(name)) {
86+
logger->critical(
87+
"SemanticAnalysisVisitor :: '{}' is not thread safe and incompatible with CoreNEURON",
88+
name);
89+
check_fail = true;
90+
}
91+
/// -->
92+
}
93+
8194
} // namespace visitor
8295
} // namespace nmodl

src/visitors/semantic_analysis_visitor.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
* (mandatory in mod2c).
2828
* 2. Check that destructor blocks are only inside mod file that are point_process
2929
* 3. A TABLE statement in functions cannot have name list, and should have one in procedures
30+
* 4. Check that an external definition is allowed by CoreNeuron
3031
*/
3132
#include "ast/ast.hpp"
3233
#include "visitors/ast_visitor.hpp"
@@ -59,6 +60,10 @@ class SemanticAnalysisVisitor: public ConstAstVisitor {
5960
/// Visit destructor and check that the file is of type POINT_PROCESS or ARTIFICIAL_CELL
6061
void visit_destructor_block(const ast::DestructorBlock& node) override;
6162

63+
/// Visit function call and check if the function is not thread safe and so not
64+
/// compatible with CoreNeuron
65+
void visit_function_call(const ast::FunctionCall& node) override;
66+
6267
public:
6368
SemanticAnalysisVisitor() = default;
6469

0 commit comments

Comments
 (0)