Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Unreleased

- Build: Conditionally enable `-Wnrvo` via compiler feature detection
- Fix: Ensure NRVO in `affinity_for_node` by returning a single named local
`ThreadAffinity` on all paths (removes `-Wnrvo` warning).

## v1.2.1

- fix build for some older mingw version
Expand Down
30 changes: 29 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,39 @@ if(UNIX AND NOT APPLE AND NOT WIN32)
endif()
# Windows (MSVC and MinGW) use Threads::Threads which is already linked above

# Check support for optional warning flags (e.g. -Wnrvo)
include(CheckCXXCompilerFlag)

function(ts_add_warning_if_supported flag out_var)
string(REPLACE "-" "_" _flag_var "${flag}")
Copy link

Copilot AI Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _flag_var variable name may conflict across multiple calls to this function with different flags. The variable should include a unique suffix or use a more specific naming pattern. Consider using CXX_SUPPORTS${_flag_var} or similar to ensure uniqueness when checking multiple flags.

Suggested change
string(REPLACE "-" "_" _flag_var "${flag}")
string(REPLACE "-" "_" _flag_var "${flag}")
set(_flag_var "CXX_SUPPORTS${_flag_var}")

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable name _flag_var created by sanitizing the flag contains characters like 'W' and is used directly as the output variable for check_cxx_compiler_flag. However, on line 168, the sanitized string (e.g., '_Wnrvo') is used as a variable name without proper handling. CMake variable names from check_cxx_compiler_flag should be valid identifiers. The sanitized variable _flag_var should convert '-Wnrvo' to something like '_Wnrvo', but this may still contain uppercase letters at the start which could cause issues. Consider using a more robust sanitization that also handles the leading character, such as string(MAKE_C_IDENTIFIER \"CXX_FLAG_${flag}\" _flag_var) or a more explicit pattern like string(REGEX REPLACE \"[^a-zA-Z0-9_]\" \"_\" _flag_var \"HAS${flag}\").

Suggested change
string(REPLACE "-" "_" _flag_var "${flag}")
string(MAKE_C_IDENTIFIER "CXX_FLAG_${flag}" _flag_var)

Copilot uses AI. Check for mistakes.
check_cxx_compiler_flag("${flag}" ${_flag_var})
if(${_flag_var})
if(DEFINED ${out_var} AND NOT "${${out_var}}" STREQUAL "")
set(${out_var} "${${out_var}};${flag}" PARENT_SCOPE)
else()
set(${out_var} "${flag}" PARENT_SCOPE)
endif()
Comment on lines +170 to +174
Copy link

Copilot AI Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The manual string concatenation with semicolons can be replaced with CMake's list(APPEND ...) command for better maintainability and clarity. Replace lines 170-174 with: list(APPEND ${out_var} \"${flag}\") followed by set(${out_var} \"${${out_var}}\" PARENT_SCOPE).

Suggested change
if(DEFINED ${out_var} AND NOT "${${out_var}}" STREQUAL "")
set(${out_var} "${${out_var}};${flag}" PARENT_SCOPE)
else()
set(${out_var} "${flag}" PARENT_SCOPE)
endif()
list(APPEND ${out_var} "${flag}")
set(${out_var} "${${out_var}}" PARENT_SCOPE)

Copilot uses AI. Check for mistakes.
endif()
endfunction()

# Collect optional warnings conditionally
set(TS_OPTIONAL_WARNINGS "")
ts_add_warning_if_supported("-Wnrvo" TS_OPTIONAL_WARNINGS)

# Wrap optional warnings in BUILD_INTERFACE generator expressions, one per flag
set(TS_OPTIONAL_WARNINGS_GE "")
foreach(_w ${TS_OPTIONAL_WARNINGS})
list(APPEND TS_OPTIONAL_WARNINGS_GE $<BUILD_INTERFACE:${_w}>)
endforeach()

# Compiler-specific warnings and flags (only for top-level project to avoid polluting parent)
if(THREADSCHEDULE_IS_TOPLEVEL_PROJECT)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(ThreadSchedule INTERFACE
$<BUILD_INTERFACE:-Wall -Wextra -Wpedantic>
$<BUILD_INTERFACE:-Wall>
$<BUILD_INTERFACE:-Wextra>
$<BUILD_INTERFACE:-Wpedantic>
${TS_OPTIONAL_WARNINGS_GE}
)
# MinGW (GCC): allow permissive mode for broader compatibility when requested
if(MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
Expand Down
4 changes: 2 additions & 2 deletions include/threadschedule/topology.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,11 @@ inline auto read_topology() -> CpuTopology
inline auto affinity_for_node(int node_index, int thread_index, int threads_per_node = 1) -> ThreadAffinity
{
CpuTopology topo = read_topology();
ThreadAffinity aff;
if (topo.numa_nodes <= 0)
return {};
return aff;
int const n = (node_index % topo.numa_nodes + topo.numa_nodes) % topo.numa_nodes;
auto const& cpus = topo.node_to_cpus[n];
ThreadAffinity aff;
if (cpus.empty())
return aff;

Expand Down