Description of problem: During tha compilation of xrood using gcc 12 there are some -Wrestrict warnings I can't make any sense of. Number 1: In file included from /usr/include/c++/12/string:40, from /builddir/build/BUILD/xrootd-5.4.0/src/XrdOssCsi/XrdOssCsiConfig.hh:39, from /builddir/build/BUILD/xrootd-5.4.0/src/XrdOssCsi/XrdOssCsiConfig.cc:32: In function 'std::char_traits<char>::copy(char*, char const*, unsigned long)', inlined from 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy(char*, char const*, unsigned long)' at /usr/include/c++/12/bits/basic_string.h:423:21, inlined from 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy(char*, char const*, unsigned long)' at /usr/include/c++/12/bits/basic_string.h:418:7, inlined from 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace(unsigned long, unsigned long, char const*, unsigned long)' at /usr/include/c++/12/bits/basic_string.tcc:532:22, inlined from 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign(char const*)' at /usr/include/c++/12/bits/basic_string.h:1647:19, inlined from 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(char const*)' at /usr/include/c++/12/bits/basic_string.h:815:28, inlined from 'TagPath::calcPrefixElements()' at /builddir/build/BUILD/xrootd-5.4.0/src/XrdOssCsi/XrdOssCsiConfig.hh:135:46: /usr/include/c++/12/bits/char_traits.h:431:56: warning: 'memcpy' accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Wrestrict] 431 | return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); | ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~ This is the relevant part of the file src/XrdOssCsi/XrdOssCsiConfig.hh void calcPrefixElements() { prefixstart_.clear(); prefixend_.clear(); if (prefix_.empty()) return; simplePath(prefix_); const size_t idx = prefix_.rfind("/"); prefixstart_ = prefix_.substr(0,idx); if (prefixstart_.empty()) prefixstart_="/"; // ← This is line 135 prefixend_ = prefix_.substr(idx+1,std::string::npos); } Position 46 on line 135 is the starting quote around the string "/". It is an assignment of the value "/" to a std::string. The resulting memcpy should at most copy 2 bytes (if the copy includes the terminating \0 byte). I don't see how this can cause an overlap. Number 2: In file included from /usr/include/c++/12/string:40, from /builddir/build/BUILD/xrootd-5.4.0/src/XrdPfc/XrdPfc.hh:20, from /builddir/build/BUILD/xrootd-5.4.0/src/XrdPfc/XrdPfcPurge.cc:1: In function 'std::char_traits<char>::copy(char*, char const*, unsigned long)', inlined from 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy(char*, char const*, unsigned long)' at /usr/include/c++/12/bits/basic_string.h:423:21, inlined from 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy(char*, char const*, unsigned long)' at /usr/include/c++/12/bits/basic_string.h:418:7, inlined from 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace(unsigned long, unsigned long, char const*, unsigned long)' at /usr/include/c++/12/bits/basic_string.tcc:532:22, inlined from 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign(char const*)' at /usr/include/c++/12/bits/basic_string.h:1647:19, inlined from 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(char const*)' at /usr/include/c++/12/bits/basic_string.h:815:28, inlined from 'XrdPfc::FPurgeState::begin_traversal(XrdPfc::DirState*, char const*)' at /builddir/build/BUILD/xrootd-5.4.0/src/XrdPfc/XrdPfcPurge.cc:279:24, inlined from 'XrdPfc::Cache::Purge()' at /builddir/build/BUILD/xrootd-5.4.0/src/XrdPfc/XrdPfcPurge.cc:829:39: /usr/include/c++/12/bits/char_traits.h:431:56: warning: 'memcpy' accessing 9223372036854775810 or more bytes at offsets -4611686018427387902 and [-4611686018427387903, 4611686018427387904] may overlap up to 9223372036854775813 bytes at offset -3 [-Wrestrict] 431 | return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); | ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~ This is the relevant part of the file src/XrdPfc/XrdPfcPurge.cc: void begin_traversal(DirState *root, const char *root_path = "/") { m_dir_state = root; m_dir_level = 0; m_current_path = root_path; // ← This is line 279 m_dir_usage_stack.push_back(0); TRACE_PURGE("FPurgeState::begin_traversal cur_path '" << m_current_path <\ < "', usage=" << m_dir_usage_stack.back() << ", level=" << m_dir_level); } Position 24 on line 279 is the "r" in the filename "root_path". The last line of the trace says this method is called form line 829, which reads: purgeState.begin_traversal(m_fs_state->get_root()); i.e. it is called with one argument and the second argument "root_path" get the default value, which is "/". So again this is an assignment of a the value "/" to a std::string. I don't see how this can cause an overlap. Version-Release number of selected component (if applicable): gcc-c++-12.0.1-0.3.fc36 How reproducible: Always. Steps to Reproduce: 1. Build xrootd for Fedora 36 Actual results: Strange -Wrestrict warnings Expected results: No such warnings Additional info: The xrootd build in koji is here: https://koji.fedoraproject.org/koji/buildinfo?buildID=1903276
We'll need a translation unit for the affected source file (the result of compiling with -E) to reproduce the warning to fully analyze it. My best guess is that the warning points out code that was isolated by some GCC optimization and that's either unreachable, or reachable under unlikely conditions that aren't obvious from the source. We have seen and suppressed similar warnings issued for code defined in libstdc++ headers and inlined into user programs, but I don't think -Wrestrict was among those.
Created attachment 1858279 [details] Preprocessed code 1 (using --save-temps)
Created attachment 1858282 [details] Preprocessed code 2 (using --save-temps)
The reduced test case below reproduces a similar warning with -O2 -D_GLIBCXX_ASSERTIONS. It's a false positive precipitated by a call to std::string::_M_disjunct() function made to handle self-insertion. GCC's alias analysis isn't "intelligent" enough to rule out the possibility that the "/" literal overlaps with s's buffer, so both branches of libstdc++ code, one to handle the overlapping case, and the nonoverlapping one, are emitted. The overlapping one is the one that triggers the warning. We worked around a similar problem before (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98465) and looks like we might need to again. Longer term, we need to make GCC alias analysis smarter. I've raised https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104336 upstream. std::string s; void f (void) { s = "/"; } In file included from /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/string:40, from t.C:1: In static member function ‘static std::char_traits<char>::char_type* std::char_traits<char>::copy(char_type*, const char_type*, std::size_t)’, inlined from ‘static void std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_S_copy(_CharT*, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:423:21, inlined from ‘static void std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_S_copy(_CharT*, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:418:7, inlined from ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_M_replace(size_type, size_type, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:532:22, inlined from ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::assign(const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:1647:19, inlined from ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:815:28, inlined from ‘void f()’ at t.C:7:7: /build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/char_traits.h:431:56: warning: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ accessing 9223372036854775810 or more bytes at offsets -4611686018427387902 and [-4611686018427387903, 4611686018427387904] may overlap up to 9223372036854775813 bytes at offset -3 [-Wrestrict] 431 | return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); | ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
This bug appears to have been reported against 'rawhide' during the Fedora 36 development cycle. Changing version to 36.
Marking this as blocking colobot's and spirv-tools's FTBFS bugs, as both these packages build with -Werror by default and had their builds fail because of the memcpy warning.
IMHO if a package chooses to build with -Werror then that package needs to be prepared to use -Wno-error=xxx for specific warnings. GCC doesn't force any package to use -Werror.
I mean, in the case of Colobot, it's upstream preference set in CMakeLists.txt. Those can, of course, be patched to either remove -Werror, or add -Wno-error=restrict, but I'd rather patch the *code*, if possible (and then submit that upstream). Either way, I plan on waiting a bit to see the response on the gcc bug report.
Warnings can be disabled with pragmas in the code too etc. Using -Werror means one needs to be prepared to deal with warnings, and also accept that some warnings are false positives and be able to work around them.
just FYI I've pragma this in the spirv-tools builds for now.
*** Bug 2057597 has been marked as a duplicate of this bug. ***
Created attachment 1874858 [details] Proposed fix Proposed fix: ``` {.diff} --- usr/include/c++/12/bits/basic_string.tcc.orig 2022-04-14 01:23:43.000000000 +0200 +++ usr/include/c++/12/bits/basic_string.tcc 2022-04-25 16:18:57.028352162 +0200 @@ -527,10 +527,10 @@ } else { - const size_type __nleft = (__p + __len1) - __s; - this->_S_move(__p, __s, __nleft); - this->_S_copy(__p + __nleft, __p + __len2, - __len2 - __nleft); + const size_type __nleft = (__s + __len2) - (__p + __len1); + this->_S_move(__p, __s, __len2 - __nleft); + this->_S_copy(__p + __len2 - __nleft, __p + __len2, + __nleft); } } } ```
Any chance of getting this fixed? I know it is a false positive warning, and therefore maybe not critical. But it is easy to trigger as the reduced test case in comment #4 shows. And it has been reported twice in upstream's bugzilla already.
This message is a reminder that Fedora Linux 36 is nearing its end of life. Fedora will stop maintaining and issuing updates for Fedora Linux 36 on 2023-05-16. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as EOL if it remains open with a 'version' of '36'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, change the 'version' to a later Fedora Linux version. Note that the version field may be hidden. Click the "Show advanced fields" button if you do not see it. Thank you for reporting this issue and we are sorry that we were not able to fix it before Fedora Linux 36 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora Linux, you are encouraged to change the 'version' to a later version prior to this bug being closed.
Fedora Linux 36 entered end-of-life (EOL) status on 2023-05-16. Fedora Linux 36 is no longer maintained, which means that it will not receive any further security or bug fix updates. As a result we are closing this bug. If you can reproduce this bug against a currently maintained version of Fedora Linux please feel free to reopen this bug against that version. Note that the version field may be hidden. Click the "Show advanced fields" button if you do not see the version field. If you are unable to reopen this bug, please file a new report against an active release. Thank you for reporting this bug and we are sorry it could not be fixed.
The needinfo request[s] on this closed bug have been removed as they have been unresolved for 120 days