[ 
https://issues.apache.org/jira/browse/MESOS-3141?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14645670#comment-14645670
 ] 

haosdent commented on MESOS-3141:
---------------------------------

The pull request in Github. https://github.com/apache/mesos/pull/50/files 
Contains binary changes. [~mcypark]

> 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
>            Assignee: haosdent
>              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)

Reply via email to