You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@mesos.apache.org by "haosdent (JIRA)" <ji...@apache.org> on 2015/07/27 05:37:06 UTC
[jira] [Commented] (MESOS-3141) Compiler warning when mocking
function type has an enum return type.
[ https://issues.apache.org/jira/browse/MESOS-3141?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14642221#comment-14642221 ]
haosdent commented on MESOS-3141:
---------------------------------
I update gmock to 1.7.0
> 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)