diff --git a/CMakeLists.txt b/CMakeLists.txt index af1f64bd83..938daec865 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -625,11 +625,22 @@ else() else() set(ZIG2_LINK_FLAGS "-Wl,-z,stack-size=0x10000000") endif() - # Prevent GCC from miscompiling 'zig2.c'. See also 'workaround_gcc_sra_miscomp' in 'bootstrap.c'. - if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND - CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "13.0" AND - CMAKE_C_COMPILER_VERSION VERSION_LESS_EQUAL "15.2") - set(ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS} -fno-tree-sra") + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + # Prevent GCC from miscompiling 'zig2.c'. See also 'GCC_BUG_119085_PRESENT' workaround details in 'bootstrap.c'. + if ( + (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "10.0" AND + CMAKE_C_COMPILER_VERSION VERSION_LESS_EQUAL "13.4") OR + (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "14.0" AND + CMAKE_C_COMPILER_VERSION VERSION_LESS_EQUAL "14.3") OR + (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "15.0" AND + CMAKE_C_COMPILER_VERSION VERSION_LESS "15.2") + ) + set(ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS} -fno-tree-sra") + endif() + + # Prevent GCC from spamming false positive `-Waddress-of-packed-member` warnings in 'zig2.c'. + # See also 'GCC_BUG_94081_PRESENT' workaround details in 'bootstrap.c'. + set(ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS} -Wno-address-of-packed-member") endif() endif() diff --git a/bootstrap.c b/bootstrap.c index 8d2725cfb9..cc40670d4a 100644 --- a/bootstrap.c +++ b/bootstrap.c @@ -13,6 +13,49 @@ static void panic(const char *reason) { abort(); } +#if defined(__GNUC__) && !defined(__clang__) + #define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + // GCC versions 10.0--15.1 have a miscompilation where some bytes of a union may get clobbered + // depending on the union layout and the order in which types are defined. This miscompilation + // affects the output of the C backend, and thus can affect the bootstrap process. Specifically, + // we observe that using the self-hosted x86_64 backend in 'zig2' will cause all function calls + // to be relocated incorrectly, causing immediate crashes on any binary produced by it. + // + // The only reliable workaround for this bug is to disable the optimization pass containing it, + // so here we detect whether the compiler being used requires that workaround. + // + // The upstream bug is fixed in GCC version 15.2 onwards (and was also backported to the 13 and + // 14 branches, however there are no 13.x and 14.x releases that contains the fix as of now). + // Once this bug is no longer widespread, we can remove this workaround. + // + // Upstream bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119085 + #if (GCC_VERSION >= 160000) || \ + (GCC_VERSION >= 150200 && GCC_VERSION < 160000) || \ + (GCC_VERSION > 140300 && GCC_VERSION < 150000) || \ + (GCC_VERSION > 130400 && GCC_VERSION < 140000) || \ + (GCC_VERSION <= 100000) + #define GCC_BUG_119085_PRESENT 0 + #else + #define GCC_BUG_119085_PRESENT 1 + #endif + + + // GCC doesn't take into account alignment annotations when --Waddress-of-packed-member is + // evaluated, which causes false positive warnings when the C backend generates code that takes + // the address of a field in a packed struct. + // + // There is no fix for this as now, so the only way to get rid of the false positive warnings + // is to disable the flag altogether. + // + // Upstream bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94081 + #define GCC_BUG_94081_PRESENT 1 +#else + #define GCC_BUG_94081_PRESENT 0 + #define GCC_BUG_119085_PRESENT 0 +#endif + #if defined(__WIN32__) #error TODO write the functionality for executing child process into this build script #else @@ -102,26 +145,6 @@ int main(int argc, char **argv) { const char *cc = get_c_compiler(); const char *host_triple = get_host_triple(); - // GCC versions 10.0--15.1 have a miscompilation where some bytes of a union may get clobbered - // depending on the union layout and the order in which types are defined. This miscompilation - // affects the output of the C backend, and thus can affect the bootstrap process. Specifically, - // we observe that using the self-hosted x86_64 backend in 'zig2' will cause all function calls - // to be relocated incorrectly, causing immediate crashes on any binary produced by it. - // - // The only reliable workaround for this bug is to disable the optimization pass containing it, - // so here we check for a CLI flag requesting that workaround. - // - // The upstream bug is fixed in GCC version 15.2 onwards (and was also backported to the 13 and - // 14 branches). Once this bug is no longer widespread, we can remove this CLI flag. - // - // Upstream bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119085 - bool workaround_gcc_sra_miscomp = false; - for (int i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "--workaround-gcc-sra-miscomp")) { - workaround_gcc_sra_miscomp = true; - } - } - { const char *child_argv[] = { cc, "-o", "zig-wasm2c", "stage1/wasm2c.c", "-O2", "-std=c99", NULL, @@ -214,7 +237,12 @@ int main(int argc, char **argv) { "-pthread", #endif "-fno-strict-aliasing", - workaround_gcc_sra_miscomp ? "-fno-tree-sra" : NULL, +#if GCC_BUG_119085_PRESENT + "-fno-tree-sra", +#endif +#if GCC_BUG_94081_PRESENT + "-Wno-address-of-packed-member", +#endif NULL, }; print_and_run(child_argv); diff --git a/ci/x86_64-linux-release.sh b/ci/x86_64-linux-release.sh index b1f6b84dcd..00446f789c 100755 --- a/ci/x86_64-linux-release.sh +++ b/ci/x86_64-linux-release.sh @@ -21,8 +21,7 @@ export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache" # Test building from source without LLVM. cc -o bootstrap bootstrap.c -# See comments in bootstrap.c for an explanation of the flag given here. -./bootstrap --workaround-gcc-sra-miscomp +./bootstrap ./zig2 build -Dno-lib ./zig-out/bin/zig test test/behavior.zig