Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler warning 'array-bounds' on g++12.2.0 on Ubuntu 22.10 kinetic with RelWithDebugInfo #3808

Closed
1 of 2 tasks
NeroBurner opened this issue Oct 27, 2022 · 6 comments
Closed
1 of 2 tasks
Labels
confirmed solution: invalid the issue is not related to the library solution: wontfix the issue will not be fixed (either it is impossible or deemed out of scope)

Comments

@NeroBurner
Copy link

NeroBurner commented Oct 27, 2022

Description

On the latest Ubuntu 22.10 kinetic release -Werror in RelWithDebInfo can't be used because of compiler warning array-bounds

Reproduction steps

  • Get g++-12 like Ubuntu 22.10 kinetic
    • for example the ubuntu:22.10 docker container docker run --rm -it -v"${PWD}":"${PWD}" -w "${PWD}" ubuntu:22.10
    • install build dependencies sudo apt update -q && sudo apt install -yq g++ cmake make

Build Release with Debug Info, enable warnings and error on them, then build test-constructor1_cpp11

cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_CXX_FLAGS="-Werror -Wall -Wextra -pedantic"
cmake --build build --target test-constructor1_cpp11

Get Build Error

Expected vs. actual results

expected: build without warning

actual result: build warning (leading to error because of my -Werror flag)

Minimal code example

// Unittest `constructor1.cpp` in `RelWithDebInfo` build type
TEST_CASE("constructors")
{
    SECTION("create a JSON container from an iterator range")
    {
        SECTION("other values")
        {
            SECTION("construct with two valid iterators")
            {
                SECTION("string")
                {
                    {
                        json j = "foo";
                        json const j_new(j.begin(), j.end());
                        CHECK(j == j_new);
                    }
                    {
                        json const j = "bar";
                        json const j_new(j.cbegin(), j.cend());
                        CHECK(j == j_new);
                    }
                }
            }
        }
    }
}

Error messages

cmake --build build --target test-constructor1_cpp11
[ 33%] Building CXX object tests/CMakeFiles/test_main.dir/src/unit.cpp.o
[ 33%] Built target test_main
[ 66%] Building CXX object tests/CMakeFiles/test-constructor1_cpp11.dir/src/unit-constructor1.cpp.o
In file included from /usr/include/c++/12/map:60,
                 from /home/nero/repos/external/nlohmann-json/include/nlohmann/detail/conversions/from_json.hpp:15,
                 from /home/nero/repos/external/nlohmann-json/include/nlohmann/adl_serializer.hpp:14,
                 from /home/nero/repos/external/nlohmann-json/include/nlohmann/json.hpp:35,
                 from /home/nero/repos/external/nlohmann-json/tests/src/unit-constructor1.cpp:12:
In member function 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::begin() [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> > >]',
    inlined from 'std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::begin() [with _Key = std::__cxx11::basic_string<char>; _Tp = nlohmann::json_abi_v3_11_2::basic_json<>; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> > >]' at /usr/include/c++/12/bits/stl_map.h:367:26,
    inlined from 'void nlohmann::json_abi_v3_11_2::detail::iter_impl<BasicJsonType>::set_begin() [with BasicJsonType = nlohmann::json_abi_v3_11_2::basic_json<>]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/detail/iterators/iter_impl.hpp:205:71,
    inlined from 'nlohmann::json_abi_v3_11_2::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::iterator nlohmann::json_abi_v3_11_2::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::begin() [with ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::json_abi_v3_11_2::adl_serializer; BinaryType = std::vector<unsigned char>]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/json.hpp:2761:25,
    inlined from 'void _DOCTEST_ANON_FUNC_2()' at /home/nero/repos/external/nlohmann-json/tests/src/unit-constructor1.cpp:1425:43:
/usr/include/c++/12/bits/stl_tree.h:996:16: error: array subscript 'std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> > >, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> > > >[0]' is partly outside array bounds of 'unsigned char [32]' [-Werror=array-bounds]
  996 |       { return iterator(this->_M_impl._M_header._M_left); }
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/x86_64-linux-gnu/c++/12/bits/c++allocator.h:33,
                 from /usr/include/c++/12/bits/allocator.h:46,
                 from /usr/include/c++/12/string:41,
                 from /usr/include/c++/12/bits/locale_classes.h:40,
                 from /usr/include/c++/12/bits/ios_base.h:41,
                 from /usr/include/c++/12/streambuf:41,
                 from /usr/include/c++/12/bits/streambuf_iterator.h:35,
                 from /usr/include/c++/12/iterator:66,
                 from /home/nero/repos/external/nlohmann-json/include/nlohmann/json.hpp:28:
In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = std::__cxx11::basic_string<char>]',
    inlined from 'static _Tp* std::allocator_traits<std::allocator<_CharT> >::allocate(allocator_type&, size_type) [with _Tp = std::__cxx11::basic_string<char>]' at /usr/include/c++/12/bits/alloc_traits.h:464:28,
    inlined from 'static T* nlohmann::json_abi_v3_11_2::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::create(Args&& ...) [with T = std::__cxx11::basic_string<char>; Args = {const char (&)[4]}; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::json_abi_v3_11_2::adl_serializer; BinaryType = std::vector<unsigned char>]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/json.hpp:387:47,
    inlined from 'static void nlohmann::json_abi_v3_11_2::detail::external_constructor<nlohmann::json_abi_v3_11_2::detail::value_t::string>::construct(BasicJsonType&, const CompatibleStringType&) [with BasicJsonType = nlohmann::json_abi_v3_11_2::basic_json<>; CompatibleStringType = char [4]; typename std::enable_if<(! std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value), int>::type <anonymous> = 0]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/detail/conversions/to_json.hpp:85:79,
    inlined from 'void nlohmann::json_abi_v3_11_2::detail::to_json(BasicJsonType&, const CompatibleString&) [with BasicJsonType = nlohmann::json_abi_v3_11_2::basic_json<>; CompatibleString = char [4]; typename std::enable_if<std::is_constructible<typename BasicJsonType::string_t, Key>::value, int>::type <anonymous> = 0]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/detail/conversions/to_json.hpp:287:53,
    inlined from 'decltype ((nlohmann::json_abi_v3_11_2::detail::to_json(j, forward<T>(val)), void())) nlohmann::json_abi_v3_11_2::detail::to_json_fn::operator()(BasicJsonType&, T&&) const [with BasicJsonType = nlohmann::json_abi_v3_11_2::basic_json<>; T = const char (&)[4]]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/detail/conversions/to_json.hpp:428:23,
    inlined from 'static decltype ((nlohmann::json_abi_v3_11_2::{anonymous}::to_json(j, forward<TargetType>(val)), void())) nlohmann::json_abi_v3_11_2::adl_serializer<T, SFINAE>::to_json(BasicJsonType&, TargetType&&) [with BasicJsonType = nlohmann::json_abi_v3_11_2::basic_json<>; TargetType = const char (&)[4]; ValueType = char [4]; <template-parameter-1-2> = void]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/adl_serializer.hpp:51:28,
    inlined from 'nlohmann::json_abi_v3_11_2::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::basic_json(CompatibleType&&) [with CompatibleType = const char (&)[4]; U = char [4]; typename std::enable_if<((! nlohmann::json_abi_v3_11_2::detail::is_basic_json<U>::value) && nlohmann::json_abi_v3_11_2::detail::is_compatible_type<nlohmann::json_abi_v3_11_2::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>, U>::value), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::json_abi_v3_11_2::adl_serializer; BinaryType = std::vector<unsigned char>]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/json.hpp:829:35,
    inlined from 'void _DOCTEST_ANON_FUNC_2()' at /home/nero/repos/external/nlohmann-json/tests/src/unit-constructor1.cpp:1424:34:
/usr/include/c++/12/bits/new_allocator.h:137:55: note: object of size 32 allocated by 'operator new'
  137 |         return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp)));
      |                                                       ^
In member function 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::begin() [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> > >]',
    inlined from 'std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::begin() [with _Key = std::__cxx11::basic_string<char>; _Tp = nlohmann::json_abi_v3_11_2::basic_json<>; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> > >]' at /usr/include/c++/12/bits/stl_map.h:367:26,
    inlined from 'void nlohmann::json_abi_v3_11_2::detail::iter_impl<BasicJsonType>::set_begin() [with BasicJsonType = const nlohmann::json_abi_v3_11_2::basic_json<>]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/detail/iterators/iter_impl.hpp:205:71,
    inlined from 'nlohmann::json_abi_v3_11_2::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::const_iterator nlohmann::json_abi_v3_11_2::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::cbegin() const [with ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::json_abi_v3_11_2::adl_serializer; BinaryType = std::vector<unsigned char>]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/json.hpp:2777:25,
    inlined from 'void _DOCTEST_ANON_FUNC_2()' at /home/nero/repos/external/nlohmann-json/tests/src/unit-constructor1.cpp:1430:44:
/usr/include/c++/12/bits/stl_tree.h:996:16: error: array subscript 'std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> > >, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_2::basic_json<> > > >[0]' is partly outside array bounds of 'unsigned char [32]' [-Werror=array-bounds]
  996 |       { return iterator(this->_M_impl._M_header._M_left); }
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = std::__cxx11::basic_string<char>]',
    inlined from 'static _Tp* std::allocator_traits<std::allocator<_CharT> >::allocate(allocator_type&, size_type) [with _Tp = std::__cxx11::basic_string<char>]' at /usr/include/c++/12/bits/alloc_traits.h:464:28,
    inlined from 'static T* nlohmann::json_abi_v3_11_2::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::create(Args&& ...) [with T = std::__cxx11::basic_string<char>; Args = {const char (&)[4]}; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::json_abi_v3_11_2::adl_serializer; BinaryType = std::vector<unsigned char>]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/json.hpp:387:47,
    inlined from 'static void nlohmann::json_abi_v3_11_2::detail::external_constructor<nlohmann::json_abi_v3_11_2::detail::value_t::string>::construct(BasicJsonType&, const CompatibleStringType&) [with BasicJsonType = nlohmann::json_abi_v3_11_2::basic_json<>; CompatibleStringType = char [4]; typename std::enable_if<(! std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value), int>::type <anonymous> = 0]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/detail/conversions/to_json.hpp:85:79,
    inlined from 'void nlohmann::json_abi_v3_11_2::detail::to_json(BasicJsonType&, const CompatibleString&) [with BasicJsonType = nlohmann::json_abi_v3_11_2::basic_json<>; CompatibleString = char [4]; typename std::enable_if<std::is_constructible<typename BasicJsonType::string_t, Key>::value, int>::type <anonymous> = 0]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/detail/conversions/to_json.hpp:287:53,
    inlined from 'decltype ((nlohmann::json_abi_v3_11_2::detail::to_json(j, forward<T>(val)), void())) nlohmann::json_abi_v3_11_2::detail::to_json_fn::operator()(BasicJsonType&, T&&) const [with BasicJsonType = nlohmann::json_abi_v3_11_2::basic_json<>; T = const char (&)[4]]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/detail/conversions/to_json.hpp:428:23,
    inlined from 'static decltype ((nlohmann::json_abi_v3_11_2::{anonymous}::to_json(j, forward<TargetType>(val)), void())) nlohmann::json_abi_v3_11_2::adl_serializer<T, SFINAE>::to_json(BasicJsonType&, TargetType&&) [with BasicJsonType = nlohmann::json_abi_v3_11_2::basic_json<>; TargetType = const char (&)[4]; ValueType = char [4]; <template-parameter-1-2> = void]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/adl_serializer.hpp:51:28,
    inlined from 'nlohmann::json_abi_v3_11_2::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::basic_json(CompatibleType&&) [with CompatibleType = const char (&)[4]; U = char [4]; typename std::enable_if<((! nlohmann::json_abi_v3_11_2::detail::is_basic_json<U>::value) && nlohmann::json_abi_v3_11_2::detail::is_compatible_type<nlohmann::json_abi_v3_11_2::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>, U>::value), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::json_abi_v3_11_2::adl_serializer; BinaryType = std::vector<unsigned char>]' at /home/nero/repos/external/nlohmann-json/include/nlohmann/json.hpp:829:35,
    inlined from 'void _DOCTEST_ANON_FUNC_2()' at /home/nero/repos/external/nlohmann-json/tests/src/unit-constructor1.cpp:1429:34:
/usr/include/c++/12/bits/new_allocator.h:137:55: note: object of size 32 allocated by 'operator new'
  137 |         return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp)));
      |                                                       ^
cc1plus: all warnings being treated as errors
gmake[3]: *** [tests/CMakeFiles/test-constructor1_cpp11.dir/build.make:76: tests/CMakeFiles/test-constructor1_cpp11.dir/src/unit-constructor1.cpp.o] Error 1
gmake[2]: *** [CMakeFiles/Makefile2:1681: tests/CMakeFiles/test-constructor1_cpp11.dir/all] Error 2
gmake[1]: *** [CMakeFiles/Makefile2:1688: tests/CMakeFiles/test-constructor1_cpp11.dir/rule] Error 2
gmake: *** [Makefile:790: test-constructor1_cpp11] Error 2

Compiler and operating system

Ubuntu 22.10, g++12.2

Library version

3.11.2

Validation


edit: copied affected code from unit-constructor1.cpp to minimal example

@NeroBurner
Copy link
Author

also happens on the g++12 compiler from Ubuntu 22.04 jammy

$ g++-12 --version
g++-12 (Ubuntu 12.1.0-2ubuntu1~22.04) 12.1.0

@falbrechtskirchinger
Copy link
Contributor

I'd class this as a false positive. The compiler is complaining about the call to begin() here:

    void set_begin() noexcept
    {
        JSON_ASSERT(m_object != nullptr);

        switch (m_object->m_type)
        {
            case value_t::object:
            {
                m_it.object_iterator = m_object->m_value.object->begin();
                break;
            }

Of course, this call will only happen if the correct type (i.e. std::map) is stored. m_type is value_t::string in this case.

@NeroBurner
Copy link
Author

NeroBurner commented Oct 19, 2023

still happens on Ubuntu 23.10 mantis with gcc (Ubuntu 13.2.0-4ubuntu3) 13.2.0

tested on current develop branch with commit edffad0

@kkarbowiak
Copy link
Contributor

Still happens on Ubuntu 24.04 with g++ (Ubuntu 13.2.0-23ubuntu4) 13.2.0 and develop branch commit 960b763.

@nlohmann
Copy link
Owner

I agree with @falbrechtskirchinger - this is a false positive. I will check if this is the only position in the code that is affected - then a local exception of the warning flag could make sense.

@nlohmann
Copy link
Owner

I checked again - more tests are affected by this or similar versions of -Warray-bounds warnings. I have not looked into most of them, but given we don't have any actual warnings from Valgrind or ASAN, I don't worry about this. I don't plan to annotate all tests with suppressions for this warning.

If somebody decides to compile the tests with -Werror -Warray-bounds, then this is what you get.

@nlohmann nlohmann added solution: wontfix the issue will not be fixed (either it is impossible or deemed out of scope) solution: invalid the issue is not related to the library and removed kind: bug labels Nov 30, 2024
@nlohmann nlohmann closed this as not planned Won't fix, can't repro, duplicate, stale Nov 30, 2024
cspiegel added a commit to cspiegel/garglk that referenced this issue Dec 29, 2024
These are false positives (see
nlohmann/json#3808), and really clutter up the
output during a build.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed solution: invalid the issue is not related to the library solution: wontfix the issue will not be fixed (either it is impossible or deemed out of scope)
Projects
None yet
Development

No branches or pull requests

4 participants