From 482257764b063b228bd4195b476575c7ca405be7 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sun, 15 Mar 2026 10:16:45 -0400 Subject: [PATCH 1/9] Enable -Werror in CMake (CI only) --- CMakePresets.json | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakePresets.json b/CMakePresets.json index f2df4ba9c7c1..301a7ac7071a 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -21,6 +21,7 @@ "toolchainFile": "$env{VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake", "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "CMAKE_COMPILE_WARNING_AS_ERROR": "ON", "FETCHCONTENT_FULLY_DISCONNECTED": "ON", "VCPKG_CHAINLOAD_TOOLCHAIN_FILE": "${sourceDir}/cmake/toolchain.${presetName}.cmake", "VCPKG_MANIFEST_FEATURES": "developer", From c7c4bf8034842b3fd9d9959b2595395b79f1b292 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sun, 15 Mar 2026 10:42:21 -0400 Subject: [PATCH 2/9] Fix unused variable warning for has_scalable_vector in Target.cpp --- src/Target.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Target.cpp b/src/Target.cpp index c1b8ebbdb99a..c73215f40282 100644 --- a/src/Target.cpp +++ b/src/Target.cpp @@ -257,7 +257,9 @@ Target calculate_host_target() { #else #if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) Target::Arch arch = Target::ARM; +#if !defined(__arm__) bool has_scalable_vector = false; +#endif #ifdef __APPLE__ if (is_armv7s()) { @@ -293,7 +295,9 @@ Target calculate_host_target() { if (hwcaps2 & HWCAP2_SVE2) { initial_features.push_back(Target::SVE2); +#if !defined(__arm__) has_scalable_vector = true; +#endif } #endif @@ -322,12 +326,14 @@ Target calculate_host_target() { if (IsProcessorFeaturePresent(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE)) { initial_features.push_back(Target::SVE2); +#if !defined(__arm__) has_scalable_vector = true; +#endif } #endif -#if defined(__aarch64__) +#if !defined(__arm__) if (has_scalable_vector) { vector_bits = get_sve_vector_length(); } From e87a146ed0011e0d7b08f0849334bd839efca659 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sun, 15 Mar 2026 10:46:44 -0400 Subject: [PATCH 3/9] Suppress unsafe CRT function warnings in halide_image_io.h --- tools/halide_image_io.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/halide_image_io.h b/tools/halide_image_io.h index 3d84f22b04e4..695bc9f78c94 100644 --- a/tools/halide_image_io.h +++ b/tools/halide_image_io.h @@ -4,6 +4,11 @@ #ifndef HALIDE_IMAGE_IO_H #define HALIDE_IMAGE_IO_H +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4996) // disable unsafe CRT function warnings +#endif + #include #include #include @@ -2791,4 +2796,8 @@ void convert_and_save_image(ImageType &im, const std::string &filename) { } // namespace Tools } // namespace Halide +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #endif // HALIDE_IMAGE_IO_H From 82b8ea12fbfe30eca36fc26315ef7f500df9da09 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sun, 15 Mar 2026 12:57:25 -0400 Subject: [PATCH 4/9] Fix loss of precision in double-to-float conversion --- test/autoschedulers/anderson2021/test.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/autoschedulers/anderson2021/test.h b/test/autoschedulers/anderson2021/test.h index 20e48f6590dd..82a169822c59 100644 --- a/test/autoschedulers/anderson2021/test.h +++ b/test/autoschedulers/anderson2021/test.h @@ -21,7 +21,7 @@ void expect_eq(int line, const A &expected, const B &actual) { } template -void approx_eq(int line, const A &expected, const B &actual, float epsilon) { +void approx_eq(int line, const A &expected, const B &actual, double epsilon) { user_assert(std::abs(expected - actual) < epsilon) << "Assert failed on line " << line << "." << "\nExpected value = " << expected From feb2003567ae15ba6a8e2ea2ada01a9a3a3474dd Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sun, 15 Mar 2026 12:58:52 -0400 Subject: [PATCH 5/9] Suppress unsafe CRT function warnings in test_sharding.h --- test/common/test_sharding.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/common/test_sharding.h b/test/common/test_sharding.h index a6ec297f9061..678351f156ac 100644 --- a/test/common/test_sharding.h +++ b/test/common/test_sharding.h @@ -1,6 +1,11 @@ #ifndef TEST_SHARDING_H #define TEST_SHARDING_H +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4996) +#endif + // This file may be used by AOT tests, so it deliberately does not // include Halide.h @@ -86,4 +91,8 @@ class Sharder { } // namespace Internal } // namespace Halide +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #endif // TEST_SHARDING_H From a6afb47390adfa562f5cb35d581c17892a8b286a Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sun, 15 Mar 2026 13:56:11 -0400 Subject: [PATCH 6/9] Set _CRT_SECURE_NO_WARNINGS for Halide::Test sources --- cmake/HalideTestHelpers.cmake | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmake/HalideTestHelpers.cmake b/cmake/HalideTestHelpers.cmake index 218ed82ca9d5..c46a4672d3ce 100644 --- a/cmake/HalideTestHelpers.cmake +++ b/cmake/HalideTestHelpers.cmake @@ -21,6 +21,11 @@ if (NOT TARGET Halide::Test) # Make internal_assert, debug, etc. available to tests target_compile_definitions(Halide_test INTERFACE HALIDE_KEEP_MACROS) + # Disable warnings about standard C functions that have more secure replacements + # in the Windows API. + target_compile_definitions(Halide_test INTERFACE + $<$:_CRT_SECURE_NO_WARNINGS>) + # Everyone gets to see the common headers target_include_directories(Halide_test INTERFACE From b746b5bbdff48f06af2abc3f36c32e6250c4ac2e Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sun, 15 Mar 2026 17:36:08 -0400 Subject: [PATCH 7/9] Fix float literal suffix. --- test/correctness/fuzz_schedule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/correctness/fuzz_schedule.cpp b/test/correctness/fuzz_schedule.cpp index 78fe9e0cb757..5ad69db70c11 100644 --- a/test/correctness/fuzz_schedule.cpp +++ b/test/correctness/fuzz_schedule.cpp @@ -230,7 +230,7 @@ int main(int argc, char **argv) { // https://github.com/halide/Halide/issues/8054 { ImageParam input(Float(32), 2, "input"); - const float r_sigma = 0.1; + const float r_sigma = 0.1f; const int s_sigma = 8; Func bilateral_grid{"bilateral_grid"}; From c12e80aa8efdc14c63fc3929f7449d18ce02e0b1 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sun, 15 Mar 2026 18:03:54 -0400 Subject: [PATCH 8/9] MSVC: cast M_PI to float (C4305) --- test/correctness/rfactor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/correctness/rfactor.cpp b/test/correctness/rfactor.cpp index e26751f2a0dc..204a318f5f43 100644 --- a/test/correctness/rfactor.cpp +++ b/test/correctness/rfactor.cpp @@ -839,7 +839,7 @@ enum class InlineReductionVariant { template int inline_reductions_test() { using namespace ConciseCasts; - constexpr float pi = M_PI; + constexpr float pi = static_cast(M_PI); Func f{"f"}; Var x("x"); @@ -897,7 +897,7 @@ enum class ArgMaxTupleOrder { template int argmax_rfactor_test() { using namespace ConciseCasts; - constexpr float pi = M_PI; + constexpr float pi = static_cast(M_PI); Func f{"f"}; Var x("x"); From eafcda72f9033221e7f215b0792a505438fa97ee Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Sun, 15 Mar 2026 21:09:38 -0400 Subject: [PATCH 9/9] Normalize line endings in templates and string literals On Windows, raw string literals and binary2cpp-generated arrays can contain \r\n line endings (from git checkout with core.autocrlf). Normalize to \n so that generated source files have consistent, platform-independent line endings. --- src/CodeGen_C.cpp | 81 ++++++++++++++++++++++---------------- src/PythonExtensionGen.cpp | 20 ++++++++-- 2 files changed, 63 insertions(+), 38 deletions(-) diff --git a/src/CodeGen_C.cpp b/src/CodeGen_C.cpp index 65892bff2c2c..7b5a9792247e 100644 --- a/src/CodeGen_C.cpp +++ b/src/CodeGen_C.cpp @@ -39,10 +39,29 @@ extern "C" unsigned char halide_c_template_CodeGen_C_vectors[]; namespace { +// On Windows, raw string literals and binary2cpp-generated arrays can +// contain \r\n line endings (from git checkout with core.autocrlf). +// Normalize to \n so that generated source files have consistent, +// platform-independent line endings. +string normalize_line_endings(const char *s) { + string result; + result.reserve(strlen(s)); + for (; *s; ++s) { + if (*s != '\r') { + result += *s; + } + } + return result; +} + +string normalize_line_endings(const unsigned char *s) { + return normalize_line_endings(reinterpret_cast(s)); +} + // HALIDE_MUST_USE_RESULT defined here is intended to exactly // duplicate the definition in HalideRuntime.h (so that either or // both can be present, in any order). -const char *const kDefineMustUseResult = R"INLINE_CODE(#ifndef HALIDE_MUST_USE_RESULT +const string kDefineMustUseResult = normalize_line_endings(R"INLINE_CODE(#ifndef HALIDE_MUST_USE_RESULT #ifdef __has_attribute #if __has_attribute(nodiscard) #define HALIDE_MUST_USE_RESULT [[nodiscard]] @@ -55,9 +74,9 @@ const char *const kDefineMustUseResult = R"INLINE_CODE(#ifndef HALIDE_MUST_USE_R #define HALIDE_MUST_USE_RESULT #endif #endif -)INLINE_CODE"; +)INLINE_CODE"); -const char *const constexpr_argument_info_docs = R"INLINE_CODE( +const string constexpr_argument_info_docs = normalize_line_endings(R"INLINE_CODE( /** * This function returns a constexpr array of information about a Halide-generated * function's argument signature (e.g., number of arguments, type of each, etc). @@ -88,7 +107,7 @@ const char *const constexpr_argument_info_docs = R"INLINE_CODE( * impact aside from the numerical value of the constant. */ -)INLINE_CODE"; +)INLINE_CODE"); class TypeInfoGatherer : public IRGraphVisitor { private: @@ -194,7 +213,7 @@ CodeGen_C::CodeGen_C(ostream &s, const Target &t, OutputKind output_kind, const // If it's a header, emit an include guard. stream << "#ifndef HALIDE_FUNCTION_INFO_" << c_print_name(guard) << "\n" << "#define HALIDE_FUNCTION_INFO_" << c_print_name(guard) << "\n"; - stream << R"INLINE_CODE( + stream << normalize_line_endings(R"INLINE_CODE( /* MACHINE GENERATED By Halide. */ #if !(__cplusplus >= 201703L || _MSVC_LANG >= 201703L) @@ -203,7 +222,7 @@ CodeGen_C::CodeGen_C(ostream &s, const Target &t, OutputKind output_kind, const #include "HalideRuntime.h" -)INLINE_CODE"; +)INLINE_CODE"); return; } @@ -247,9 +266,9 @@ CodeGen_C::CodeGen_C(ostream &s, const Target &t, OutputKind output_kind, const } else { // Include declarations of everything generated C source might want stream - << halide_c_template_CodeGen_C_prologue << "\n" - << halide_internal_runtime_header_HalideRuntime_h << "\n" - << halide_internal_initmod_inlined_c << "\n"; + << normalize_line_endings(halide_c_template_CodeGen_C_prologue) << "\n" + << normalize_line_endings(halide_internal_runtime_header_HalideRuntime_h) << "\n" + << normalize_line_endings(halide_internal_initmod_inlined_c) << "\n"; stream << "\n"; } @@ -294,24 +313,24 @@ CodeGen_C::~CodeGen_C() { << "// use the -r flag with any Halide generator binary, e.g.:\n" << "// $ ./my_generator -r halide_runtime -o . target=host\n" << "\n" - << halide_internal_runtime_header_HalideRuntime_h << "\n"; + << normalize_line_endings(halide_internal_runtime_header_HalideRuntime_h) << "\n"; if (target.has_feature(Target::CUDA)) { - stream << halide_internal_runtime_header_HalideRuntimeCuda_h << "\n"; + stream << normalize_line_endings(halide_internal_runtime_header_HalideRuntimeCuda_h) << "\n"; } if (target.has_feature(Target::HVX)) { - stream << halide_internal_runtime_header_HalideRuntimeHexagonHost_h << "\n"; + stream << normalize_line_endings(halide_internal_runtime_header_HalideRuntimeHexagonHost_h) << "\n"; } if (target.has_feature(Target::Metal)) { - stream << halide_internal_runtime_header_HalideRuntimeMetal_h << "\n"; + stream << normalize_line_endings(halide_internal_runtime_header_HalideRuntimeMetal_h) << "\n"; } if (target.has_feature(Target::OpenCL)) { - stream << halide_internal_runtime_header_HalideRuntimeOpenCL_h << "\n"; + stream << normalize_line_endings(halide_internal_runtime_header_HalideRuntimeOpenCL_h) << "\n"; } if (target.has_feature(Target::D3D12Compute)) { - stream << halide_internal_runtime_header_HalideRuntimeD3D12Compute_h << "\n"; + stream << normalize_line_endings(halide_internal_runtime_header_HalideRuntimeD3D12Compute_h) << "\n"; } if (target.has_feature(Target::WebGPU)) { - stream << halide_internal_runtime_header_HalideRuntimeWebGPU_h << "\n"; + stream << normalize_line_endings(halide_internal_runtime_header_HalideRuntimeWebGPU_h) << "\n"; } } stream << "#endif\n"; @@ -324,13 +343,7 @@ void CodeGen_C::add_platform_prologue() { void CodeGen_C::add_vector_typedefs(const std::set &vector_types) { if (!vector_types.empty()) { - // Voodoo fix: on at least one config (our arm32 buildbot running gcc 5.4), - // emitting this long text string was regularly garbled in a predictable pattern; - // flushing the stream before or after heals it. Since C++ codegen is rarely - // on a compilation critical path, we'll just band-aid it in this way. - stream << std::flush; - stream << halide_c_template_CodeGen_C_vectors; - stream << std::flush; + stream << normalize_line_endings(halide_c_template_CodeGen_C_vectors); for (const auto &t : vector_types) { string name = print_type(t, DoNotAppendSpace); @@ -354,20 +367,20 @@ void CodeGen_C::add_vector_typedefs(const std::set &vector_types) { void CodeGen_C::set_name_mangling_mode(NameMangling mode) { if (extern_c_open && mode != NameMangling::C) { - stream << R"INLINE_CODE( + stream << normalize_line_endings(R"INLINE_CODE( #ifdef __cplusplus } // extern "C" #endif -)INLINE_CODE"; +)INLINE_CODE"); extern_c_open = false; } else if (!extern_c_open && mode == NameMangling::C) { - stream << R"INLINE_CODE( + stream << normalize_line_endings(R"INLINE_CODE( #ifdef __cplusplus extern "C" { #endif -)INLINE_CODE"; +)INLINE_CODE"); extern_c_open = true; } } @@ -2567,10 +2580,10 @@ void CodeGen_C::test() { } string correct_source = - string((const char *)halide_c_template_CodeGen_C_prologue) + '\n' + - string((const char *)halide_internal_runtime_header_HalideRuntime_h) + '\n' + - string((const char *)halide_internal_initmod_inlined_c) + '\n' + - '\n' + kDefineMustUseResult + R"GOLDEN_CODE( + normalize_line_endings(halide_c_template_CodeGen_C_prologue) + '\n' + + normalize_line_endings(halide_internal_runtime_header_HalideRuntime_h) + '\n' + + normalize_line_endings(halide_internal_initmod_inlined_c) + '\n' + + '\n' + kDefineMustUseResult + normalize_line_endings(R"GOLDEN_CODE( #ifndef HALIDE_FUNCTION_ATTRS #define HALIDE_FUNCTION_ATTRS #endif @@ -2638,7 +2651,7 @@ int test1(struct halide_buffer_t *_buf_buffer, float _alpha, int32_t _beta, void } // extern "C" #endif -)GOLDEN_CODE"; +)GOLDEN_CODE"); const auto compare_srcs = [](const string &actual, const string &expected) { if (actual != expected) { @@ -2673,7 +2686,7 @@ int test1(struct halide_buffer_t *_buf_buffer, float _alpha, int32_t _beta, void cg.compile(m); } - string correct_function_info = R"GOLDEN_CODE(#ifndef HALIDE_FUNCTION_INFO__Function___Info___Test + string correct_function_info = normalize_line_endings(R"GOLDEN_CODE(#ifndef HALIDE_FUNCTION_INFO__Function___Info___Test #define HALIDE_FUNCTION_INFO__Function___Info___Test /* MACHINE GENERATED By Halide. */ @@ -2724,7 +2737,7 @@ inline constexpr std::array<::HalideFunctionInfo::ArgumentInfo, 4> test1_argumen }}; } #endif -)GOLDEN_CODE"; +)GOLDEN_CODE"); compare_srcs(function_info.str(), correct_function_info); diff --git a/src/PythonExtensionGen.cpp b/src/PythonExtensionGen.cpp index e6cac20d9dd7..85674c19229c 100644 --- a/src/PythonExtensionGen.cpp +++ b/src/PythonExtensionGen.cpp @@ -15,6 +15,18 @@ using std::string; namespace { +// See normalize_line_endings in CodeGen_C.cpp for rationale. +string normalize_line_endings(const char *s) { + string result; + result.reserve(strlen(s)); + for (; *s; ++s) { + if (*s != '\r') { + result += *s; + } + } + return result; +} + string sanitize_name(const string &name) { ostringstream oss; for (char c : name) { @@ -95,7 +107,7 @@ std::pair print_type(const LoweredArgument *arg) { } } -const char kModuleRegistrationCode[] = R"INLINE_CODE( +const string kModuleRegistrationCode = normalize_line_endings(R"INLINE_CODE( static_assert(PY_MAJOR_VERSION >= 3, "Python bindings for Halide require Python 3+"); namespace Halide::PythonExtensions { @@ -271,7 +283,7 @@ HALIDE_EXPORT_SYMBOL PyObject *_HALIDE_EXPAND_AND_CONCAT(PyInit_, HALIDE_PYTHON_ } } // extern "C" -)INLINE_CODE"; +)INLINE_CODE"); } // namespace @@ -300,7 +312,7 @@ void PythonExtensionGen::compile(const Module &module) { extern_decl_gen.compile(module); } - dest << R"INLINE_CODE( + dest << normalize_line_endings(R"INLINE_CODE( namespace Halide::PythonRuntime { extern bool unpack_buffer(PyObject *py_obj, int py_getbuffer_flags, @@ -389,7 +401,7 @@ struct PyHalideBuffer { } // namespace -)INLINE_CODE"; +)INLINE_CODE"); for (const auto &f : module.functions()) { if (f.linkage == LinkageType::ExternalPlusMetadata) {