g++ 10.3.0:误报还是实际问题?

g++ 10.3.0: False positive or an actual problem?

使用 g++ 10.3 编译以下代码会给出一些可怕的警告(参见 https://godbolt.org/z/excrEzjsd):

#include <iostream>
#include <memory>
#include <vector>
#include <cstring>
#include <boost/algorithm/clamp.hpp>

namespace demo {
template <typename T, size_t N> constexpr std::size_t array_size(T (&)[N]) { return N; }
template <std::size_t N> inline void StrCpy(std::string::value_type (&dest)[N], const std::string::value_type *src) {
    std::strncpy(dest, src, N);
    dest[N - 1] = 0; // make sure the terminating NUL is there
}

template <std::size_t N> inline void StrCpy(std::string::value_type (&dest)[N], const std::string &src) { StrCpy(dest, src.c_str()); }
} // namespace demo
int main() {
    struct a {
        int m_num_lines;
        char m_lines[6][201];
    };

    std::vector<std::string> lines{
        "Line0",
        "Line1",
        "Line2",
        "Line3",
        "Line4",
        "Line5",
        "Line6",
        "Line7",
        "Line8",
        "Line9",
        "Line10",
    };

    auto theA = std::make_shared<a>();

    theA->m_num_lines = boost::algorithm::clamp(lines.size(), 0, demo::array_size(theA->m_lines));

    for (auto i = 0; i < theA->m_num_lines; i++) {
        demo::StrCpy(theA->m_lines[i], lines[i]);
    }

    for (auto i = 0; i < theA->m_num_lines; i++) {
        std::cout << theA->m_lines[i] << std::endl;
    }
}

我不明白编译器实际上想说什么。我有错误还是编译器看到了幻影?顺便说一句:clang++ 和 MSVC 看不出这里有什么问题。

输出:

g++ -Wall -pedantic -O3 gcc.cpp -o gcc-bug
In file included from /usr/include/string.h:495,
                 from /usr/include/c++/10/cstring:42,
                 from gcc.cpp:4:
In function ‘char* strncpy(char*, const char*, size_t)’,
    inlined from ‘void demo::StrCpy(std::__cxx11::basic_string<char>::value_type (&)[N], const value_type*) [with long unsigned int N = 201]’ at gcc.cpp:10:17,
    inlined from ‘int main()’ at gcc.cpp:14:113:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:34: warning: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ forming offset [1212, 1410] is out of the bounds [0, 1212] [-Warray-bounds]
  106 |   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
      |          ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In function ‘void demo::StrCpy(std::__cxx11::basic_string<char>::value_type (&)[N], const value_type*) [with long unsigned int N = 201]’,
    inlined from ‘int main()’ at gcc.cpp:14:113:
gcc.cpp:11:17: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   11 |     dest[N - 1] = 0; // make sure the terminating NUL is there
      |     ~~~~~~~~~~~~^~~
gcc.cpp: In function ‘int main()’:
gcc.cpp:19:14: note: at offset 206 to object ‘main()::a::m_lines’ with size 1206 declared here
   19 |         char m_lines[6][201];
      |              ^~~~~~~

感谢@StoryTeller-UnslanderMonica 将此识别为编译器错误。添加选项 -fno-peel-loops 解决问题。