[SERVER-29335] MongoDB 3.4.4 fails to build with gcc 7 Created: 23/May/17  Updated: 30/Oct/23  Resolved: 23/Aug/18

Status: Closed
Project: Core Server
Component/s: Build
Affects Version/s: 3.4.4
Fix Version/s: 3.7.1

Type: Bug Priority: Major - P3
Reporter: Alexander Pyhalov Assignee: Billy Donahue
Resolution: Fixed Votes: 0
Labels: platforms-re-triaged
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: File 06-gcc7.patch    
Issue Links:
Related
Backwards Compatibility: Fully Compatible
Operating System: ALL
Participants:

 Description   

MongoDB fails to build with gcc 7. The following warning is issued:

src/mongo/util/time_support.cpp: In function 'void mongo::

{anonymous}::_dateToCtimeString(mongo::Date_t, mongo::{anonymous}

::DateStringBuffer*)':
src/mongo/util/time_support.cpp:196:6: error: 'snprintf' output may be truncated before the last format character [-Werror=format-truncation=]
void _dateToCtimeString(Date_t date, DateStringBuffer* result) {
^~~~~~~~~~~~~~~~~~
src/mongo/util/time_support.cpp:206:13: note: 'snprintf' output between 5 and 6 bytes into a destination of size 5
snprintf(
milliSecStr, millisSubstrLen + 1, ".%03d", static_cast<int32_t>(date.asInt64() % 1000));

The issue seems to be that gcc sees that int32_t can be negative (really, why time since epoch can't be negative here?). In this case 5 symbols can be not enough to store string in .%03d format.



 Comments   
Comment by Gregory McKeon (Inactive) [ 23/Aug/18 ]

pinging kelsey.schubert - just added this to 3.7.1, which is where it was released.

Comment by Mathias Stearn [ 02/Jan/18 ]

FYI, / and % with mixed signs was made well defined in c++11: http://en.cppreference.com/w/cpp/language/operator_arithmetic#Multiplicative_operators

Comment by Githook User [ 29/Dec/17 ]

Author:

{'name': 'Billy Donahue', 'username': 'BillyDonahue', 'email': 'billy.donahue@mongodb.com'}

Message: SERVER-29335 fix millisecond formatting
Branch: master
https://github.com/mongodb/mongo/commit/e304b58275d36a1c28d0e652582268c070f599b7

Comment by Billy Donahue [ 27/Dec/17 ]

I ran into this today. It's annoying. There are several fixes I guess.
One way is to switch to `unsigned` so the compiler knows there's no possibility of a '-' showing up.

Other problems with that line:

  • Formatting uint32_t with 'd' isn't portable.
  • Result of negative%positive is implementation defined.
  • Date_t::asInt64 is deprecated.

I shouldn't spend the time to push this change, but here it is if someone wants to pick it up.

diff --git a/src/mongo/util/time_support.cpp b/src/mongo/util/time_support.cpp
index e19843ca47..81713d2460 100644
--- a/src/mongo/util/time_support.cpp
+++ b/src/mongo/util/time_support.cpp
@@ -205,7 +205,8 @@ void _dateToCtimeString(Date_t date, DateStringBuffer* result) {
 #endif
     char* milliSecStr = result->data + ctimeSubstrLen;
     snprintf(
-        milliSecStr, millisSubstrLen + 1, ".%03d", static_cast<int32_t>(date.asInt64() % 1000));
+        milliSecStr, millisSubstrLen + 1, ".%03u",
+        static_cast<unsigned>(date.toMillisSinceEpoch() % 1000));
     result->size = ctimeSubstrLen + millisSubstrLen;
 }
 }  // namespace

Comment by Mathias Stearn [ 30/May/17 ]

Hopefully putting invariant(date.isFormattable()); at the top of the function is enough to make gcc not complain since it ensures that the value isn't negative. Supporting dates before 1970 requires a little bit more math (https://github.com/mongodb/mongo/blob/r3.5.8/src/mongo/db/pipeline/expression.cpp#L1834-L1836) and that would still only work on systems where the built-in date formatting functions work correctly with negative dates.

Comment by Kelsey Schubert [ 26/May/17 ]

Thanks for the report, alp. Please note that gcc 7 is not currently supported. To resolve this issue, I recommend invoking scons with the --disable-warnings-as-errors flag.

Kind regards,
Thomas

Comment by Alexander Pyhalov [ 24/May/17 ]

Now if I apply attached workaround to build time_support.o I get more interesting issue, compiling cmdline.o:

In file included from src/third_party/boost-1.60.0/boost/function/detail/maybe_include.hpp:18:0,
                 from src/third_party/boost-1.60.0/boost/function/function1.hpp:11,
                 from src/third_party/boost-1.60.0/boost/program_options/value_semantic.hpp:13,
                 from src/third_party/boost-1.60.0/boost/program_options/options_description.hpp:13,
                 from src/third_party/boost-1.60.0/boost/program_options/detail/cmdline.hpp:14,
                 from src/third_party/boost-1.60.0/libs/program_options/src/cmdline.cpp:11:
src/third_party/boost-1.60.0/boost/function/function_template.hpp: In instantiation of 'void boost::detail::function::basic_vtable1<R, T0>::assign_functor(FunctionObj, boost::detail::function::function_buffer&, mpl_::true_) const [with FunctionObj = boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >; R = std::vector<boost::program_options::basic_option<char> >; T0 = std::vector<std::__cxx11::basic_string<char> >&; mpl_::true_ = mpl_::bool_<true>]':
src/third_party/boost-1.60.0/boost/function/function_template.hpp:608:27:   required from 'bool boost::detail::function::basic_vtable1<R, T0>::assign_to(FunctionObj, boost::detail::function::function_buffer&, boost::detail::function::function_obj_tag) const [with FunctionObj = boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >; R = std::vector<boost::program_options::basic_option<char> >; T0 = std::vector<std::__cxx11::basic_string<char> >&]'
src/third_party/boost-1.60.0/boost/function/function_template.hpp:498:27:   required from 'bool boost::detail::function::basic_vtable1<R, T0>::assign_to(F, boost::detail::function::function_buffer&) const [with F = boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >; R = std::vector<boost::program_options::basic_option<char> >; T0 = std::vector<std::__cxx11::basic_string<char> >&]'
src/third_party/boost-1.60.0/boost/function/function_template.hpp:939:7:   required from 'void boost::function1<R, T1>::assign_to(Functor) [with Functor = boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >; R = std::vector<boost::program_options::basic_option<char> >; T0 = std::vector<std::__cxx11::basic_string<char> >&]'
src/third_party/boost-1.60.0/boost/function/function_template.hpp:727:7:   required from 'boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type) [with Functor = boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >; R = std::vector<boost::program_options::basic_option<char> >; T0 = std::vector<std::__cxx11::basic_string<char> >&; typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type = int]'
src/third_party/boost-1.60.0/libs/program_options/src/cmdline.cpp:227:74:   required from here
src/third_party/boost-1.60.0/boost/function/function_template.hpp:572:11: error: placement new constructing an object of type 'boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >' and size '24' in a region of type 'char' and size '1' [-Werror=placement-new=]
           new (reinterpret_cast<void*>(&functor.data)) FunctionObj(f);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/third_party/boost-1.60.0/boost/function/detail/prologue.hpp:17:0,
                 from src/third_party/boost-1.60.0/boost/function/function_template.hpp:13,
                 from src/third_party/boost-1.60.0/boost/function/detail/maybe_include.hpp:18,
                 from src/third_party/boost-1.60.0/boost/function/function1.hpp:11,
                 from src/third_party/boost-1.60.0/boost/program_options/value_semantic.hpp:13,
                 from src/third_party/boost-1.60.0/boost/program_options/options_description.hpp:13,
                 from src/third_party/boost-1.60.0/boost/program_options/detail/cmdline.hpp:14,
                 from src/third_party/boost-1.60.0/libs/program_options/src/cmdline.cpp:11:
src/third_party/boost-1.60.0/boost/function/function_base.hpp: In instantiation of 'static void boost::detail::function::functor_manager_common<Functor>::manage_small(const boost::detail::function::function_buffer&, boost::detail::function::function_buffer&, boost::detail::function::functor_manager_operation_type) [with Functor = boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >]':
src/third_party/boost-1.60.0/boost/function/function_base.hpp:354:56:   required from 'static void boost::detail::function::functor_manager<Functor>::manager(const boost::detail::function::function_buffer&, boost::detail::function::function_buffer&, boost::detail::function::functor_manager_operation_type, mpl_::true_) [with Functor = boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >; mpl_::true_ = mpl_::bool_<true>]'
src/third_party/boost-1.60.0/boost/function/function_base.hpp:402:18:   required from 'static void boost::detail::function::functor_manager<Functor>::manager(const boost::detail::function::function_buffer&, boost::detail::function::function_buffer&, boost::detail::function::functor_manager_operation_type, boost::detail::function::function_obj_tag) [with Functor = boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >]'
src/third_party/boost-1.60.0/boost/function/function_base.hpp:430:20:   required from 'static void boost::detail::function::functor_manager<Functor>::manage(const boost::detail::function::function_buffer&, boost::detail::function::function_buffer&, boost::detail::function::functor_manager_operation_type) [with Functor = boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >]'
src/third_party/boost-1.60.0/boost/function/function_template.hpp:937:13:   required from 'void boost::function1<R, T1>::assign_to(Functor) [with Functor = boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >; R = std::vector<boost::program_options::basic_option<char> >; T0 = std::vector<std::__cxx11::basic_string<char> >&]'
src/third_party/boost-1.60.0/boost/function/function_template.hpp:727:7:   required from 'boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type) [with Functor = boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >; R = std::vector<boost::program_options::basic_option<char> >; T0 = std::vector<std::__cxx11::basic_string<char> >&; typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type = int]'
src/third_party/boost-1.60.0/libs/program_options/src/cmdline.cpp:227:74:   required from here
src/third_party/boost-1.60.0/boost/function/function_base.hpp:308:13: error: placement new constructing an object of type 'boost::detail::function::functor_manager_common<boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > > >::functor_type {aka boost::_bi::bind_t<std::vector<boost::program_options::basic_option<char> >, boost::_mfi::mf1<std::vector<boost::program_options::basic_option<char> >, boost::program_options::detail::cmdline, std::vector<std::__cxx11::basic_string<char> >&>, boost::_bi::list2<boost::_bi::value<boost::program_options::detail::cmdline*>, boost::arg<1> > >}' and size '24' in a region of type 'char' and size '1' [-Werror=placement-new=]
             new (reinterpret_cast<void*>(&out_buffer.data)) functor_type(*in_functor);
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Comment by Alexander Pyhalov [ 24/May/17 ]

Workaround to build time_support.o

Generated at Thu Feb 08 04:20:32 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.