Commit ce781438 authored by Michael Kuron's avatar Michael Kuron Committed by Kai Szuttor

Clang Address Sanitizer and Undefinded Behavior Sanitizer (#2130)

* Add support for Clang sanitizers

* Fixes per Clang ASAN and UBSAN

* Enable ASAN and UBSAN in Clang CI build

* Add tags to CI jobs

* Some more ASAN/UBSAN fixes

* Abort even when non-fatal undefined behavior is encountered

* Sanitize some more undefined behavior

Mostly divisions by zero, but also some nullptrs bound to references and nonnull arguments

* Cleanup

* MSAN is experimental for now
parent 5db2beb7
Pipeline #3010 passed with stages
in 71 minutes and 57 seconds
......@@ -19,10 +19,14 @@ check_permission:
allow_failure: false
script:
- exit 0
tags:
- linux
status_pending:
stage: prepare
script: bash maintainer/gh_post_status.sh pending
tags:
- linux
### Builds without CUDA
......@@ -31,12 +35,18 @@ default:
script:
- export with_cuda=false myconfig=default with_coverage=true
- bash maintainer/CI/build_cmake.sh
tags:
- docker
- linux
maxset:
stage: build
script:
- export with_cuda=false myconfig=maxset with_coverage=true
- bash maintainer/CI/build_cmake.sh
tags:
- docker
- linux
maxset-python3:
stage: build
......@@ -44,12 +54,18 @@ maxset-python3:
script:
- export myconfig=maxset with_coverage=true python_version=3
- bash maintainer/CI/build_cmake.sh
tags:
- docker
- linux
nocheckmaxset:
stage: build
script:
- export with_cuda=false myconfig=nocheck-maxset make_check=false
- bash maintainer/CI/build_cmake.sh
tags:
- docker
- linux
### Builds with different Distributions
......@@ -62,6 +78,9 @@ debian:9:
- export with_cuda=false
- export myconfig=maxset make_check=false
- bash maintainer/CI/build_cmake.sh
tags:
- docker
- linux
opensuse:42.3:
stage: build
......@@ -69,6 +88,9 @@ opensuse:42.3:
script:
- export with_cuda=false myconfig=maxset make_check=false
- bash maintainer/CI/build_cmake.sh
tags:
- docker
- linux
opensuse:15.0:
stage: build
......@@ -76,6 +98,9 @@ opensuse:15.0:
script:
- export with_cuda=false myconfig=maxset make_check=false
- bash maintainer/CI/build_cmake.sh
tags:
- docker
- linux
centos:7:
stage: build
......@@ -83,6 +108,9 @@ centos:7:
script:
- export with_cuda=false myconfig=maxset make_check=false
- bash maintainer/CI/build_cmake.sh
tags:
- docker
- linux
fedora:
stage: build
......@@ -90,6 +118,9 @@ fedora:
script:
- export with_cuda=false myconfig=maxset make_check=false
- bash maintainer/CI/build_cmake.sh
tags:
- docker
- linux
#ubuntu:1404 not needed: used in cuda:8.0
#ubuntu:1604 not needed: used in cuda:9.0
......@@ -103,6 +134,10 @@ cuda-shanchen:
script:
- export myconfig=shanchen with_coverage=true python_version=3
- bash maintainer/cuda_build.sh
tags:
- docker
- linux
- cuda
cuda-maxset:
stage: build
......@@ -114,6 +149,10 @@ cuda-maxset:
paths:
- build/
expire_in: 1 week
tags:
- docker
- linux
- cuda
cuda8-maxset:
stage: build
......@@ -125,6 +164,10 @@ cuda8-maxset:
paths:
- build/
expire_in: 1 week
tags:
- docker
- linux
- cuda
empty:
stage: build
......@@ -132,6 +175,10 @@ empty:
script:
- export myconfig=empty python_version=3
- bash maintainer/CI/build_cmake.sh
tags:
- docker
- linux
- cuda
### Builds with OS X
......@@ -165,8 +212,13 @@ clang:6.0:
stage: build
image: gitlab.icp.uni-stuttgart.de:4567/espressomd/docker/$CI_JOB_NAME
script:
- export myconfig=maxset with_coverage=false with_static_analysis=true
- export myconfig=maxset with_coverage=false with_static_analysis=true with_asan=true with_ubsan=true
- bash maintainer/cuda_build.sh
tags:
- docker
- linux
- cuda
- ptrace
intel:15:
stage: build
......@@ -174,6 +226,10 @@ intel:15:
script:
- export myconfig=maxset with_coverage=false I_MPI_SHM_LMT=shm
- bash maintainer/cuda_build.sh
tags:
- docker
- linux
- cuda
intel:17:
stage: build
......@@ -181,6 +237,10 @@ intel:17:
script:
- export myconfig=maxset with_coverage=false I_MPI_SHM_LMT=shm
- bash maintainer/cuda_build.sh
tags:
- docker
- linux
- cuda
### Other builds
......@@ -192,6 +252,10 @@ check_sphinx:
when: on_success
script:
- cd ${CI_PROJECT_DIR}; cd build && find ./ -exec touch -c -t 203901010000 {} \; && make sphinx
tags:
- docker
- linux
- cuda
check_with_odd_no_of_processors:
stage: additional_checks
......@@ -202,6 +266,10 @@ check_with_odd_no_of_processors:
script:
- export myconfig=maxset with_coverage=true python_version=3 build_procs=3 check_procs=3 check_odd_only=true
- bash maintainer/cuda_build.sh
tags:
- docker
- linux
- cuda
deploy_documentation:
stage: deploy
......@@ -223,16 +291,24 @@ deploy_documentation:
rsync -avz --delete -e "ssh -i ${HOME}/.ssh/espresso_rsa" ./* espresso@elk.icp.uni-stuttgart.de:/home/espresso/public_html/html/doc
- cd ../../doxygen/html &&
rsync -avz --delete -e "ssh -i ${HOME}/.ssh/espresso_rsa" ./* espresso@elk.icp.uni-stuttgart.de:/home/espresso/public_html/html/dox
tags:
- docker
- linux
- cuda
status_success:
stage: result
script: bash maintainer/gh_post_status.sh success
when: on_success
tags:
- linux
dependencies: []
status_failure:
stage: result
script: bash maintainer/gh_post_status.sh failure
when: on_failure
tags:
- linux
dependencies: []
......@@ -74,10 +74,17 @@ option(WITH_HDF5 "Build with HDF5 support" ON)
option(WITH_TESTS "Enable tests" ON)
option(WITH_SCAFACOS "Build with Scafacos support" ON)
option(WITH_VALGRIND_INSTRUMENTATION "Build with valgrind instrumentation markers" OFF)
option(WITH_COVERAGE "Generate code coverage report" OFF)
if( CMAKE_VERSION VERSION_GREATER 3.5.2 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
option(WITH_CLANG_TIDY "Run Clang-Tidy during compilation" OFF)
endif()
if( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
option(WITH_COVERAGE "Generate code coverage report" OFF)
option(WITH_ASAN "Build with address sanitizer" OFF)
option(WITH_UBSAN "Build with undefined behavior sanitizer" OFF)
endif()
if( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT APPLE )
option(WITH_MSAN "Build with memory sanitizer (experimental; requires a memory-sanitized Python interpreter)" OFF)
endif()
option(WARNINGS_ARE_ERRORS "Treat warnings as errors during compilation" OFF)
# Write compile commands to file, for various tools...
......@@ -374,6 +381,21 @@ endif()
set(CMAKE_MACOSX_RPATH TRUE)
if( WITH_ASAN AND WITH_MSAN )
message(FATAL_ERROR "Address sanitizer and memory sanitizer cannot be enabled simultaneously")
endif()
if( WITH_ASAN )
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -O1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
endif()
if( WITH_MSAN )
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -O1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=memory -fno-omit-frame-pointer")
endif()
if( WITH_UBSAN )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
endif()
#######################################################################
# Testing
#######################################################################
......
......@@ -43,6 +43,8 @@ function cmd {
[ -z "$with_fftw" ] && with_fftw="true"
[ -z "$with_python_interface" ] && with_python_interface="true"
[ -z "$with_coverage" ] && with_coverage="false"
[ -z "$with_ubsan" ] && with_ubsan="false"
[ -z "$with_asan" ] && with_asan="false"
[ -z "$with_static_analysis" ] && with_static_analysis="false"
[ -z "$myconfig" ] && myconfig="default"
[ -z "$check_procs" ] && check_procs=2
......@@ -66,7 +68,10 @@ fi
outp insource srcdir builddir make_check \
cmake_params with_fftw \
with_python_interface with_coverage with_static_analysis myconfig check_procs build_procs check_odd_only \
with_python_interface with_coverage \
with_ubsan with_asan \
with_static_analysis myconfig check_procs \
build_procs check_odd_only \
with_static_analysis myconfig \
check_procs build_procs \
python_version with_cuda
......@@ -153,6 +158,14 @@ if [ $with_coverage = "true" ]; then
cmake_params="-DWITH_COVERAGE=ON $cmake_params"
fi
if [ $with_asan = "true" ]; then
cmake_params="-DWITH_ASAN=ON $cmake_params"
fi
if [ $with_ubsan = "true" ]; then
cmake_params="-DWITH_UBSAN=ON $cmake_params"
fi
if [ $with_static_analysis = "true" ]; then
cmake_params="-DWITH_CLANG_TIDY=ON $cmake_params"
fi
......
......@@ -3,8 +3,13 @@ file(GLOB EspressoCore_SRC
if( WITH_COVERAGE )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Og --coverage -fprofile-arcs -ftest-coverage")
link_libraries(gcov)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -Og")
if( CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
link_libraries(gcov)
endif()
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
......
......@@ -29,6 +29,13 @@ class GetLocalParts {
public:
Range operator()() const {
if (local_particles == nullptr) {
auto begin =
skip_it(nullptr, nullptr, SkipIfNullOrGhost());
return Utils::make_range(make_indirect_iterator(begin),
make_indirect_iterator(begin));
}
auto begin =
skip_it(local_particles, local_particles + max_seen_particle + 1,
SkipIfNullOrGhost());
......
......@@ -53,9 +53,9 @@ ParticleForce ShapeBasedConstraint::force(const Particle &p, const Vector3d &fol
if (checkIfInteraction(ia_params)) {
m_shape->calculate_dist(folded_pos.data(), &dist, dist_vec.data());
outer_normal_vec=-dist_vec/dist_vec.norm();
if (dist > 0) {
outer_normal_vec=-dist_vec/dist;
auto const dist2 = dist * dist;
calc_non_bonded_pair_force(&p, &part_rep, ia_params, dist_vec.data(), dist, dist2,
force.data(), torque1.data(), torque2.data());
......
......@@ -674,7 +674,7 @@ void dd_on_geometry_change(int flags) {
/* If we are not in a hurry, check if we can maybe optimize the cell
system by using smaller cells. */
if (!(flags & CELL_FLAG_FAST)) {
if (!(flags & CELL_FLAG_FAST) && max_range > 0) {
int i;
for (i = 0; i < 3; i++) {
int poss_size = (int)floor(local_box_l[i] / max_range);
......
......@@ -108,10 +108,14 @@ inline void init_ghost_force(Particle *part) {
/* and rescale quaternion, so it is exactly of unit length */
scale = sqrt(Utils::sqr(part->r.quat[0]) + Utils::sqr(part->r.quat[1]) +
Utils::sqr(part->r.quat[2]) + Utils::sqr(part->r.quat[3]));
part->r.quat[0] /= scale;
part->r.quat[1] /= scale;
part->r.quat[2] /= scale;
part->r.quat[3] /= scale;
if (scale == 0) {
part->r.quat[0] = 1;
} else {
part->r.quat[0] /= scale;
part->r.quat[1] /= scale;
part->r.quat[2] /= scale;
part->r.quat[3] /= scale;
}
}
#endif
}
......@@ -163,10 +167,14 @@ inline void init_local_particle_force(Particle *part) {
/* and rescale quaternion, so it is exactly of unit length */
scale = sqrt(Utils::sqr(part->r.quat[0]) + Utils::sqr(part->r.quat[1]) +
Utils::sqr(part->r.quat[2]) + Utils::sqr(part->r.quat[3]));
part->r.quat[0] /= scale;
part->r.quat[1] /= scale;
part->r.quat[2] /= scale;
part->r.quat[3] /= scale;
if (scale == 0) {
part->r.quat[0] = 1;
} else {
part->r.quat[0] /= scale;
part->r.quat[1] /= scale;
part->r.quat[2] /= scale;
part->r.quat[3] /= scale;
}
}
#endif
}
......
......@@ -228,7 +228,7 @@ std::size_t hash_value(Datafield const &field) {
return hash_range(ptr, ptr + field.dimension);
}
case Datafield::Type::BOOL: {
auto ptr = reinterpret_cast<int *>(field.data);
auto ptr = reinterpret_cast<char *>(field.data);
return hash_range(ptr, ptr + 1);
}
case Datafield::Type::DOUBLE: {
......@@ -247,7 +247,8 @@ void common_bcast_parameter(int i) {
comm_cart);
break;
case Datafield::Type::BOOL:
MPI_Bcast((int *)fields.at(i).data, 1, MPI_INT, 0, comm_cart);
static_assert(sizeof(bool) == sizeof(char), "bool datatype does not have the expected size");
MPI_Bcast((char *)fields.at(i).data, 1, MPI_CHAR, 0, comm_cart);
break;
case Datafield::Type::DOUBLE:
MPI_Bcast((double *)fields.at(i).data, fields.at(i).dimension, MPI_DOUBLE,
......
......@@ -258,7 +258,7 @@ void lb_reinit_parameters_gpu() {
for(ii=0;ii<LB_COMPONENTS;++ii){
lbpar_gpu.mu[ii] = 0.0;
if (lbpar_gpu.viscosity[ii] > 0.0) {
if (lbpar_gpu.viscosity[ii] > 0.0 && lbpar_gpu.agrid > 0.0 && lbpar_gpu.tau > 0.0 ) {
/* Eq. (80) Duenweg, Schiller, Ladd, PRE 76(3):036704 (2007). */
lbpar_gpu.gamma_shear[ii] = 1. - 2./(6.*lbpar_gpu.viscosity[ii]*lbpar_gpu.tau/(lbpar_gpu.agrid*lbpar_gpu.agrid) + 1.);
}
......@@ -443,15 +443,20 @@ void lb_lbfluid_particles_add_momentum(float momentum[3]) {
auto & parts = partCfg();
auto const n_part = parts.size();
// set_particle_v invalidates the parts pointer, so we need to defer setting the new values
std::vector<std::pair<int, double[3]>> new_velocity(n_part);
size_t i = 0;
for (auto const &p : parts) {
double new_velocity[3] = {
p.m.v[0] +
momentum[0] / p.p.mass / n_part,
p.m.v[1] +
momentum[1] / p.p.mass / n_part,
p.m.v[2] +
momentum[2] / p.p.mass / n_part};
set_particle_v(p.p.identity, new_velocity);
new_velocity[i].first = p.p.identity;
const auto factor = 1 / (p.p.mass * n_part);
new_velocity[i].second[0] = p.m.v[0] + momentum[0] * factor;
new_velocity[i].second[1] = p.m.v[1] + momentum[1] * factor;
new_velocity[i].second[2] = p.m.v[2] + momentum[2] * factor;
++i;
}
for (auto &p : new_velocity) {
set_particle_v(p.first, p.second);
}
}
......
......@@ -353,18 +353,6 @@ void p3m_init() {
p3m.send_grid = Utils::realloc(p3m.send_grid, sizeof(double) * p3m.sm.max);
p3m.recv_grid = Utils::realloc(p3m.recv_grid, sizeof(double) * p3m.sm.max);
/* fix box length dependent constants */
p3m_scaleby_box_l();
if (p3m.params.inter > 0)
p3m_interpolate_charge_assignment_function();
/* position offset for calc. of first meshpoint */
p3m.pos_shift =
std::floor((p3m.params.cao - 1) / 2.0) - (p3m.params.cao % 2) / 2.0;
P3M_TRACE(
fprintf(stderr, "%d: p3m.pos_shift = %f\n", this_node, p3m.pos_shift));
/* FFT */
P3M_TRACE(
fprintf(stderr, "%d: p3m.rs_mesh ADR=%p\n", this_node, (void*) p3m.rs_mesh));
......@@ -380,6 +368,18 @@ void p3m_init() {
/* k-space part: */
p3m_calc_differential_operator();
/* fix box length dependent constants */
p3m_scaleby_box_l();
if (p3m.params.inter > 0)
p3m_interpolate_charge_assignment_function();
/* position offset for calc. of first meshpoint */
p3m.pos_shift =
std::floor((p3m.params.cao - 1) / 2.0) - (p3m.params.cao % 2) / 2.0;
P3M_TRACE(
fprintf(stderr, "%d: p3m.pos_shift = %f\n", this_node, p3m.pos_shift));
p3m_count_charged_particles();
P3M_TRACE(fprintf(stderr, "%d: p3m-charges initialized\n", this_node));
......@@ -1207,7 +1207,12 @@ template <int cao> void calc_influence_function_force() {
Utils::sqr(p3m.d_op[RY][n[KY]] / box_l[RY]) +
Utils::sqr(p3m.d_op[RZ][n[KZ]] / box_l[RZ]);
fak3 = fak1 / (fak2 * Utils::sqr(denominator));
if(fak2 == 0) {
fak3 = 0;
}
else
fak3 = fak1 / (fak2 * Utils::sqr(denominator));
p3m.g_force[ind] = 2 * fak3 / (PI);
}
}
......
......@@ -37,7 +37,10 @@ int tabulated_set_params(int part_type_a, int part_type_b, double min,
data->TAB.maxval = max;
data->TAB.minval = min;
data->TAB.invstepsize = static_cast<double>(force.size() - 1) / (max - min);
if (max == min)
data->TAB.invstepsize = 0;
else
data->TAB.invstepsize = static_cast<double>(force.size() - 1) / (max - min);
data->TAB.force_tab = force;
data->TAB.energy_tab = energy;
......
......@@ -52,6 +52,10 @@ function(UNIT_TEST)
add_test(${TEST_NAME} ${TEST_NAME})
endif( )
if(WARNINGS_ARE_ERRORS)
set_tests_properties(${TEST_NAME} PROPERTIES ENVIRONMENT "UBSAN_OPTIONS=suppressions=${CMAKE_SOURCE_DIR}/tools/ubsan-suppressions.txt:halt_on_error=1:print_stacktrace=1 ASAN_OPTIONS=halt_on_error=1:detect_leaks=0 MSAN_OPTIONS=halt_on_error=1")
endif()
add_dependencies(check_unit_tests ${TEST_NAME})
endfunction(UNIT_TEST)
......
......@@ -75,12 +75,13 @@ inline std::vector<double> Accumulator::get_mean() const {
inline std::vector<double> Accumulator::get_variance() const {
std::vector<double> res;
std::transform(m_acc_data.begin(), m_acc_data.end(), std::back_inserter(res),
if(m_n==1){
res=std::vector<double>(m_acc_data.size(),std::numeric_limits<double>::max());
} else {
std::transform(m_acc_data.begin(), m_acc_data.end(), std::back_inserter(res),
[this](const AccumulatorData<double> &acc_data) {
return acc_data.m/(static_cast<double>(m_n)-1); //numerically stable sample variance, see https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
});
if(m_n==1){
res=std::vector<double>(m_acc_data.size(),std::numeric_limits<double>::max());
}
return res;
}
......
......@@ -15,6 +15,9 @@ template <typename T>
void gatherv_impl(const boost::mpi::communicator &comm, const T *in_values,
int in_size, T *out_values, const int *sizes,
const int *displs, int root, boost::mpl::true_) {
if (in_values == nullptr)
return;
MPI_Datatype type = boost::mpi::get_mpi_datatype<T>(*in_values);
/* in-place ? */
......
......@@ -14,6 +14,43 @@ else
fi
export PYTHONPATH
if [ "@CMAKE_CXX_COMPILER_ID@" != "GNU" -a "@WITH_ASAN@" = "ON" ]; then
asan_lib=$("@CMAKE_CXX_COMPILER@" /dev/null -### -o /dev/null -fsanitize=address 2>&1 | grep -o '[" ][^" ]*libclang_rt.asan[^" ]*[^s][" ]' | sed 's/[" ]//g' | sed 's/\.a$/.so/g')
for lib in $asan_lib; do
test -f $lib && LD_PRELOAD="$lib $LD_PRELOAD"
done
fi
if [ "@CMAKE_CXX_COMPILER_ID@" != "GNU" -a "@WITH_UBSAN@" = "ON" -a "@WITH_ASAN@" != "ON" ]; then
ubsan_lib=$("@CMAKE_CXX_COMPILER@" /dev/null -### -o /dev/null -fsanitize=undefined 2>&1 | grep -o '[" ][^" ]*libclang_rt.ubsan[^" ]*[^s][" ]' | sed 's/[" ]//g' | sed 's/\.a$/.so/g')
for lib in $ubsan_lib; do
test -f $lib && LD_PRELOAD="$lib $LD_PRELOAD"
done
fi
export LD_PRELOAD
if [ "@WITH_UBSAN@" = "ON" ]; then
if [ "@WARNINGS_ARE_ERRORS@" = "ON" ]; then
export UBSAN_OPTIONS="halt_on_error=1 print_stacktrace=1 suppressions=@CMAKE_SOURCE_DIR@/tools/ubsan-suppressions.txt $UBSAN_OPTIONS"
else
export UBSAN_OPTIONS="print_stacktrace=1 suppressions=@CMAKE_SOURCE_DIR@/tools/ubsan-suppressions.txt $UBSAN_OPTIONS"
fi
fi
if [ "@WITH_ASAN@" = "ON" ]; then
if [ "@WARNINGS_ARE_ERRORS@" = "ON" ]; then
ASAN_OPTIONS="halt_on_error=1 protect_shadow_gap=0 $ASAN_OPTIONS"
else
ASAN_OPTIONS="protect_shadow_gap=0 $ASAN_OPTIONS"
fi
if [ "$1" = "--leaks" ]; then
shift
else
ASAN_OPTIONS="$ASAN_OPTIONS detect_leaks=0"
fi
export ASAN_OPTIONS
fi
if [ "@WITH_MSAN@" = "ON" -a "@WARNINGS_ARE_ERRORS@" = "ON" ]; then
export MSAN_OPTIONS="halt_on_error=1 $MSAN_OPTIONS"
fi
case $1 in
--gdb)
shift
......
......@@ -25,8 +25,13 @@ if(H5MD)
endif(H5MD)
if( WITH_COVERAGE )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 --coverage -fprofile-arcs -ftest-coverage")
link_libraries(gcov)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -Og")
if( CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
link_libraries(gcov)
endif()
endif()
add_library(EspressoScriptInterface SHARED ${EspressoScriptInterface_SRC})
......
null:boost/serialization/singleton.hpp
function:src/python/espressomd/
nonnull-attribute:boost::container::container_detail::memmove_n_source
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment