Regression between 0.8.29 and 0.8.30 with GCC 14.2.1 on AArch64 and PPC64le
Description
Solidity build fails with GCC 14.2.1 on AArch64 and PPC64le but completes just fine on these arches with a more modern GCC 15.1.1. On X86_64 it compiles just fine with both GCC versions.
Environment
- Compiler version: GCC 14.2.1
- Compilation pipeline (legacy, IR, EOF): n/a
- Target EVM version (as per compiler settings): n/a
- Framework/IDE (e.g. Foundry, Hardhat, Remix): n/a
- EVM execution environment / backend / blockchain client: n/a
- Operating system: Linux
Steps to Reproduce
I've tried to build solidity with the following parameters (note the -Werror=array-bounds parameter implied by -Wall):
CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection '
CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection '
...
/usr/bin/cmake -S . -B redhat-linux-build -DCMAKE_C_FLAGS_RELEASE:STRING=-DNDEBUG -DCMAKE_CXX_FLAGS_RELEASE:STRING=-DNDEBUG -DCMAKE_Fortran_FLAGS_RELEASE:STRING=-DNDEBUG -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCMAKE_INSTALL_DO_STRIP:BOOL=OFF -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_INSTALL_FULL_SBINDIR:PATH=/usr/sbin -DCMAKE_INSTALL_SBINDIR:PATH=sbin -DINCLUDE_INSTALL_DIR:PATH=/usr/include -DLIB_INSTALL_DIR:PATH=/usr/lib64 -DSYSCONF_INSTALL_DIR:PATH=/etc -DSHARE_INSTALL_PREFIX:PATH=/usr/share -DLIB_SUFFIX=64 -DBUILD_SHARED_LIBS:BOOL=ON -DIGNORE_VENDORED_DEPENDENCIES:BOOL=ON -DBoost_USE_STATIC_LIBS:BOOL=OFF -DSTRICT_Z3_VERSION:BOOL=OFF -DTESTS:BOOL=OFF
It works just fine on x86_64 with this old GCC version but fails on secondary arches (aarch64, ppc64le) with the following stacktrace:
[ 57%] Building CXX object libsolidity/CMakeFiles/solidity.dir/analysis/ControlFlowRevertPruner.cpp.o
cd /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/redhat-linux-build/libsolidity && /usr/bin/g++ -DBOOST_ATOMIC_DYN_LINK -DBOOST_ATOMIC_NO_LIB -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_FILESYSTEM_NO_LIB -DBOOST_SYSTEM_DYN_LINK -DBOOST_SYSTEM_NO_LIB -DFMT_HEADER_ONLY=1 -I/builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/redhat-linux-build/include -I/builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30 -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -O2 -DNDEBUG -std=c++20 -fstack-protector-strong -Wimplicit-fallthrough -fmacro-prefix-map=/builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30=/solidity -Wpessimizing-move -Wredundant-move -Wall -Wextra -Werror -pedantic -Wmissing-declarations -Wno-unknown-pragmas -Wsign-conversion -Wconversion -Wextra-semi -Wno-dangling-reference -Wduplicated-cond -Wlogical-op -fdiagnostics-color -MD -MT libsolidity/CMakeFiles/solidity.dir/analysis/ControlFlowRevertPruner.cpp.o -MF CMakeFiles/solidity.dir/analysis/ControlFlowRevertPruner.cpp.o.d -o CMakeFiles/solidity.dir/analysis/ControlFlowRevertPruner.cpp.o -c /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/analysis/ControlFlowRevertPruner.cpp
In file included from /usr/include/c++/14/bits/stl_uninitialized.h:63,
from /usr/include/c++/14/memory:69,
from /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/ast/ASTForward.h:26,
from /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/ast/AST.h:26,
from /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/analysis/ControlFlowRevertPruner.h:21,
from /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/analysis/ControlFlowRevertPruner.cpp:19:
In function ‘std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m<solidity::frontend::CFGNode* const, solidity::frontend::CFGNode*>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’,
inlined from ‘std::__copy_move_a2<false, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’ at /usr/include/c++/14/bits/stl_algobase.h:521:30,
inlined from ‘std::__copy_move_a1<false, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’ at /usr/include/c++/14/bits/stl_algobase.h:548:42,
inlined from ‘std::__copy_move_a<false, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’ at /usr/include/c++/14/bits/stl_algobase.h:555:31,
inlined from ‘std::copy<solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’ at /usr/include/c++/14/bits/stl_algobase.h:651:7,
inlined from ‘std::vector<solidity::frontend::CFGNode*, std::allocator<solidity::frontend::CFGNode*> >::_M_assign_aux<solidity::frontend::CFGNode* const*>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, std::forward_iterator_tag)void’ at /usr/include/c++/14/bits/vector.tcc:348:15,
inlined from ‘std::vector<solidity::frontend::CFGNode*, std::allocator<solidity::frontend::CFGNode*> >::operator=(std::initializer_list<solidity::frontend::CFGNode*>)’ at /usr/include/c++/14/bits/stl_vector.h:790:21,
inlined from ‘solidity::frontend::ControlFlowRevertPruner::modifyFunctionFlows()::{lambda(solidity::frontend::CFGNode*, auto:1&&)#1}::operator()<solidity::util::BreadthFirstSearch<solidity::frontend::CFGNode*>::run<{lambda(solidity::frontend::CFGNode*, auto:1&&)#1}>({lambda(solidity::frontend::CFGNode*, auto:1&&)#1}&&)::{lambda(solidity::frontend::CFGNode*)#1}>(solidity::frontend::CFGNode*, {lambda(solidity::frontend::CFGNode*, auto:1&&)#1}&&) constauto’ at /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/analysis/ControlFlowRevertPruner.cpp:148:43,
inlined from ‘solidity::util::BreadthFirstSearch<solidity::frontend::CFGNode*>::run<solidity::frontend::ControlFlowRevertPruner::modifyFunctionFlows()::{lambda(solidity::frontend::CFGNode*, auto:1&&)#1}>(solidity::frontend::ControlFlowRevertPruner::modifyFunctionFlows()::{lambda(solidity::frontend::CFGNode*, auto:1&&)#1}&&)solidity::util::BreadthFirstSearch<solidity::frontend::CFGNode*>&’ at /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolutil/Algorithms.h:113:17,
inlined from ‘solidity::frontend::ControlFlowRevertPruner::modifyFunctionFlows()’ at /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/analysis/ControlFlowRevertPruner.cpp:132:73:
/usr/include/c++/14/bits/stl_algobase.h:452:30: error: ‘memcpy’ forming offset 8 is out of the bounds [0, 8] of object ‘<anonymous>’ with type ‘struct CFGNode * const[1]’ [-Werror=array-bounds=]
452 | __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/analysis/ControlFlowRevertPruner.cpp: In member function ‘solidity::frontend::ControlFlowRevertPruner::modifyFunctionFlows()’:
/builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/analysis/ControlFlowRevertPruner.cpp:148:92: note: ‘<anonymous>’ declared here
148 | _node->exits = {functionFlow.revert};
| ^
In function ‘std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m<solidity::frontend::CFGNode* const, solidity::frontend::CFGNode*>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’,
inlined from ‘std::__copy_move_a2<false, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’ at /usr/include/c++/14/bits/stl_algobase.h:521:30,
inlined from ‘std::__copy_move_a1<false, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’ at /usr/include/c++/14/bits/stl_algobase.h:548:42,
inlined from ‘std::__copy_move_a<false, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’ at /usr/include/c++/14/bits/stl_algobase.h:555:31,
inlined from ‘std::copy<solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’ at /usr/include/c++/14/bits/stl_algobase.h:651:7,
inlined from ‘std::__uninitialized_copy<true>::__uninit_copy<solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’ at /usr/include/c++/14/bits/stl_uninitialized.h:147:27,
inlined from ‘std::uninitialized_copy<solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**)solidity::frontend::CFGNode**’ at /usr/include/c++/14/bits/stl_uninitialized.h:185:15,
inlined from ‘std::__uninitialized_copy_a<solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**, solidity::frontend::CFGNode*>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode**, std::allocator<solidity::frontend::CFGNode*>&)solidity::frontend::CFGNode**’ at /usr/include/c++/14/bits/stl_uninitialized.h:373:37,
inlined from ‘std::vector<solidity::frontend::CFGNode*, std::allocator<solidity::frontend::CFGNode*> >::_M_assign_aux<solidity::frontend::CFGNode* const*>(solidity::frontend::CFGNode* const*, solidity::frontend::CFGNode* const*, std::forward_iterator_tag)void’ at /usr/include/c++/14/bits/vector.tcc:352:35,
inlined from ‘std::vector<solidity::frontend::CFGNode*, std::allocator<solidity::frontend::CFGNode*> >::operator=(std::initializer_list<solidity::frontend::CFGNode*>)’ at /usr/include/c++/14/bits/stl_vector.h:790:21,
inlined from ‘solidity::frontend::ControlFlowRevertPruner::modifyFunctionFlows()::{lambda(solidity::frontend::CFGNode*, auto:1&&)#1}::operator()<solidity::util::BreadthFirstSearch<solidity::frontend::CFGNode*>::run<{lambda(solidity::frontend::CFGNode*, auto:1&&)#1}>({lambda(solidity::frontend::CFGNode*, auto:1&&)#1}&&)::{lambda(solidity::frontend::CFGNode*)#1}>(solidity::frontend::CFGNode*, {lambda(solidity::frontend::CFGNode*, auto:1&&)#1}&&) constauto’ at /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/analysis/ControlFlowRevertPruner.cpp:148:43,
inlined from ‘solidity::util::BreadthFirstSearch<solidity::frontend::CFGNode*>::run<solidity::frontend::ControlFlowRevertPruner::modifyFunctionFlows()::{lambda(solidity::frontend::CFGNode*, auto:1&&)#1}>(solidity::frontend::ControlFlowRevertPruner::modifyFunctionFlows()::{lambda(solidity::frontend::CFGNode*, auto:1&&)#1}&&)solidity::util::BreadthFirstSearch<solidity::frontend::CFGNode*>&’ at /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolutil/Algorithms.h:113:17,
inlined from ‘solidity::frontend::ControlFlowRevertPruner::modifyFunctionFlows()’ at /builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/analysis/ControlFlowRevertPruner.cpp:132:73:
/usr/include/c++/14/bits/stl_algobase.h:452:30: error: ‘memcpy’ offset [-9223372036854775799, -1] is out of the bounds [0, 8] of object ‘<anonymous>’ with type ‘struct CFGNode * const[1]’ [-Werror=array-bounds=]
452 | __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/analysis/ControlFlowRevertPruner.cpp: In member function ‘solidity::frontend::ControlFlowRevertPruner::modifyFunctionFlows()’:
/builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/libsolidity/analysis/ControlFlowRevertPruner.cpp:148:92: note: ‘<anonymous>’ declared here
148 | _node->exits = {functionFlow.revert};
| ^
cc1plus: all warnings being treated as errors
gmake[2]: Leaving directory '/builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/redhat-linux-build'
gmake[2]: *** [libsolidity/CMakeFiles/solidity.dir/build.make:149: libsolidity/CMakeFiles/solidity.dir/analysis/ControlFlowRevertPruner.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:432: libsolidity/CMakeFiles/solidity.dir/all] Error 2
gmake: *** [Makefile:139: all] Error 2
gmake[1]: Leaving directory '/builddir/build/BUILD/solidity-0.8.30-build/solidity-0.8.30/redhat-linux-build'
I suspect this is likely a compiler's bug but maybe we could hint it somehow to calculate arrays properly?
Again everything is totally fine on x86_64, that's just a problem with non-Intel/AMD arches with a non-recent compiler.
Obviously if I add -Wno-error=array-bounds to CXXFLAGS then everything builds just fine on any architectures.