[
https://issues.apache.org/jira/browse/MESOS-3141?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Artem Harutyunyan updated MESOS-3141:
-------------------------------------
Story Points: 3
Labels: mesosphere (was: )
> Compiler warning when mocking function type has an enum return type.
> --------------------------------------------------------------------
>
> Key: MESOS-3141
> URL: https://issues.apache.org/jira/browse/MESOS-3141
> Project: Mesos
> Issue Type: Bug
> Affects Versions: 0.23.0
> Reporter: Michael Park
> Labels: mesosphere
>
> 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.
> h3. Problem
> The following code is attempting to mock a {{MesosExecutorDriver}}:
> {code}
> class MockMesosExecutorDriver : public MesosExecutorDriver {
> public:
> MockMesosExecutorDriver(mesos::Executor* executor)
> : MesosExecutorDriver(executor) {}
> MOCK_METHOD1(sendStatusUpdate, Status(const TaskStatus&));
> };
> {code}
> The above code generates the following error message:
> {noformat}
> 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);
> ^
> {noformat}
> 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:
> {code}
> template <typename T>
> T Invalid() {
> return *static_cast<typename remove_reference<T>::type*>(NULL);
> }
> {code}
> 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:
> {code}
> #include <type_traits>
> template <typename T>
> T invalid() {
> return *static_cast<typename std::remove_reference<T>::type *>(nullptr);
> }
> enum E { A, B };
> int main() {
> invalid<E>();
> }
> {code}
> * See it online on [GCC Explorer|https://goo.gl/t1FepZ]
> 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.
> h3. Solutions
> The simplest solution is to add {{-Wno-null-deference}} to
> {{mesos_tests_CPPFLAGS}} in {{src/Makefile.am}}.
> {code}
> mesos_tests_CPPFLAGS = $(MESOS_CPPFLAGS) -Wno-null-dereference
> {code}
> Another solution is to upgrade {{gmock}} from *1.6* to *1.7* to as I believe
> this problem is solved in the newer versions.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)