Address review: fix all compiler warnings across GCC, Clang, and MSVC

Requested by @lefticus in PR #687 review.

Fix warnings-as-errors failures on all three compiler families:

- GCC Release: replace strncpy with memcpy in mystrdup (stringop-truncation)
- GCC ASAN+UBSAN Release: add bounds check in Operator() before indexing
  m_operators array — the recursive call could exceed the array size of 12,
  which is an actual out-of-bounds bug, not just a warning
- GCC: downgrade maybe-uninitialized to warning (false positive in libstdc++
  std::regex under sanitizers + optimizations)
- AppleClang: add default cases to all switch statements on Common_Types in
  boxed_number.hpp (Wswitch-default)
- AppleClang: mark Dispatch_Engine move ctor/assignment as deleted since
  shared_mutex is non-movable (Wdefaulted-function-deleted)
- AppleClang on macOS: suppress Wpoison-system-directories for /usr/local/include
- MSVC Release: suppress C4702 (unreachable code) around if-constexpr in
  proxy_functions_detail.hpp
- Fix unused variable warnings in emscripten_eval_test.cpp when asserts are
  disabled in Release mode

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
leftibot 2026-04-14 12:06:25 -06:00
parent 7f63b5dbd1
commit 88d3124272
7 changed files with 35 additions and 18 deletions

View File

@ -180,11 +180,11 @@ else()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command -Wno-unused-template -Wno-undef -Wno-double-promotion)
else()
add_definitions(-Wnoexcept)
add_definitions(-Wnoexcept -Wno-error=maybe-uninitialized)
endif()
if(APPLE)
add_definitions(-Wno-sign-compare)
add_definitions(-Wno-sign-compare -Wno-poison-system-directories)
endif()
endif()

View File

@ -272,6 +272,8 @@ namespace chaiscript {
return callable(*static_cast<const float *>(bv.get_const_ptr()));
case Common_Types::t_long_double:
return callable(*static_cast<const long double *>(bv.get_const_ptr()));
default:
throw chaiscript::detail::exception::bad_any_cast();
}
throw chaiscript::detail::exception::bad_any_cast();
}
@ -479,6 +481,8 @@ namespace chaiscript {
case Common_Types::t_long_double:
check_type<long double, Target>();
return get_as_aux<Target, long double>(bv);
default:
throw chaiscript::detail::exception::bad_any_cast();
}
throw chaiscript::detail::exception::bad_any_cast();
@ -509,6 +513,8 @@ namespace chaiscript {
return get_as_aux<Target, float>(bv);
case Common_Types::t_long_double:
return get_as_aux<Target, long double>(bv);
default:
throw chaiscript::detail::exception::bad_any_cast();
}
throw chaiscript::detail::exception::bad_any_cast();
@ -538,6 +544,8 @@ namespace chaiscript {
return to_string_aux<float>(bv);
case Common_Types::t_long_double:
return to_string_aux<long double>(bv);
default:
throw chaiscript::detail::exception::bad_any_cast();
}
throw chaiscript::detail::exception::bad_any_cast();

View File

@ -377,8 +377,8 @@ namespace chaiscript {
Dispatch_Engine(const Dispatch_Engine &) = delete;
Dispatch_Engine &operator=(const Dispatch_Engine &) = delete;
Dispatch_Engine(Dispatch_Engine &&) = default;
Dispatch_Engine &operator=(Dispatch_Engine &&) = default;
Dispatch_Engine(Dispatch_Engine &&) = delete;
Dispatch_Engine &operator=(Dispatch_Engine &&) = delete;
#ifndef CHAISCRIPT_NO_THREADS
/// Track an async thread so it can be joined during destruction

View File

@ -92,6 +92,10 @@ namespace chaiscript {
/// The function attempts to unbox each parameter to the expected type.
/// if any unboxing fails the execution of the function fails and
/// the bad_boxed_cast is passed up to the caller.
#ifdef CHAISCRIPT_MSVC
#pragma warning(push)
#pragma warning(disable : 4702)
#endif
template<typename Callable, typename Ret, typename... Params>
Boxed_Value
call_func(Ret (*sig)(Params...), const Callable &f, const chaiscript::Function_Params &params, const Type_Conversions_State &t_conversions) {
@ -102,6 +106,9 @@ namespace chaiscript {
return Handle_Return<Ret>::handle(call_func(sig, std::index_sequence_for<Params...>{}, f, params, t_conversions));
}
}
#ifdef CHAISCRIPT_MSVC
#pragma warning(pop)
#endif
} // namespace detail
} // namespace dispatch

View File

@ -2570,6 +2570,10 @@ namespace chaiscript {
bool retval = false;
const auto prev_stack_top = m_match_stack.size();
if (t_precedence >= m_operators.size()) {
return Value();
}
if (m_operators[t_precedence] != Operator_Precedence::Prefix) {
if (Operator(t_precedence + 1)) {
retval = true;

View File

@ -34,7 +34,7 @@ char *mystrdup(const char *s) {
#ifdef CHAISCRIPT_MSVC
strcpy_s(d, len + 1, s); // Copy the characters
#else
strncpy(d, s, len); // Copy the characters
memcpy(d, s, len);
#endif
d[len] = '\0';
return d; // Return the new string

View File

@ -16,36 +16,34 @@
#include <string>
int main() {
// Test eval (void return) - same as Emscripten eval()
chaiscript_eval("var x = 42");
// Test evalString - same as Emscripten evalString()
std::string s = chaiscript_eval_string("to_string(x)");
const std::string s = chaiscript_eval_string("to_string(x)");
assert(s == "42");
static_cast<void>(s);
// Test evalInt - same as Emscripten evalInt()
int i = chaiscript_eval_int("1 + 2");
const int i = chaiscript_eval_int("1 + 2");
assert(i == 3);
static_cast<void>(i);
// Test evalBool - same as Emscripten evalBool()
bool b = chaiscript_eval_bool("true");
assert(b == true);
b = chaiscript_eval_bool("false");
assert(b == false);
static_cast<void>(b);
// Test evalFloat - same as Emscripten evalFloat()
float f = chaiscript_eval_float("1.5f");
const float f = chaiscript_eval_float("1.5f");
assert(std::abs(f - 1.5f) < 0.001f);
static_cast<void>(f);
// Test evalDouble - same as Emscripten evalDouble()
double d = chaiscript_eval_double("3.14");
const double d = chaiscript_eval_double("3.14");
assert(std::abs(d - 3.14) < 0.001);
static_cast<void>(d);
// Test a more complex expression
chaiscript_eval("def square(n) { return n * n; }");
int sq = chaiscript_eval_int("square(7)");
const int sq = chaiscript_eval_int("square(7)");
assert(sq == 49);
static_cast<void>(sq);
return 0;
}