Uploaded image for project: 'Mesos'
  1. Mesos
  2. MESOS-3141

Compiler warning when mocking function type has an enum return type.



    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 0.23.0
    • Fix Version/s: 0.24.0
    • Component/s: None
    • Labels:
    • Story Points:


      The purpose of this ticket is to document a very cryptic error message (actually a warning that gets propagated by -Werror) that gets generated by clang-3.5 from gmock source code when trying to mock a perfectly innocent-looking function.


      The following code is attempting to mock a MesosExecutorDriver:

      class MockMesosExecutorDriver : public MesosExecutorDriver {
        MockMesosExecutorDriver(mesos::Executor* executor)
          : MesosExecutorDriver(executor) {}
        MOCK_METHOD1(sendStatusUpdate, Status(const TaskStatus&));

      The above code generates the following error message:

      In file included from ../3rdparty/libprocess/3rdparty/gmock-1.6.0/include/gmock/gmock.h:58:
      In file included from ../3rdparty/libprocess/3rdparty/gmock-1.6.0/include/gmock/gmock-actions.h:46:
      ../3rdparty/libprocess/3rdparty/gmock-1.6.0/include/gmock/internal/gmock-internal-utils.h:355:10: error: indirection of non-volatile null pointer will be deleted, not trap [-Werror,-Wnull-dereference]
        return *static_cast<typename remove_reference<T>::type*>(__null);
      ../3rdparty/libprocess/3rdparty/gmock-1.6.0/include/gmock/gmock-actions.h:78:22: note: in instantiation of function template specialization 'testing::internal::Invalid<mesos::Status>' requested here
          return internal::Invalid<T>();
      ../3rdparty/libprocess/3rdparty/gmock-1.6.0/include/gmock/gmock-actions.h:190:43: note: in instantiation of member function 'testing::internal::BuiltInDefaultValue<mesos::Status>::Get' requested here
              internal::BuiltInDefaultValue<T>::Get() : *value_;
      ../3rdparty/libprocess/3rdparty/gmock-1.6.0/include/gmock/gmock-spec-builders.h:1435:34: note: in instantiation of member function 'testing::DefaultValue<mesos::Status>::Get' requested here
          return DefaultValue<Result>::Get();
      ../3rdparty/libprocess/3rdparty/gmock-1.6.0/include/gmock/gmock-spec-builders.h:1334:22: note: in instantiation of member function 'testing::internal::FunctionMockerBase<mesos::Status (const mesos::TaskStatus &)>::PerformDefaultAction' requested here
              func_mocker->PerformDefaultAction(args, call_description));
      ../3rdparty/libprocess/3rdparty/gmock-1.6.0/include/gmock/gmock-spec-builders.h:1448:26: note: in instantiation of function template specialization 'testing::internal::ActionResultHolder<mesos::Status>::PerformDefaultAction<mesos::Status (const mesos::TaskStatus &)>' requested here
          return ResultHolder::PerformDefaultAction(this, args, call_description);
      ../3rdparty/libprocess/3rdparty/gmock-1.6.0/include/gmock/gmock-generated-function-mockers.h:81:7: note: in instantiation of member function 'testing::internal::FunctionMockerBase<mesos::Status (const mesos::TaskStatus &)>::UntypedPerformDefaultAction' requested here
      class FunctionMocker<R(A1)> : public
      ../3rdparty/libprocess/3rdparty/gmock-1.6.0/include/gmock/internal/gmock-internal-utils.h:355:10: note: consider using __builtin_trap() or qualifying pointer with 'volatile'
        return *static_cast<typename remove_reference<T>::type*>(__null);

      The source of the issue here is that Status is an enum. In gmock-1.6.0/include/gmock/internal/gmock-internal-utils.h you can find the following function:

      template <typename T>
      T Invalid() {
        return *static_cast<typename remove_reference<T>::type*>(NULL);

      This function gets called with the return type of a mocked function. In our case, the return type of the mocked function is Status.

      Attempting to compile the following minimal example with clang-3.5 reproduces the error message:

      #include <type_traits>
      template <typename T>
      T invalid() {
        return *static_cast<typename std::remove_reference<T>::type *>(nullptr);
      enum E { A, B };
      int main() {

      Note that if the type is not an enum, the warning is not generated. This is why existing mocked functions that return non-enum types such as Future<void> does not encounter this issue.


      The simplest solution is to add -Wno-null-deference to mesos_tests_CPPFLAGS in src/Makefile.am.

      mesos_tests_CPPFLAGS = $(MESOS_CPPFLAGS) -Wno-null-dereference

      Another solution is to upgrade gmock from 1.6 to 1.7 because this problem is solved in the newer versions.

      In gmock 1.7

      template <typename T>
      inline T Invalid() {
        return const_cast<typename remove_reference<T>::type&>(
            *static_cast<volatile typename remove_reference<T>::type*>(NULL));

      Add volatile could avoid this warning. https://goo.gl/opCiLC


          Issue Links



              • Assignee:
                haosdent@gmail.com haosdent
                mcypark Michael Park
              • Votes:
                0 Vote for this issue
                3 Start watching this issue


                • Created: