Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/test-library.yml
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,55 @@ jobs:
path: warnings_analyzer.log


build-linux-x86_64-clang-tidy:
name: Linux x86_64 (Clang tidy)
runs-on: ubuntu-latest
needs: basicchecks

steps:
- uses: actions/checkout@v4

- name: Checkout OpenMM (for Lepton library)
uses: actions/checkout@v4
with:
repository: 'openmm/openmm'
ref: 'master'
path: 'openmm-source'

- name: Install build dependencies, clang-tidy and bash for library
shell: bash
run: |
sudo apt -y install bash ccache tcl8.6-dev clang-20 clang-tidy-20

- name: Configure and build the library (but do not run tests)
env:
CMAKE_BUILD_DIR: build
CXX: clang++-20
CC: clang-20
run: cmake -DBUILD_TARGETS=OFF -DRUN_TESTS=OFF -P devel-tools/build_test_library.cmake

- name: Run "run_clang_tidy.sh" in the "build" folder
env:
CLANG_TIDY: clang-tidy-20
working-directory: build
run: bash ${{ github.workspace }}/devel-tools/run_clang_tidy.sh &> clang-tidy.log

- name: Print clang-tidy errors to screen
if: failure()
working-directory: build
shell: bash
run: |
cat clang-tidy.log >&2
exit 1

- name: Archive warnings artifacts
uses: actions/upload-artifact@v4
if: failure()
with:
name: clang_tidy_log
path: build/clang-tidy.log


address-sanitizer:
name: Linux x86_64 (Clang address sanitizer)
runs-on: ubuntu-latest
Expand Down
16 changes: 10 additions & 6 deletions devel-tools/build_test_library.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ execute_process(
-D BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}
-D WARNINGS_ARE_ERRORS=ON
-D CMAKE_VERBOSE_MAKEFILE=ON
-D CMAKE_EXPORT_COMPILE_COMMANDS=ON
-D CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
${DEFINE_CXX_COMPILER}
${DEFINE_CC_CCACHE}
Expand All @@ -142,20 +143,23 @@ execute_process(
${DEFINE_TORCH_PREFIX}
-D COLVARS_LEPTON=${COLVARS_LEPTON}
-D LEPTON_DIR=${LEPTON_DIR}
-D CMAKE_PREFIX_PATH="/opt/libtorch/share/cmake"
RESULT_VARIABLE result
)

if(NOT result EQUAL 0)
message(FATAL_ERROR "Error generating CMake buildsystem.")
endif()

execute_process(
COMMAND ${CMAKE_COMMAND}
--build ${BUILD_DIR}
--parallel
RESULT_VARIABLE result
option(BUILD_TARGETS "Build library and related tools" ON)

if(BUILD_TARGETS)
execute_process(
COMMAND ${CMAKE_COMMAND}
--build ${BUILD_DIR}
--parallel
RESULT_VARIABLE result
)
endif()

option(RUN_TESTS "Run library tests" ON)

Expand Down
39 changes: 39 additions & 0 deletions devel-tools/run_clang_tidy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash

# Get the top Colvars repo directory
TOPDIR=$(git rev-parse --show-toplevel)
if [ ! -d ${TOPDIR} ] ; then
echo "Error: cannot identify top project directory." >& 2
exit 1
fi

# Get the build directory
COLVARS_BUILD_DIR="$(pwd)"

# Get the clang-tidy binary
if [[ -v CLANG_TIDY ]]; then
CLANG_TIDY_BINARY=$CLANG_TIDY
echo "Using $CLANG_TIDY_BINARY as clang-tidy"
else
CLANG_TIDY_BINARY="clang-tidy"
fi

# Get the Colvars source directory
COLVARS_SOURCE_DIR="$TOPDIR/src"
# Find all source files that are required to build the run_colvars_test
COLVARS_STUB_SOURCE_DIR="$TOPDIR/misc_interfaces/stubs"
COLVARS_TEST_SOURCE_DIR="$TOPDIR/tests/functional/"
COLVARS_SOURCE_FILES=($(find $COLVARS_STUB_SOURCE_DIR $COLVARS_TEST_SOURCE_DIR $COLVARS_SOURCE_DIR -name "*.cpp"))

printf '%s\n' ${COLVARS_SOURCE_FILES[@]} | \
xargs -I{} -P $(nproc) \
bash -c "$CLANG_TIDY_BINARY -p=$COLVARS_BUILD_DIR -header-filter=.* --warnings-as-errors='*' '{}' > '{}'.log"

retcode=$?

if [ $retcode != 0 ] ; then
cat "${COLVARS_SOURCE_FILES[@]/%/.log}"
exit $retcode
fi

exit 0
4 changes: 2 additions & 2 deletions src/colvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1139,9 +1139,9 @@ int colvar::parse_analysis(std::string const &conf)

int colvar::init_dependencies() {
size_t i;
if (features().size() == 0) {
if (colvar::features().size() == 0) {
for (i = 0; i < f_cv_ntot; i++) {
modify_features().push_back(new feature);
colvar::modify_features().push_back(new feature);
}

init_feature(f_cv_active, "active", f_type_dynamic);
Expand Down
5 changes: 4 additions & 1 deletion src/colvar_arithmeticpath.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ using std::vector;
template <typename scalar_type>
class ArithmeticPathBase {
public:
ArithmeticPathBase() {}
ArithmeticPathBase():
lambda(scalar_type(0)), num_elements(0), total_frames(0),
max_exponent(scalar_type(0)), saved_exponent_sum(scalar_type(0)),
normalization_factor(scalar_type(0)), saved_s(scalar_type(0)) {}
~ArithmeticPathBase() {}
void initialize(size_t p_num_elements, size_t p_total_frames, scalar_type p_lambda, const vector<scalar_type>& p_weights);
void reComputeLambda(const vector<scalar_type>& rmsd_between_refs);
Expand Down
4 changes: 3 additions & 1 deletion src/colvar_rotation_derivative.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ enum class rotation_derivative_dldq {
/// Require the derivative of the leading eigenvalue with respect to the atom coordinates
use_dl = 1 << 0,
/// Require the derivative of the leading eigenvector with respect to the atom coordinates
use_dq = 1 << 1
use_dq = 1 << 1,
/// Require the derivative of both L and Q
use_all = (use_dl) + (use_dq)
};

inline constexpr rotation_derivative_dldq operator|(rotation_derivative_dldq Lhs, rotation_derivative_dldq Rhs) {
Expand Down
4 changes: 2 additions & 2 deletions src/colvaratoms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,9 @@ int cvm::atom_group::init()
int cvm::atom_group::init_dependencies() {
size_t i;
// Initialize static array once and for all
if (features().size() == 0) {
if (atom_group::features().size() == 0) {
for (i = 0; i < f_ag_ntot; i++) {
modify_features().push_back(new feature);
atom_group::modify_features().push_back(new feature);
}

init_feature(f_ag_active, "active", f_type_dynamic);
Expand Down
4 changes: 2 additions & 2 deletions src/colvarbias.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ int colvarbias::init_mts(std::string const &conf) {

int colvarbias::init_dependencies() {
int i;
if (features().size() == 0) {
if (colvarbias::features().size() == 0) {
for (i = 0; i < f_cvb_ntot; i++) {
modify_features().push_back(new feature);
colvarbias::modify_features().push_back(new feature);
}

init_feature(f_cvb_active, "active", f_type_dynamic);
Expand Down
4 changes: 2 additions & 2 deletions src/colvarbias_abf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ template <typename OST> OST & colvarbias_abf::write_state_data_template_(OST &os
{
auto flags = os.flags();

os.setf(std::ios::fmtflags(0), std::ios::floatfield); // default floating-point format
os.setf(std::ios::fmtflags(std::ios::dec), std::ios::floatfield); // default floating-point format

write_state_data_key(os, "samples");
samples->write_raw(os, 8);
Expand All @@ -941,7 +941,7 @@ template <typename OST> OST & colvarbias_abf::write_state_data_template_(OST &os
}

if (b_CZAR_estimator) {
os.setf(std::ios::fmtflags(0), std::ios::floatfield); // default floating-point format
os.setf(std::ios::fmtflags(std::ios::dec), std::ios::floatfield); // default floating-point format
write_state_data_key(os, "z_samples");
z_samples->write_raw(os, 8);
write_state_data_key(os, "z_gradient");
Expand Down
8 changes: 3 additions & 5 deletions src/colvarbias_abmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,10 @@ int colvarbias_abmd::set_state_params(std::string const &conf)
colvarparse::parse_restart | colvarparse::parse_required);
ref_initialized = true;

get_keyval(conf, "forceConstant", k, k,
colvarparse::parse_restart | colvarparse::parse_required);
get_keyval(conf, "decreasing", decreasing, decreasing,
colvarparse::parse_restart | colvarparse::parse_required);
get_keyval(conf, "forceConstant", k, k, colvarparse::parse_required_restart);
get_keyval(conf, "decreasing", decreasing, decreasing, colvarparse::parse_required_restart);
get_keyval(conf, "stoppingValue", stopping_val, stopping_val,
colvarparse::parse_restart | colvarparse::parse_required);
colvarparse::parse_required_restart);

return COLVARS_OK;
}
Expand Down
2 changes: 1 addition & 1 deletion src/colvarbias_histogram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ cvm::memory_stream & colvarbias_histogram::read_state_data(cvm::memory_stream& i
std::ostream & colvarbias_histogram::write_state_data(std::ostream& os)
{
std::ios::fmtflags flags(os.flags());
os.setf(std::ios::fmtflags(0), std::ios::floatfield);
os.setf(std::ios::fmtflags(std::ios::dec), std::ios::floatfield);
write_state_data_key(os, "grid");
grid->write_raw(os, 8);
os.flags(flags);
Expand Down
2 changes: 1 addition & 1 deletion src/colvarbias_histogram_reweight_amd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ void colvarbias_reweightaMD::compute_cumulant_expansion_factor(
template <typename OST> OST & colvarbias_reweightaMD::write_state_data_template_(OST& os)
{
std::ios::fmtflags flags(os.flags());
os.setf(std::ios::fmtflags(0), std::ios::floatfield);
os.setf(std::ios::fmtflags(std::ios::dec), std::ios::floatfield);
write_state_data_key(os, "grid");
grid->write_raw(os, 8);
write_state_data_key(os, "grid_count");
Expand Down
2 changes: 1 addition & 1 deletion src/colvarbias_opes.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class colvarbias_opes: public colvarbias {
cvm::real m_height;
std::vector<cvm::real> m_center;
std::vector<cvm::real> m_sigma;
kernel() {}
kernel(): m_height(0) {}
kernel(cvm::real h, const std::vector<cvm::real>& c,
const std::vector<cvm::real>& s):
m_height(h), m_center(c), m_sigma(s) {}
Expand Down
4 changes: 2 additions & 2 deletions src/colvarcomp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,9 @@ cvm::atom_group *colvar::cvc::parse_group(std::string const &conf,
int colvar::cvc::init_dependencies() {
size_t i;
// Initialize static array once and for all
if (features().size() == 0) {
if (cvc::features().size() == 0) {
for (i = 0; i < colvardeps::f_cvc_ntot; i++) {
modify_features().push_back(new feature);
cvc::modify_features().push_back(new feature);
}

init_feature(f_cvc_active, "active", f_type_dynamic);
Expand Down
18 changes: 13 additions & 5 deletions src/colvarparse.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,14 @@ class colvarparse : public colvarparams {
return config_string;
}

#ifdef __clang__
#define PARSE_MODE_IS_FLAG [[clang::flag_enum]]
#else
#define PARSE_MODE_IS_FLAG
#endif

/// How a keyword is parsed in a string
enum Parse_Mode {
enum PARSE_MODE_IS_FLAG Parse_Mode {
/// Zero for all flags
parse_null = 0,
/// Print the value of a keyword if it is given
Expand All @@ -68,6 +74,8 @@ class colvarparse : public colvarparams {
parse_override = (1<<17),
/// The call is being executed from a read_restart() function
parse_restart = (1<<18),
/// Provide explicitly to silence clang-tidy warnings
parse_required_restart = (1<<16) | (1<<18),
/// Alias for old default behavior (should be phased out)
parse_normal = (1<<1) | (1<<2) | (1<<17),
/// Settings for a deprecated keyword
Expand Down Expand Up @@ -386,11 +394,11 @@ class colvarparse : public colvarparams {


/// Bitwise OR between two Parse_mode flags
inline colvarparse::Parse_Mode operator | (colvarparse::Parse_Mode const &mode1,
colvarparse::Parse_Mode const &mode2)
inline constexpr colvarparse::Parse_Mode operator|(colvarparse::Parse_Mode mode1,
colvarparse::Parse_Mode mode2)
{
return static_cast<colvarparse::Parse_Mode>(static_cast<int>(mode1) |
static_cast<int>(mode2));
using T = std::underlying_type<colvarparse::Parse_Mode>::type;
return static_cast<colvarparse::Parse_Mode>(static_cast<T>(mode1) | static_cast<T>(mode2));
}

#endif
10 changes: 5 additions & 5 deletions src/colvars_memstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,16 @@ class cvm::memory_stream {
inline memory_stream & seekg(size_t pos) { read_pos_ = pos; return *this; }

/// Ignore formatting operators
inline void setf(decltype(std::ios::fmtflags(0)), decltype(std::ios::floatfield)) {}
inline void setf(decltype(std::ios::fmtflags(std::ios::unitbuf)), decltype(std::ios::floatfield)) {}

/// Ignore formatting operators
inline void setf(decltype(std::ios::fmtflags(0))) {}
inline void setf(decltype(std::ios::fmtflags(std::ios::unitbuf))) {}

/// Ignore formatting operators
inline void flags(decltype(std::ios::fmtflags(0))) {}
inline void flags(decltype(std::ios::fmtflags(std::ios::unitbuf))) {}

/// Get the current formatting flags (i.e. none because this stream is unformatted)
inline decltype(std::ios::fmtflags(0)) flags() const { return std::ios::fmtflags(0); }
/// Get the current formatting flags (throw a useless result because this stream is unformatted)
inline decltype(std::ios::fmtflags(std::ios::unitbuf)) flags() const { return std::ios::fmtflags(std::ios::unitbuf); }

/// Get the error code
inline std::ios::iostate rdstate() const { return state_; }
Expand Down
Loading