From bc771ab8ba409908702bcab8809a7e48fcf4b50d Mon Sep 17 00:00:00 2001 From: leftibot Date: Sat, 11 Apr 2026 13:40:04 -0600 Subject: [PATCH 1/3] =?UTF-8?q?[WIP]=20Issue=20#615=20=E2=80=94=20Switch?= =?UTF-8?q?=20to=20GitHub=20Actions=20(#658)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #615: Switch from Travis CI to GitHub Actions Add a GitHub Actions CI workflow with a full build matrix covering linux, macOS, and Windows with both GCC and Clang compilers, Debug and Release build types, and optional ASan+UBSan sanitizers (24 builds total). Windows builds use MSYS2 for GCC/Clang toolchains. The workflow relies on CMake and CTest to drive configuration, building, and testing. Co-Authored-By: Claude Opus 4.6 (1M context) * Address review: use native compilers, remove MSYS/MinGW Use Visual Studio (MSVC) on Windows, Apple Clang on macOS, and GCC on Linux. Remove MSYS2/MinGW toolchain setup entirely. Split into three separate jobs for clarity. Fix workflow validation issues. Requested by @lefticus in PR #658 review. Co-Authored-By: Claude Opus 4.6 (1M context) * Address review: add workflow_dispatch to enable manual CI runs on fork Add workflow_dispatch trigger so the workflow can be manually run on the leftibot fork to verify that GitHub Actions are working correctly. Requested by @lefticus in PR #658 review. Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: leftibot Co-authored-by: Claude Opus 4.6 (1M context) --- .github/workflows/ci.yml | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..6bb834e3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,66 @@ +name: CI + +on: + push: + branches: [develop, main] + pull_request: + branches: [develop, main] + workflow_dispatch: + +jobs: + linux: + name: Linux GCC ${{ matrix.build_type }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + build_type: [Debug, Release] + steps: + - uses: actions/checkout@v4 + + - name: Configure + run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} + + - name: Build + run: cmake --build build -j + + - name: Test + run: ctest --test-dir build --output-on-failure + + macos: + name: macOS AppleClang ${{ matrix.build_type }} + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + build_type: [Debug, Release] + steps: + - uses: actions/checkout@v4 + + - name: Configure + run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} + + - name: Build + run: cmake --build build -j + + - name: Test + run: ctest --test-dir build --output-on-failure + + windows: + name: Windows MSVC ${{ matrix.build_type }} + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + build_type: [Debug, Release] + steps: + - uses: actions/checkout@v4 + + - name: Configure + run: cmake -B build + + - name: Build + run: cmake --build build --config ${{ matrix.build_type }} -j + + - name: Test + run: ctest --test-dir build --output-on-failure -C ${{ matrix.build_type }} From 1619d846daacc0b667d52707b28309b0536c3132 Mon Sep 17 00:00:00 2001 From: leftibot Date: Sat, 11 Apr 2026 13:42:40 -0600 Subject: [PATCH 2/3] Fix #607: Remove unnecessary forward declarations that cause C++20 build failures (#647) The forward declarations of AST_Node_Trace and eval_error at the top of chaiscript_common.hpp introduced these types as incomplete before the standard library headers were fully processed. On clang/libc++ in C++20 mode, this caused compilation errors because std::vector was instantiated while the type was still incomplete. Since the full definitions of both types appear later in the same file (and nothing between the forward declarations and the definitions references them), these forward declarations are unnecessary and removing them prevents the incomplete type issue. Co-authored-by: leftibot Co-authored-by: Claude Opus 4.6 (1M context) --- .../chaiscript/language/chaiscript_common.hpp | 4 ---- unittests/compiled_tests.cpp | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 44116735..fb75a933 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -26,10 +26,6 @@ namespace chaiscript { struct AST_Node; - struct AST_Node_Trace; - namespace exception { - struct eval_error; - } } // namespace chaiscript namespace chaiscript { diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 27a99585..4c7d96fa 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -1436,3 +1436,23 @@ TEST_CASE("Issue #421 - Switch with type_conversion does not compare destroyed o result })") == 0); } + +// Regression test for issue #607: AST_Node_Trace must be a complete type +// when used in eval_error's std::vector call_stack member. +// This failed to compile with C++20 on clang/libc++ when AST_Node_Trace +// was only forward-declared before eval_error's definition. +TEST_CASE("eval_error with AST_Node_Trace call stack compiles in C++20") { + chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(), create_chaiscript_parser()); + + // Trigger an eval_error by calling a non-existent function + try { + chai.eval("nonexistent_function()"); + REQUIRE(false); + } catch (const chaiscript::exception::eval_error &e) { + // Verify that eval_error's call_stack member (std::vector) + // is usable - this would fail to compile if AST_Node_Trace were incomplete + const auto &stack = e.call_stack; + CHECK(e.pretty_print().size() > 0); + (void)stack; + } +} From 92abd226a9a08f0657936fbcb09141447dd9a8e4 Mon Sep 17 00:00:00 2001 From: leftibot Date: Sat, 11 Apr 2026 15:06:33 -0600 Subject: [PATCH 3/3] Fix #660: Windows builds are broken (#661) * Fix #660: Fix Windows builds, remove Appveyor, add sanitizer CI builds Add missing #include to src/main.cpp which caused MSVC build failures since high_resolution_clock and duration_cast were used without the header (GCC/Clang included it transitively). Remove obsolete appveyor.yml (superseded by GitHub Actions). Add ASAN+UBSAN build jobs for Linux and macOS in the CI workflow. Co-Authored-By: Claude Opus 4.6 (1M context) * Address review: add Windows ASAN+UBSAN sanitizer support - Add MSVC-native ASAN support in CMakeLists.txt (/fsanitize=address) with /RTC removal and /INCREMENTAL:NO (both incompatible with ASAN) - Add Windows MSVC ASAN CI job - Add Windows ClangCL ASAN+UBSAN CI job (UBSAN requires Clang, not available in native MSVC) - Fix sanitizer guard to include AppleClang (macOS sanitizer jobs were silently not enabling sanitizers) Requested by @lefticus in PR #661 review. Co-Authored-By: Claude Opus 4.6 (1M context) * Address review: remove Windows sanitizers, add TSAN for Linux/macOS Remove windows-sanitizers and windows-clangcl-sanitizers CI jobs. Add linux-tsan and macos-tsan CI jobs using ENABLE_THREAD_SANITIZER. Requested by @lefticus in PR #661 review. Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: leftibot Co-authored-by: Claude Opus 4.6 (1M context) --- .github/workflows/ci.yml | 76 +++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 12 +++++- appveyor.yml | 23 ----------- src/main.cpp | 1 + unittests/now_function.chai | 3 ++ 5 files changed, 91 insertions(+), 24 deletions(-) delete mode 100644 appveyor.yml create mode 100644 unittests/now_function.chai diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6bb834e3..62ae5d24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,44 @@ jobs: - name: Test run: ctest --test-dir build --output-on-failure + linux-sanitizers: + name: Linux GCC ASAN+UBSAN ${{ matrix.build_type }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + build_type: [Debug, Release] + steps: + - uses: actions/checkout@v4 + + - name: Configure + run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_ADDRESS_SANITIZER=ON -DENABLE_UNDEFINED_SANITIZER=ON + + - name: Build + run: cmake --build build -j + + - name: Test + run: ctest --test-dir build --output-on-failure + + macos-sanitizers: + name: macOS AppleClang ASAN+UBSAN ${{ matrix.build_type }} + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + build_type: [Debug, Release] + steps: + - uses: actions/checkout@v4 + + - name: Configure + run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_ADDRESS_SANITIZER=ON -DENABLE_UNDEFINED_SANITIZER=ON + + - name: Build + run: cmake --build build -j + + - name: Test + run: ctest --test-dir build --output-on-failure + windows: name: Windows MSVC ${{ matrix.build_type }} runs-on: windows-latest @@ -64,3 +102,41 @@ jobs: - name: Test run: ctest --test-dir build --output-on-failure -C ${{ matrix.build_type }} + + linux-tsan: + name: Linux GCC TSAN ${{ matrix.build_type }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + build_type: [Debug, Release] + steps: + - uses: actions/checkout@v4 + + - name: Configure + run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_THREAD_SANITIZER=ON + + - name: Build + run: cmake --build build -j + + - name: Test + run: ctest --test-dir build --output-on-failure + + macos-tsan: + name: macOS AppleClang TSAN ${{ matrix.build_type }} + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + build_type: [Debug, Release] + steps: + - uses: actions/checkout@v4 + + - name: Configure + run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DENABLE_THREAD_SANITIZER=ON + + - name: Build + run: cmake --build build -j + + - name: Test + run: ctest --test-dir build --output-on-failure diff --git a/CMakeLists.txt b/CMakeLists.txt index 878749ad..ad3e79a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ if(CMAKE_COMPILER_IS_GNUCC) endif() endif() -if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") +if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") option(ENABLE_THREAD_SANITIZER "Enable thread sanitizer testing in gcc/clang" FALSE) if(ENABLE_THREAD_SANITIZER) add_definitions(-fsanitize=thread -g) @@ -87,6 +87,16 @@ if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") endif() +elseif(MSVC) + option(ENABLE_ADDRESS_SANITIZER "Enable address sanitizer testing in MSVC" FALSE) + if(ENABLE_ADDRESS_SANITIZER) + add_compile_options(/fsanitize=address) + # ASAN is incompatible with /RTC (runtime error checks) and incremental linking + string(REGEX REPLACE "/RTC[^ ]*" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + string(REGEX REPLACE "/RTC[^ ]*" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") + add_link_options(/INCREMENTAL:NO) + endif() + endif() list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 5a4fe67e..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,23 +0,0 @@ -version: 6.1.x.{build} -image: - - Visual Studio 2019 -environment: - matrix: - - VS_VERSION: "Visual Studio 16" -build_script: -- cmd: >- - mkdir build - - cd build - - cmake c:\Projects\chaiscript -G "%VS_VERSION%" -DBUILD_TESTING:BOOL=ON -DBUILD_MODULES:BOOL=ON - - cmake --build . --config Debug -test_script: -- cmd: ctest -C Debug -notifications: -- provider: Webhook - url: https://webhooks.gitter.im/e/9ff725a985b5679d1d5d - on_build_success: true - on_build_failure: true - on_build_status_changed: false diff --git a/src/main.cpp b/src/main.cpp index 6ec746fb..ab94b5d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check it. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +#include #include #include #include diff --git a/unittests/now_function.chai b/unittests/now_function.chai new file mode 100644 index 00000000..5825cdec --- /dev/null +++ b/unittests/now_function.chai @@ -0,0 +1,3 @@ +// Regression test for issue #660: now() requires include +var t = now() +assert_true(t > 0)